mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
Major refactoring of files in package: hide them in Package type.
This commit is contained in:
Vendored
+127
-31
@@ -7,18 +7,38 @@ import (
|
||||
"github.com/smira/aptly/utils"
|
||||
"github.com/ugorji/go/codec"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PackageFile is a single file entry in package
|
||||
type PackageFile struct {
|
||||
Filename string
|
||||
Checksums utils.ChecksumInfo
|
||||
}
|
||||
|
||||
// Verify that package file is present and correct
|
||||
func (f *PackageFile) Verify(packageRepo *Repository) (bool, error) {
|
||||
poolPath, err := packageRepo.PoolPath(f.Filename, f.Checksums.MD5)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
st, err := os.Stat(poolPath)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// verify size
|
||||
// TODO: verify checksum if configured
|
||||
return st.Size() == f.Checksums.Size, nil
|
||||
}
|
||||
|
||||
// Package is single instance of Debian package
|
||||
//
|
||||
// TODO: support source & binary
|
||||
type Package struct {
|
||||
Name string
|
||||
Version string
|
||||
Filename string
|
||||
Filesize int64
|
||||
Architecture string
|
||||
Source string
|
||||
// Various dependencies
|
||||
@@ -26,10 +46,8 @@ type Package struct {
|
||||
PreDepends []string
|
||||
Suggests []string
|
||||
Recommends []string
|
||||
// Hashsums of package contents
|
||||
HashMD5 string
|
||||
HashSHA1 string
|
||||
HashSHA256 string
|
||||
// Files in package
|
||||
Files []PackageFile
|
||||
// Extra information from stanza
|
||||
Extra Stanza
|
||||
}
|
||||
@@ -50,24 +68,32 @@ func NewPackageFromControlFile(input Stanza) *Package {
|
||||
result := &Package{
|
||||
Name: input["Package"],
|
||||
Version: input["Version"],
|
||||
Filename: input["Filename"],
|
||||
Architecture: input["Architecture"],
|
||||
Source: input["Source"],
|
||||
HashMD5: input["MD5sum"],
|
||||
HashSHA1: input["SHA1"],
|
||||
HashSHA256: input["SHA256"],
|
||||
Files: make([]PackageFile, 0, 1),
|
||||
}
|
||||
|
||||
delete(input, "Package")
|
||||
delete(input, "Version")
|
||||
delete(input, "Filename")
|
||||
delete(input, "Architecture")
|
||||
delete(input, "Source")
|
||||
|
||||
filesize, _ := strconv.ParseInt(input["Size"], 10, 64)
|
||||
|
||||
result.Files = append(result.Files, PackageFile{
|
||||
Filename: input["Filename"],
|
||||
Checksums: utils.ChecksumInfo{
|
||||
Size: filesize,
|
||||
MD5: input["MD5sum"],
|
||||
SHA1: input["SHA1"],
|
||||
SHA256: input["SHA256"],
|
||||
},
|
||||
})
|
||||
|
||||
delete(input, "Filename")
|
||||
delete(input, "MD5sum")
|
||||
delete(input, "SHA1")
|
||||
delete(input, "SHA256")
|
||||
|
||||
result.Filesize, _ = strconv.ParseInt(input["Size"], 10, 64)
|
||||
delete(input, "Size")
|
||||
|
||||
result.Depends = parseDependencies(input, "Depends")
|
||||
@@ -111,18 +137,18 @@ func (p *Package) Stanza() (result Stanza) {
|
||||
result = p.Extra.Copy()
|
||||
result["Package"] = p.Name
|
||||
result["Version"] = p.Version
|
||||
result["Filename"] = p.Filename
|
||||
result["Filename"] = p.Files[0].Filename
|
||||
result["Architecture"] = p.Architecture
|
||||
result["Source"] = p.Source
|
||||
|
||||
if p.HashMD5 != "" {
|
||||
result["MD5sum"] = p.HashMD5
|
||||
if p.Files[0].Checksums.MD5 != "" {
|
||||
result["MD5sum"] = p.Files[0].Checksums.MD5
|
||||
}
|
||||
if p.HashSHA1 != "" {
|
||||
result["SHA1"] = p.HashSHA1
|
||||
if p.Files[0].Checksums.SHA1 != "" {
|
||||
result["SHA1"] = p.Files[0].Checksums.SHA1
|
||||
}
|
||||
if p.HashSHA256 != "" {
|
||||
result["SHA256"] = p.HashSHA256
|
||||
if p.Files[0].Checksums.SHA256 != "" {
|
||||
result["SHA256"] = p.Files[0].Checksums.SHA256
|
||||
}
|
||||
|
||||
if p.Depends != nil {
|
||||
@@ -138,28 +164,98 @@ func (p *Package) Stanza() (result Stanza) {
|
||||
result["Recommends"] = strings.Join(p.Recommends, ", ")
|
||||
}
|
||||
|
||||
result["Size"] = fmt.Sprintf("%d", p.Filesize)
|
||||
result["Size"] = fmt.Sprintf("%d", p.Files[0].Checksums.Size)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Equals compares two packages to be identical
|
||||
func (p *Package) Equals(p2 *Package) bool {
|
||||
return p.Name == p2.Name && p.Version == p2.Version && p.Filename == p2.Filename &&
|
||||
if len(p.Files) != len(p2.Files) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, f := range p.Files {
|
||||
if p2.Files[i] != f {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return p.Name == p2.Name && p.Version == p2.Version &&
|
||||
p.Architecture == p2.Architecture && utils.StrSlicesEqual(p.Depends, p2.Depends) &&
|
||||
utils.StrSlicesEqual(p.PreDepends, p2.PreDepends) && utils.StrSlicesEqual(p.Suggests, p2.Suggests) &&
|
||||
utils.StrSlicesEqual(p.Recommends, p2.Recommends) && utils.StrMapsEqual(p.Extra, p2.Extra) &&
|
||||
p.Filesize == p2.Filesize && p.HashMD5 == p2.HashMD5 && p.HashSHA1 == p2.HashSHA1 &&
|
||||
p.HashSHA256 == p2.HashSHA256 && p.Source == p2.Source
|
||||
p.Source == p2.Source
|
||||
}
|
||||
|
||||
// VerifyFile verifies integrity and existence of local files for the package
|
||||
func (p *Package) VerifyFile(filepath string) bool {
|
||||
st, err := os.Stat(filepath)
|
||||
// LinkFromPool links package file from pool to dist's pool location
|
||||
func (p *Package) LinkFromPool(packageRepo *Repository, prefix string, component string) error {
|
||||
poolDir, err := p.PoolDirectory()
|
||||
if err != nil {
|
||||
return false
|
||||
return err
|
||||
}
|
||||
return st.Size() == p.Filesize
|
||||
|
||||
for i, f := range p.Files {
|
||||
sourcePath, err := packageRepo.PoolPath(f.Filename, f.Checksums.MD5)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
relPath, err := packageRepo.LinkFromPool(prefix, component, sourcePath, poolDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Files[i].Filename = relPath
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PoolDirectory returns directory in package pool for this package files
|
||||
func (p *Package) PoolDirectory() (string, error) {
|
||||
source := p.Source
|
||||
if source == "" {
|
||||
source = p.Name
|
||||
}
|
||||
|
||||
if len(source) < 2 {
|
||||
return "", fmt.Errorf("package source %s too short", source)
|
||||
}
|
||||
|
||||
var subdir string
|
||||
if strings.HasPrefix(source, "lib") {
|
||||
subdir = source[:4]
|
||||
} else {
|
||||
subdir = source[:1]
|
||||
|
||||
}
|
||||
|
||||
return filepath.Join(subdir, source), nil
|
||||
}
|
||||
|
||||
// DownloadList returns list of missing package files for download in format
|
||||
// [[srcpath, dstpath]]
|
||||
func (p *Package) DownloadList(packageRepo *Repository) (result [][]string, err error) {
|
||||
result = make([][]string, 0, 1)
|
||||
|
||||
for _, f := range p.Files {
|
||||
poolPath, err := packageRepo.PoolPath(f.Filename, f.Checksums.MD5)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verified, err := f.Verify(packageRepo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !verified {
|
||||
result = append(result, []string{f.Filename, poolPath})
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// PackageCollection does management of packages in DB
|
||||
|
||||
Reference in New Issue
Block a user