1package deb 2 3import ( 4 "os" 5 "path/filepath" 6 "sort" 7 "strings" 8 9 "github.com/aptly-dev/aptly/aptly" 10 "github.com/aptly-dev/aptly/pgp" 11 "github.com/aptly-dev/aptly/utils" 12) 13 14// CollectPackageFiles walks filesystem collecting all candidates for package files 15func CollectPackageFiles(locations []string, reporter aptly.ResultReporter) (packageFiles, otherFiles, failedFiles []string) { 16 for _, location := range locations { 17 info, err2 := os.Stat(location) 18 if err2 != nil { 19 reporter.Warning("Unable to process %s: %s", location, err2) 20 failedFiles = append(failedFiles, location) 21 continue 22 } 23 if info.IsDir() { 24 err2 = filepath.Walk(location, func(path string, info os.FileInfo, err3 error) error { 25 if err3 != nil { 26 return err3 27 } 28 if info.IsDir() { 29 return nil 30 } 31 32 if strings.HasSuffix(info.Name(), ".deb") || strings.HasSuffix(info.Name(), ".udeb") || 33 strings.HasSuffix(info.Name(), ".dsc") || strings.HasSuffix(info.Name(), ".ddeb") { 34 packageFiles = append(packageFiles, path) 35 } else if strings.HasSuffix(info.Name(), ".buildinfo") { 36 otherFiles = append(otherFiles, path) 37 } 38 39 return nil 40 }) 41 42 if err2 != nil { 43 reporter.Warning("Unable to process %s: %s", location, err2) 44 failedFiles = append(failedFiles, location) 45 continue 46 } 47 } else { 48 if strings.HasSuffix(info.Name(), ".deb") || strings.HasSuffix(info.Name(), ".udeb") || 49 strings.HasSuffix(info.Name(), ".dsc") || strings.HasSuffix(info.Name(), ".ddeb") { 50 packageFiles = append(packageFiles, location) 51 } else if strings.HasSuffix(info.Name(), ".buildinfo") { 52 otherFiles = append(otherFiles, location) 53 } else { 54 reporter.Warning("Unknown file extension: %s", location) 55 failedFiles = append(failedFiles, location) 56 continue 57 } 58 } 59 } 60 61 sort.Strings(packageFiles) 62 63 return 64} 65 66// ImportPackageFiles imports files into local repository 67func ImportPackageFiles(list *PackageList, packageFiles []string, forceReplace bool, verifier pgp.Verifier, 68 pool aptly.PackagePool, collection *PackageCollection, reporter aptly.ResultReporter, restriction PackageQuery, 69 checksumStorage aptly.ChecksumStorage) (processedFiles []string, failedFiles []string, err error) { 70 if forceReplace { 71 list.PrepareIndex() 72 } 73 74 for _, file := range packageFiles { 75 var ( 76 stanza Stanza 77 p *Package 78 ) 79 80 candidateProcessedFiles := []string{} 81 isSourcePackage := strings.HasSuffix(file, ".dsc") 82 isUdebPackage := strings.HasSuffix(file, ".udeb") 83 84 if isSourcePackage { 85 stanza, err = GetControlFileFromDsc(file, verifier) 86 87 if err == nil { 88 stanza["Package"] = stanza["Source"] 89 delete(stanza, "Source") 90 91 p, err = NewSourcePackageFromControlFile(stanza) 92 } 93 } else { 94 stanza, err = GetControlFileFromDeb(file) 95 if isUdebPackage { 96 p = NewUdebPackageFromControlFile(stanza) 97 } else { 98 p = NewPackageFromControlFile(stanza) 99 } 100 } 101 if err != nil { 102 reporter.Warning("Unable to read file %s: %s", file, err) 103 failedFiles = append(failedFiles, file) 104 continue 105 } 106 107 if p.Name == "" { 108 reporter.Warning("Empty package name on %s", file) 109 failedFiles = append(failedFiles, file) 110 continue 111 } 112 113 if p.Version == "" { 114 reporter.Warning("Empty version on %s", file) 115 failedFiles = append(failedFiles, file) 116 continue 117 } 118 119 if p.Architecture == "" { 120 reporter.Warning("Empty architecture on %s", file) 121 failedFiles = append(failedFiles, file) 122 continue 123 } 124 125 var files PackageFiles 126 127 if isSourcePackage { 128 files = p.Files() 129 } 130 131 var checksums utils.ChecksumInfo 132 checksums, err = utils.ChecksumsForFile(file) 133 if err != nil { 134 return nil, nil, err 135 } 136 137 mainPackageFile := PackageFile{ 138 Filename: filepath.Base(file), 139 Checksums: checksums, 140 } 141 142 mainPackageFile.PoolPath, err = pool.Import(file, mainPackageFile.Filename, &mainPackageFile.Checksums, false, checksumStorage) 143 if err != nil { 144 reporter.Warning("Unable to import file %s into pool: %s", file, err) 145 failedFiles = append(failedFiles, file) 146 continue 147 } 148 149 candidateProcessedFiles = append(candidateProcessedFiles, file) 150 151 // go over all the other files 152 for i := range files { 153 sourceFile := filepath.Join(filepath.Dir(file), filepath.Base(files[i].Filename)) 154 155 _, err = os.Stat(sourceFile) 156 if err == nil { 157 files[i].PoolPath, err = pool.Import(sourceFile, files[i].Filename, &files[i].Checksums, false, checksumStorage) 158 if err == nil { 159 candidateProcessedFiles = append(candidateProcessedFiles, sourceFile) 160 } 161 } else if os.IsNotExist(err) { 162 // if file is not present, try to find it in the pool 163 var ( 164 err2 error 165 found bool 166 ) 167 168 files[i].PoolPath, found, err2 = pool.Verify("", files[i].Filename, &files[i].Checksums, checksumStorage) 169 if err2 != nil { 170 err = err2 171 } else if found { 172 // clear error, file is already in the package pool 173 err = nil 174 } 175 } 176 177 if err != nil { 178 reporter.Warning("Unable to import file %s into pool: %s", sourceFile, err) 179 failedFiles = append(failedFiles, file) 180 break 181 } 182 } 183 if err != nil { 184 // some files haven't been imported 185 continue 186 } 187 188 p.UpdateFiles(append(files, mainPackageFile)) 189 190 if restriction != nil && !restriction.Matches(p) { 191 reporter.Warning("%s has been ignored as it doesn't match restriction", p) 192 failedFiles = append(failedFiles, file) 193 continue 194 } 195 196 err = collection.Update(p) 197 if err != nil { 198 reporter.Warning("Unable to save package %s: %s", p, err) 199 failedFiles = append(failedFiles, file) 200 continue 201 } 202 203 if forceReplace { 204 conflictingPackages := list.Search(Dependency{Pkg: p.Name, Version: p.Version, Relation: VersionEqual, Architecture: p.Architecture}, true) 205 for _, cp := range conflictingPackages { 206 reporter.Removed("%s removed due to conflict with package being added", cp) 207 list.Remove(cp) 208 } 209 } 210 211 err = list.Add(p) 212 if err != nil { 213 reporter.Warning("Unable to add package to repo %s: %s", p, err) 214 failedFiles = append(failedFiles, file) 215 continue 216 } 217 218 reporter.Added("%s added", p) 219 processedFiles = append(processedFiles, candidateProcessedFiles...) 220 } 221 222 err = nil 223 return 224} 225