From f1882cfe2cd2aa73ad0d6b854fabefe3c83f3b56 Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Mon, 18 Jun 2018 11:28:41 +0200 Subject: [PATCH 1/2] Expose repo include through API --- api/repos.go | 75 ++++++++++++++++++++ api/router.go | 3 + cmd/repo_include.go | 153 +++------------------------------------- deb/changes.go | 146 +++++++++++++++++++++++++++++++++++++- deb/deb.go | 2 + system/t12_api/repos.py | 32 +++++++++ 6 files changed, 264 insertions(+), 147 deletions(-) diff --git a/api/repos.go b/api/repos.go index 57d1ed01d..a5dd39d45 100644 --- a/api/repos.go +++ b/api/repos.go @@ -8,6 +8,7 @@ import ( "github.com/aptly-dev/aptly/aptly" "github.com/aptly-dev/aptly/database" "github.com/aptly-dev/aptly/deb" + "github.com/aptly-dev/aptly/query" "github.com/aptly-dev/aptly/utils" "github.com/gin-gonic/gin" ) @@ -367,3 +368,77 @@ func apiReposPackageFromDir(c *gin.Context) { "FailedFiles": failedFiles, }) } + +// POST /repos/:name/include/:dir/:file +func apiReposIncludePackageFromFile(c *gin.Context) { + // redirect all work to dir method + apiReposIncludePackageFromDir(c) +} + +// POST /repos/:name/include/:dir +func apiReposIncludePackageFromDir(c *gin.Context) { + forceReplace := c.Request.URL.Query().Get("forceReplace") == "1" + noRemoveFiles := c.Request.URL.Query().Get("noRemoveFiles") == "1" + acceptUnsigned := c.Request.URL.Query().Get("acceptUnsigned") == "1" + ignoreSignature := c.Request.URL.Query().Get("ignoreSignature") == "1" + + repoTemplateString := c.Params.ByName("name") + + if !verifyDir(c) { + return + } + + fileParam := c.Params.ByName("file") + if fileParam != "" && !verifyPath(fileParam) { + c.AbortWithError(400, fmt.Errorf("wrong file")) + return + } + + var ( + err error + verifier = context.GetVerifier() + sources, changesFiles []string + failedFiles, failedFiles2 []string + reporter = &aptly.RecordingResultReporter{ + Warnings: []string{}, + AddedLines: []string{}, + RemovedLines: []string{}, + } + ) + + if fileParam == "" { + sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"))} + } else { + sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"), c.Params.ByName("file"))} + } + + localRepoCollection := context.CollectionFactory().LocalRepoCollection() + localRepoCollection.Lock() + defer localRepoCollection.Unlock() + + changesFiles, failedFiles = deb.CollectChangesFiles(sources, reporter) + _, failedFiles2, err = deb.ImportChangesFiles( + changesFiles, reporter, acceptUnsigned, ignoreSignature, forceReplace, noRemoveFiles, verifier, + repoTemplateString, context.Progress(), localRepoCollection, context.CollectionFactory().PackageCollection(), + context.PackagePool(), context.CollectionFactory().ChecksumCollection(), nil, query.Parse) + failedFiles = append(failedFiles, failedFiles2...) + + if err != nil { + c.AbortWithError(500, fmt.Errorf("unable to import changes files: %s", err)) + return + } + + if !noRemoveFiles { + // atempt to remove dir, if it fails, that's fine: probably it's not empty + os.Remove(filepath.Join(context.UploadPath(), c.Params.ByName("dir"))) + } + + if failedFiles == nil { + failedFiles = []string{} + } + + c.JSON(200, gin.H{ + "Report": reporter, + "FailedFiles": failedFiles, + }) +} diff --git a/api/router.go b/api/router.go index 854f04146..0e1aa3bd8 100644 --- a/api/router.go +++ b/api/router.go @@ -71,6 +71,9 @@ func Router(c *ctx.AptlyContext) http.Handler { root.POST("/repos/:name/file/:dir/:file", apiReposPackageFromFile) root.POST("/repos/:name/file/:dir", apiReposPackageFromDir) + root.POST("/repos/:name/include/:dir/:file", apiReposIncludePackageFromFile) + root.POST("/repos/:name/include/:dir", apiReposIncludePackageFromDir) + root.POST("/repos/:name/snapshots", apiSnapshotsCreateFromRepository) } diff --git a/cmd/repo_include.go b/cmd/repo_include.go index d5bf0f342..120d0244e 100644 --- a/cmd/repo_include.go +++ b/cmd/repo_include.go @@ -1,16 +1,11 @@ package cmd import ( - "bytes" "fmt" - "os" - "path/filepath" - "text/template" "github.com/aptly-dev/aptly/aptly" "github.com/aptly-dev/aptly/deb" "github.com/aptly-dev/aptly/query" - "github.com/aptly-dev/aptly/utils" "github.com/smira/commander" "github.com/smira/flag" ) @@ -35,11 +30,7 @@ func aptlyRepoInclude(cmd *commander.Command, args []string) error { acceptUnsigned := context.Flags().Lookup("accept-unsigned").Value.Get().(bool) ignoreSignatures := context.Flags().Lookup("ignore-signatures").Value.Get().(bool) noRemoveFiles := context.Flags().Lookup("no-remove-files").Value.Get().(bool) - - repoTemplate, err := template.New("repo").Parse(context.Flags().Lookup("repo").Value.Get().(string)) - if err != nil { - return fmt.Errorf("error parsing -repo template: %s", err) - } + repoTemplateString := context.Flags().Lookup("repo").Value.Get().(string) uploaders := (*deb.Uploaders)(nil) uploadersFile := context.Flags().Lookup("uploaders-file").Value.Get().(string) @@ -59,143 +50,15 @@ func aptlyRepoInclude(cmd *commander.Command, args []string) error { reporter := &aptly.ConsoleResultReporter{Progress: context.Progress()} - var changesFiles, failedFiles, processedFiles []string + var changesFiles, failedFiles, failedFiles2 []string changesFiles, failedFiles = deb.CollectChangesFiles(args, reporter) - - for _, path := range changesFiles { - var changes *deb.Changes - - changes, err = deb.NewChanges(path) - if err != nil { - failedFiles = append(failedFiles, path) - reporter.Warning("unable to process file %s: %s", path, err) - continue - } - - err = changes.VerifyAndParse(acceptUnsigned, ignoreSignatures, verifier) - if err != nil { - failedFiles = append(failedFiles, path) - reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) - changes.Cleanup() - continue - } - - err = changes.Prepare() - if err != nil { - failedFiles = append(failedFiles, path) - reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) - changes.Cleanup() - continue - } - - repoName := &bytes.Buffer{} - err = repoTemplate.Execute(repoName, changes.Stanza) - if err != nil { - return fmt.Errorf("error applying template to repo: %s", err) - } - - context.Progress().Printf("Loading repository %s for changes file %s...\n", repoName.String(), changes.ChangesName) - - var repo *deb.LocalRepo - repo, err = context.CollectionFactory().LocalRepoCollection().ByName(repoName.String()) - if err != nil { - failedFiles = append(failedFiles, path) - reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) - changes.Cleanup() - continue - } - - currentUploaders := uploaders - if repo.Uploaders != nil { - currentUploaders = repo.Uploaders - for i := range currentUploaders.Rules { - currentUploaders.Rules[i].CompiledCondition, err = query.Parse(currentUploaders.Rules[i].Condition) - if err != nil { - return fmt.Errorf("error parsing query %s: %s", currentUploaders.Rules[i].Condition, err) - } - } - } - - if currentUploaders != nil { - if err = currentUploaders.IsAllowed(changes); err != nil { - failedFiles = append(failedFiles, path) - reporter.Warning("changes file skipped due to uploaders config: %s, keys %#v: %s", - changes.ChangesName, changes.SignatureKeys, err) - changes.Cleanup() - continue - } - } - - err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) - if err != nil { - return fmt.Errorf("unable to load repo: %s", err) - } - - var list *deb.PackageList - list, err = deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) - if err != nil { - return fmt.Errorf("unable to load packages: %s", err) - } - - packageFiles, otherFiles, _ := deb.CollectPackageFiles([]string{changes.TempDir}, reporter) - - var restriction deb.PackageQuery - - restriction, err = changes.PackageQuery() - if err != nil { - failedFiles = append(failedFiles, path) - reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) - changes.Cleanup() - continue - } - - var processedFiles2, failedFiles2 []string - - processedFiles2, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), - context.CollectionFactory().PackageCollection(), reporter, restriction, context.CollectionFactory().ChecksumCollection()) - - if err != nil { - return fmt.Errorf("unable to import package files: %s", err) - } - - repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) - - err = context.CollectionFactory().LocalRepoCollection().Update(repo) - if err != nil { - return fmt.Errorf("unable to save: %s", err) - } - - err = changes.Cleanup() - if err != nil { - return err - } - - for _, file := range failedFiles2 { - failedFiles = append(failedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) - } - - for _, file := range processedFiles2 { - processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) - } - - for _, file := range otherFiles { - processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) - } - - processedFiles = append(processedFiles, path) - } - - if !noRemoveFiles { - processedFiles = utils.StrSliceDeduplicate(processedFiles) - - for _, file := range processedFiles { - err = os.Remove(file) - if err != nil { - return fmt.Errorf("unable to remove file: %s", err) - } - } - } + _, failedFiles2, err = deb.ImportChangesFiles( + changesFiles, reporter, acceptUnsigned, ignoreSignatures, forceReplace, noRemoveFiles, verifier, repoTemplateString, + context.Progress(), context.CollectionFactory().LocalRepoCollection(), context.CollectionFactory().PackageCollection(), + context.PackagePool(), context.CollectionFactory().ChecksumCollection(), + uploaders, query.Parse) + failedFiles = append(failedFiles, failedFiles2...) if len(failedFiles) > 0 { context.Progress().ColoredPrintf("@y[!]@| @!Some files were skipped due to errors:@|") diff --git a/deb/changes.go b/deb/changes.go index 0d411c684..de4c5de6d 100644 --- a/deb/changes.go +++ b/deb/changes.go @@ -1,6 +1,7 @@ package deb import ( + "bytes" "fmt" "io" "io/ioutil" @@ -8,6 +9,7 @@ import ( "path/filepath" "sort" "strings" + "text/template" "github.com/aptly-dev/aptly/aptly" "github.com/aptly-dev/aptly/pgp" @@ -164,7 +166,7 @@ func (c *Changes) Cleanup() error { } // PackageQuery returns query that every package should match to be included -func (c *Changes) PackageQuery() (PackageQuery, error) { +func (c *Changes) PackageQuery() PackageQuery { var archQuery PackageQuery = &FieldQuery{Field: "$Architecture", Relation: VersionEqual, Value: ""} for _, arch := range c.Architectures { archQuery = &OrQuery{L: &FieldQuery{Field: "$Architecture", Relation: VersionEqual, Value: arch}, R: archQuery} @@ -215,7 +217,7 @@ func (c *Changes) PackageQuery() (PackageQuery, error) { nameQuery = &OrQuery{L: sourceQuery, R: binaryQuery} } - return &AndQuery{L: archQuery, R: nameQuery}, nil + return &AndQuery{L: archQuery, R: nameQuery} } // GetField implements PackageLike interface @@ -288,3 +290,143 @@ func CollectChangesFiles(locations []string, reporter aptly.ResultReporter) (cha return } + +// ImportChangesFiles imports referenced files in changes files into local repository +func ImportChangesFiles(changesFiles []string, reporter aptly.ResultReporter, acceptUnsigned, ignoreSignatures, forceReplace, noRemoveFiles bool, + verifier pgp.Verifier, repoTemplateString string, progress aptly.Progress, localRepoCollection *LocalRepoCollection, packageCollection *PackageCollection, + pool aptly.PackagePool, checksumStorage aptly.ChecksumStorage, uploaders *Uploaders, parseQuery parseQuery) (processedFiles []string, failedFiles []string, err error) { + + var repoTemplate *template.Template + repoTemplate, err = template.New("repo").Parse(repoTemplateString) + if err != nil { + return nil, nil, fmt.Errorf("error parsing -repo template: %s", err) + } + for _, path := range changesFiles { + var changes *Changes + + changes, err = NewChanges(path) + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", path, err) + continue + } + + err = changes.VerifyAndParse(acceptUnsigned, ignoreSignatures, verifier) + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + err = changes.Prepare() + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + repoName := &bytes.Buffer{} + err = repoTemplate.Execute(repoName, changes.Stanza) + if err != nil { + return nil, nil, fmt.Errorf("error applying template to repo: %s", err) + } + + if progress != nil { + progress.Printf("Loading repository %s for changes file %s...\n", repoName.String(), changes.ChangesName) + } + + var repo *LocalRepo + repo, err = localRepoCollection.ByName(repoName.String()) + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + currentUploaders := uploaders + if repo.Uploaders != nil { + currentUploaders = repo.Uploaders + for i := range currentUploaders.Rules { + currentUploaders.Rules[i].CompiledCondition, err = parseQuery(currentUploaders.Rules[i].Condition) + if err != nil { + return nil, nil, fmt.Errorf("error parsing query %s: %s", currentUploaders.Rules[i].Condition, err) + } + } + } + + if currentUploaders != nil { + if err = currentUploaders.IsAllowed(changes); err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("changes file skipped due to uploaders config: %s, keys %#v: %s", + changes.ChangesName, changes.SignatureKeys, err) + changes.Cleanup() + continue + } + } + + err = localRepoCollection.LoadComplete(repo) + if err != nil { + return nil, nil, fmt.Errorf("unable to load repo: %s", err) + } + + var list *PackageList + list, err = NewPackageListFromRefList(repo.RefList(), packageCollection, progress) + if err != nil { + return nil, nil, fmt.Errorf("unable to load packages: %s", err) + } + + packageFiles, otherFiles, _ := CollectPackageFiles([]string{changes.TempDir}, reporter) + + restriction := changes.PackageQuery() + var processedFiles2, failedFiles2 []string + + processedFiles2, failedFiles2, err = ImportPackageFiles(list, packageFiles, forceReplace, verifier, pool, + packageCollection, reporter, restriction, checksumStorage) + + if err != nil { + return nil, nil, fmt.Errorf("unable to import package files: %s", err) + } + + repo.UpdateRefList(NewPackageRefListFromPackageList(list)) + + err = localRepoCollection.Update(repo) + if err != nil { + return nil, nil, fmt.Errorf("unable to save: %s", err) + } + + err = changes.Cleanup() + if err != nil { + return nil, nil, err + } + + for _, file := range failedFiles2 { + failedFiles = append(failedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) + } + + for _, file := range processedFiles2 { + processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) + } + + for _, file := range otherFiles { + processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) + } + + processedFiles = append(processedFiles, path) + } + + if !noRemoveFiles { + processedFiles = utils.StrSliceDeduplicate(processedFiles) + + for _, file := range processedFiles { + err = os.Remove(file) + if err != nil { + return nil, nil, fmt.Errorf("unable to remove file: %s", err) + } + } + } + + return processedFiles, failedFiles, nil +} diff --git a/deb/deb.go b/deb/deb.go index cb4d85255..292e93ec8 100644 --- a/deb/deb.go +++ b/deb/deb.go @@ -26,6 +26,8 @@ const ( SourceRemoteRepo = "repo" ) +type parseQuery func(string) (PackageQuery, error) + // GetControlFileFromDeb reads control file from deb package func GetControlFileFromDeb(packageFile string) (Stanza, error) { file, err := os.Open(packageFile) diff --git a/system/t12_api/repos.py b/system/t12_api/repos.py index a4a6e353e..f327df2aa 100644 --- a/system/t12_api/repos.py +++ b/system/t12_api/repos.py @@ -176,6 +176,38 @@ def check(self): self.check_not_exists("upload/" + d) +class ReposAPITestInclude(APITest): + """ + POST /api/repos/:name/include/:dir, GET /api/repos/:name/packages + """ + def check(self): + repo_name = self.random_name() + + self.check_equal(self.post("/api/repos", json={"Name": repo_name, "Comment": "fun repo"}).status_code, 201) + + d = self.random_name() + resp = self.upload("/api/files/" + d, "hardlink_0.2.1_amd64.changes", + "hardlink_0.2.1.dsc", "hardlink_0.2.1.tar.gz", + "hardlink_0.2.1_amd64.deb", directory='changes') + self.check_equal(resp.status_code, 200) + + resp = self.post("/api/repos/" + repo_name + "/include/" + d, params={"ignoreSignature": 1}) + self.check_equal(resp.status_code, 200) + self.check_equal(resp.json(), { + u'FailedFiles': [], + u'Report': { + u'Added': [u'hardlink_0.2.1_source added', 'hardlink_0.2.1_amd64 added'], + u'Removed': [], + u'Warnings': []}}) + + self.check_equal( + sorted(self.get("/api/repos/" + repo_name + "/packages").json()), + [u'Pamd64 hardlink 0.2.1 daf8fcecbf8210ad', u'Psource hardlink 0.2.1 8f72df429d7166e5'] + ) + + self.check_not_exists("upload/" + d) + + class ReposAPITestShowQuery(APITest): """ GET /api/repos/:name/packages?q=query From 9509629bcffef832f4532add5ef3d10a61f7a802 Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Mon, 18 Jun 2018 17:13:19 +0200 Subject: [PATCH 2/2] Add changes test to increase coverage --- deb/changes_test.go | 142 ++++++++++----- deb/testdata/changes/calamares.changes | 32 ++++ deb/testdata/changes/hardlink_0.2.0_i386.deb | Bin 0 -> 12084 bytes .../hardlink_0.2.1-invalidfiles_amd64.changes | 22 +++ .../hardlink_0.2.1-invalidsig_amd64.changes | 39 ++++ deb/testdata/changes/hardlink_0.2.1.dsc | 19 ++ deb/testdata/changes/hardlink_0.2.1.tar.gz | Bin 0 -> 12516 bytes .../changes/hardlink_0.2.1_amd64.buildinfo | 170 ++++++++++++++++++ .../changes/hardlink_0.2.1_amd64.changes | 34 ++++ deb/testdata/changes/hardlink_0.2.1_amd64.deb | Bin 0 -> 12468 bytes 10 files changed, 417 insertions(+), 41 deletions(-) create mode 100644 deb/testdata/changes/calamares.changes create mode 100644 deb/testdata/changes/hardlink_0.2.0_i386.deb create mode 100644 deb/testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes create mode 100644 deb/testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes create mode 100644 deb/testdata/changes/hardlink_0.2.1.dsc create mode 100644 deb/testdata/changes/hardlink_0.2.1.tar.gz create mode 100644 deb/testdata/changes/hardlink_0.2.1_amd64.buildinfo create mode 100644 deb/testdata/changes/hardlink_0.2.1_amd64.changes create mode 100644 deb/testdata/changes/hardlink_0.2.1_amd64.deb diff --git a/deb/changes_test.go b/deb/changes_test.go index 65b219360..2a848d6aa 100644 --- a/deb/changes_test.go +++ b/deb/changes_test.go @@ -4,24 +4,52 @@ import ( "os" "path/filepath" + "github.com/aptly-dev/aptly/aptly" + "github.com/aptly-dev/aptly/console" + "github.com/aptly-dev/aptly/database" + "github.com/aptly-dev/aptly/files" + "github.com/aptly-dev/aptly/utils" + . "gopkg.in/check.v1" ) type ChangesSuite struct { - Dir, Path string + Dir, Path string + Reporter aptly.ResultReporter + db database.Storage + localRepoCollection *LocalRepoCollection + packageCollection *PackageCollection + packagePool aptly.PackagePool + checksumStorage aptly.ChecksumStorage + progress aptly.Progress } var _ = Suite(&ChangesSuite{}) func (s *ChangesSuite) SetUpTest(c *C) { + s.Reporter = &aptly.RecordingResultReporter{ + Warnings: []string{}, + AddedLines: []string{}, + RemovedLines: []string{}, + } s.Dir = c.MkDir() s.Path = filepath.Join(s.Dir, "calamares.changes") - - f, err := os.Create(s.Path) + err := utils.CopyFile("testdata/changes/calamares.changes", s.Path) c.Assert(err, IsNil) - f.WriteString(changesFile) - f.Close() + s.db, _ = database.NewOpenDB(c.MkDir()) + s.localRepoCollection = NewLocalRepoCollection(s.db) + s.packageCollection = NewPackageCollection(s.db) + + s.checksumStorage = files.NewMockChecksumStorage() + s.packagePool = files.NewPackagePool(s.Dir, false) + s.progress = console.NewProgress() + s.progress.Start() +} + +func (s *ChangesSuite) TearDownTest(c *C) { + s.progress.Shutdown() + s.db.Close() } func (s *ChangesSuite) TestParseAndVerify(c *C) { @@ -44,6 +72,73 @@ func (s *ChangesSuite) TestParseAndVerify(c *C) { c.Check(changes.Binary, DeepEquals, []string{"calamares", "calamares-dbg"}) } +func (s *ChangesSuite) TestCollectChangesFiles(c *C) { + changesFiles, failedFiles := CollectChangesFiles([]string{"testdata/changes"}, s.Reporter) + + c.Check(failedFiles, HasLen, 0) + c.Check(changesFiles, DeepEquals, []string{ + "testdata/changes/calamares.changes", + "testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes", + "testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes", + "testdata/changes/hardlink_0.2.1_amd64.changes", + }) +} + +func (s *ChangesSuite) TestImportChangesFiles(c *C) { + repo := NewLocalRepo("test", "Test Comment") + c.Assert(s.localRepoCollection.Add(repo), IsNil) + + origFailedFiles := []string{ + "testdata/changes/calamares.changes", + "testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes", + "testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes", + "testdata/changes/hardlink_0.2.0_i386.deb", + } + origProcessedFiles := []string{ + "testdata/changes/hardlink_0.2.1.dsc", + "testdata/changes/hardlink_0.2.1.tar.gz", + "testdata/changes/hardlink_0.2.1_amd64.deb", + "testdata/changes/hardlink_0.2.1_amd64.buildinfo", + "testdata/changes/hardlink_0.2.1_amd64.changes", + } + + var expectedProcessedFiles, expectedFailedFiles []string + + for _, path := range origFailedFiles { + filename := filepath.Join(s.Dir, filepath.Base(path)) + utils.CopyFile(path, filename) + expectedFailedFiles = append(expectedFailedFiles, filename) + } + + for _, path := range origProcessedFiles { + filename := filepath.Join(s.Dir, filepath.Base(path)) + utils.CopyFile(path, filename) + expectedProcessedFiles = append(expectedProcessedFiles, filename) + } + + changesFiles, failedFiles := CollectChangesFiles([]string{s.Dir}, s.Reporter) + c.Check(failedFiles, HasLen, 0) + + processedFiles, failedFiles, err := ImportChangesFiles( + append(changesFiles, "testdata/changes/notexistent.changes"), + s.Reporter, true, true, false, false, &NullVerifier{}, + "test", s.progress, s.localRepoCollection, s.packageCollection, s.packagePool, s.checksumStorage, + nil, nil) + c.Assert(err, IsNil) + c.Check(failedFiles, DeepEquals, append(expectedFailedFiles, "testdata/changes/notexistent.changes")) + c.Check(processedFiles, DeepEquals, expectedProcessedFiles) +} + +func (s *ChangesSuite) TestPrepare(c *C) { + changes, err := NewChanges("testdata/changes/hardlink_0.2.1_amd64.changes") + c.Assert(err, IsNil) + err = changes.Prepare() + c.Assert(err, IsNil) + + _, err = os.Stat(filepath.Join(changes.TempDir, "hardlink_0.2.1_amd64.changes")) + c.Check(err, IsNil) +} + func (s *ChangesSuite) TestPackageQuery(c *C) { changes, err := NewChanges(s.Path) c.Assert(err, IsNil) @@ -51,42 +146,7 @@ func (s *ChangesSuite) TestPackageQuery(c *C) { err = changes.VerifyAndParse(true, true, &NullVerifier{}) c.Check(err, IsNil) - q, err := changes.PackageQuery() - c.Check(err, IsNil) - + q := changes.PackageQuery() c.Check(q.String(), Equals, "(($Architecture (= amd64)) | (($Architecture (= source)) | ($Architecture (= )))), ((($PackageType (= source)), (Name (= calamares))) | ((!($PackageType (= source))), (((Name (= calamares-dbg)) | (Name (= calamares))) | ((Source (= calamares)), ((Name (= calamares-dbg-dbgsym)) | (Name (= calamares-dbgsym)))))))") } - -var changesFile = `Format: 1.8 -Date: Thu, 27 Nov 2014 13:24:53 +0000 -Source: calamares -Binary: calamares calamares-dbg -Architecture: source amd64 -Version: 0+git20141127.99 -Distribution: sid -Urgency: medium -Maintainer: Rohan Garg -Changed-By: Rohan -Description: - calamares - distribution-independent installer framework - calamares-dbg - distribution-independent installer framework -- debug symbols -Changes: - calamares (0+git20141127.99) sid; urgency=medium - . - * Update from git -Checksums-Sha1: - 79f10e955dab6eb25b7f7bae18213f367a3a0396 1106 calamares_0+git20141127.99.dsc - 294c28e2c8e34e72ca9ee0d9da5c14f3bf4188db 2694800 calamares_0+git20141127.99.tar.xz - d6c26c04b5407c7511f61cb3e3de60c4a1d6c4ff 1698924 calamares_0+git20141127.99_amd64.deb - a3da632d193007b0d4a1aff73159fde1b532d7a8 12835902 calamares-dbg_0+git20141127.99_amd64.deb -Checksums-Sha256: - 35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc 1106 calamares_0+git20141127.99.dsc - 5576b9caaf814564830f95561227e4f04ee87b31da22c1371aab155cbf7ce395 2694800 calamares_0+git20141127.99.tar.xz - 2e6e2f232ed7ffe52369928ebdf5436d90feb37840286ffba79e87d57a43a2e9 1698924 calamares_0+git20141127.99_amd64.deb - 8dd926080ed7bad2e2439e37e49ce12d5f1357c5041b7da4d860a1041f878a8a 12835902 calamares-dbg_0+git20141127.99_amd64.deb -Files: - 05fd8f3ffe8f362c5ef9bad2f936a56e 1106 devel optional calamares_0+git20141127.99.dsc - 097e55c81abd8e5f30bb2eed90c2c1e9 2694800 devel optional calamares_0+git20141127.99.tar.xz - 827fb3b12534241e119815d331e8197b 1698924 devel optional calamares_0+git20141127.99_amd64.deb - e6f8ce70f564d1f68cb57758b15b13e3 12835902 debug optional calamares-dbg_0+git20141127.99_amd64.deb` diff --git a/deb/testdata/changes/calamares.changes b/deb/testdata/changes/calamares.changes new file mode 100644 index 000000000..143f8d83d --- /dev/null +++ b/deb/testdata/changes/calamares.changes @@ -0,0 +1,32 @@ +Format: 1.8 +Date: Thu, 27 Nov 2014 13:24:53 +0000 +Source: calamares +Binary: calamares calamares-dbg +Architecture: source amd64 +Version: 0+git20141127.99 +Distribution: sid +Urgency: medium +Maintainer: Rohan Garg +Changed-By: Rohan +Description: + calamares - distribution-independent installer framework + calamares-dbg - distribution-independent installer framework -- debug symbols +Changes: + calamares (0+git20141127.99) sid; urgency=medium + . + * Update from git +Checksums-Sha1: + 79f10e955dab6eb25b7f7bae18213f367a3a0396 1106 calamares_0+git20141127.99.dsc + 294c28e2c8e34e72ca9ee0d9da5c14f3bf4188db 2694800 calamares_0+git20141127.99.tar.xz + d6c26c04b5407c7511f61cb3e3de60c4a1d6c4ff 1698924 calamares_0+git20141127.99_amd64.deb + a3da632d193007b0d4a1aff73159fde1b532d7a8 12835902 calamares-dbg_0+git20141127.99_amd64.deb +Checksums-Sha256: + 35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc 1106 calamares_0+git20141127.99.dsc + 5576b9caaf814564830f95561227e4f04ee87b31da22c1371aab155cbf7ce395 2694800 calamares_0+git20141127.99.tar.xz + 2e6e2f232ed7ffe52369928ebdf5436d90feb37840286ffba79e87d57a43a2e9 1698924 calamares_0+git20141127.99_amd64.deb + 8dd926080ed7bad2e2439e37e49ce12d5f1357c5041b7da4d860a1041f878a8a 12835902 calamares-dbg_0+git20141127.99_amd64.deb +Files: + 05fd8f3ffe8f362c5ef9bad2f936a56e 1106 devel optional calamares_0+git20141127.99.dsc + 097e55c81abd8e5f30bb2eed90c2c1e9 2694800 devel optional calamares_0+git20141127.99.tar.xz + 827fb3b12534241e119815d331e8197b 1698924 devel optional calamares_0+git20141127.99_amd64.deb + e6f8ce70f564d1f68cb57758b15b13e3 12835902 debug optional calamares-dbg_0+git20141127.99_amd64.deb diff --git a/deb/testdata/changes/hardlink_0.2.0_i386.deb b/deb/testdata/changes/hardlink_0.2.0_i386.deb new file mode 100644 index 0000000000000000000000000000000000000000..cbc51c363326da15eec7af8b3f52dfa1ff90e9e8 GIT binary patch literal 12084 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 literal 0 HcmV?d00001 diff --git a/deb/testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes b/deb/testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes new file mode 100644 index 000000000..e90edf9e3 --- /dev/null +++ b/deb/testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes @@ -0,0 +1,22 @@ +Format: 1.8 +Date: Sat, 12 May 2014 12:57:02 +0200 +Source: hardlink +Binary: hardlink +Architecture: source amd64 +Version: 0.2.1 +Distribution: unstable +Urgency: low +Maintainer: Julian Andres Klode +Changed-By: Aptly Tester (don't use it) +Description: + hardlink - Hardlinks multiple copies of the same file +Changes: + hardlink (0.2.1) unstable; urgency=low + . + * Update just to try it out :) +Checksums-Sha1: + ff306b8f923653b78e00c45ebbc6c1c734859cdf 949 invalidhardlink_0.2.1.dsc +Checksums-Sha256: + c0d7458aa2ca3886cd6885f395a289efbc9a396e6765cbbca45f51fde859ea70 949 invalidhardlink_0.2.1.dsc +Files: + 4efce26825af5842f43961096dd890b3 949 utils optional invalidhardlink_0.2.1.dsc diff --git a/deb/testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes b/deb/testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes new file mode 100644 index 000000000..c48899eaf --- /dev/null +++ b/deb/testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes @@ -0,0 +1,39 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +Format: 1.8 +Date: Sat, 12 May 2014 12:57:02 +0200 +Source: hardlink +Binary: hardlink +Architecture: source amd64 +Version: 0.2.1 +Distribution: unstable +Urgency: low +Maintainer: Julian Andres Klode +Changed-By: Aptly Tester (don't use it) +Description: + hardlink - Hardlinks multiple copies of the same file +Changes: + hardlink (0.2.1) unstable; urgency=low + . + * Update just to try it out :) +Checksums-Sha1: + ff306b8f923653b78e00c45ebbc6c1c734859cdf 949 hardlink_0.2.1.dsc + 6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz + 1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb +Checksums-Sha256: + c0d7458aa2ca3886cd6885f395a289efbc9a396e6765cbbca45f51fde859ea70 949 hardlink_0.2.1.dsc + 4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz + 668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb +Files: + 4efce26825af5842f43961096dd890b3 949 utils optional hardlink_0.2.1.dsc + 8e2caa4d82f228bac08dc9a38bc6edb3 12516 utils optional hardlink_0.2.1.tar.gz + 2081e20b36c47f82811c25841cc0e41b 12468 utils optional hardlink_0.2.1_amd64.deb + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.12 (GNU/Linux) + +iEYEARECAAYFAlUFwywACgkQIdu4nBbbPm1DLACgwW4V8qLQC/QHC/7+t3Iq47Ez +eesAn3ZYLQvLYRw3wPTKVAPI+AW6Fjxi +=hRBo +-----END PGP SIGNATURE----- diff --git a/deb/testdata/changes/hardlink_0.2.1.dsc b/deb/testdata/changes/hardlink_0.2.1.dsc new file mode 100644 index 000000000..bda202ae1 --- /dev/null +++ b/deb/testdata/changes/hardlink_0.2.1.dsc @@ -0,0 +1,19 @@ +Format: 1.0 +Source: hardlink +Binary: hardlink +Architecture: any +Version: 0.2.1 +Maintainer: Julian Andres Klode +Homepage: http://jak-linux.org/projects/hardlink/ +Standards-Version: 3.9.3 +Vcs-Browser: http://git.debian.org/?p=users/jak/hardlink.git;a=summary +Vcs-Git: git://git.debian.org/git/users/jak/hardlink.git +Build-Depends: debhelper (>= 9), pkg-config, libpcre3-dev +Package-List: + hardlink deb utils optional +Checksums-Sha1: + 6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz +Checksums-Sha256: + 4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz +Files: + 8e2caa4d82f228bac08dc9a38bc6edb3 12516 hardlink_0.2.1.tar.gz diff --git a/deb/testdata/changes/hardlink_0.2.1.tar.gz b/deb/testdata/changes/hardlink_0.2.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..560b9811864a65be05740ea5e6ea709d23eeb9c1 GIT binary patch literal 12516 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 literal 0 HcmV?d00001 diff --git a/deb/testdata/changes/hardlink_0.2.1_amd64.buildinfo b/deb/testdata/changes/hardlink_0.2.1_amd64.buildinfo new file mode 100644 index 000000000..f037edf87 --- /dev/null +++ b/deb/testdata/changes/hardlink_0.2.1_amd64.buildinfo @@ -0,0 +1,170 @@ +Format: 1.0 +Source: hardlink +Binary: hardlink +Architecture: amd64 +Version: 0.2.0 +Checksums-Md5: + 2081e20b36c47f82811c25841cc0e41b 12468 hardlink_0.2.1_amd64.deb +Checksums-Sha1: + 1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb +Checksums-Sha256: + 668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb +Build-Origin: Debian +Build-Architecture: amd64 +Build-Kernel-Version: 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) +Build-Date: Sun, 21 Jul 2019 08:01:03 +1400 +Build-Path: /build/hardlink-0.3.0/2nd +Installed-Build-Depends: + autoconf (= 2.69-11), + automake (= 1:1.15.1-3.1), + autopoint (= 0.19.8.1-6), + autotools-dev (= 20180224.1), + base-files (= 10.1), + base-passwd (= 3.5.45), + bash (= 4.4.18-3), + binutils (= 2.30-21), + binutils-common (= 2.30-21), + binutils-x86-64-linux-gnu (= 2.30-21), + bsdmainutils (= 11.1.2+b1), + bsdutils (= 1:2.32-0.1), + build-essential (= 12.5), + bzip2 (= 1.0.6-8.1), + coreutils (= 8.28-1), + cpp (= 4:7.3.0-3), + cpp-7 (= 7.3.0-26+really21.0~reproducible0), + dash (= 0.5.8-2.10), + debconf (= 1.5.67), + debhelper (= 11.3.2), + debianutils (= 4.8.6), + dh-autoreconf (= 19), + dh-strip-nondeterminism (= 0.042-1), + diffutils (= 1:3.6-1), + dpkg (= 1.19.0.5.0~reproducible1), + dpkg-dev (= 1.19.0.5.0~reproducible1), + dwz (= 0.12-2), + fdisk (= 2.32-0.1), + file (= 1:5.33-3), + findutils (= 4.6.0+git+20171230-2), + g++ (= 4:7.3.0-3), + g++-7 (= 7.3.0-26+really21.0~reproducible0), + gcc (= 4:7.3.0-3), + gcc-7 (= 7.3.0-26+really21.0~reproducible0), + gcc-7-base (= 7.3.0-26+really21.0~reproducible0), + gcc-8-base (= 8.1.0-6), + gettext (= 0.19.8.1-6+b1), + gettext-base (= 0.19.8.1-6+b1), + grep (= 3.1-2), + groff-base (= 1.22.3-10), + gzip (= 1.6-5+b1), + hostname (= 3.20), + init-system-helpers (= 1.51), + intltool-debian (= 0.35.0+20060710.4), + libacl1 (= 2.2.52-3+b1), + libarchive-zip-perl (= 1.60-1), + libasan4 (= 7.3.0-26+really21.0~reproducible0), + libatomic1 (= 8.1.0-6), + libattr1 (= 1:2.4.47-2+b2), + libattr1-dev (= 1:2.4.47-2+b2), + libaudit-common (= 1:2.8.3-1), + libaudit1 (= 1:2.8.3-1), + libbinutils (= 2.30-21), + libblkid1 (= 2.32-0.1), + libbsd0 (= 0.9.1-1), + libbz2-1.0 (= 1.0.6-8.1), + libc-bin (= 2.27-3), + libc-dev-bin (= 2.27-3), + libc6 (= 2.27-3), + libc6-dev (= 2.27-3), + libcap-ng0 (= 0.7.9-1), + libcc1-0 (= 8.1.0-6), + libcilkrts5 (= 7.3.0-26+really21.0~reproducible0), + libcroco3 (= 0.6.12-2), + libdb5.3 (= 5.3.28-13.1+b1), + libdebconfclient0 (= 0.243), + libdpkg-perl (= 1.19.0.5.0~reproducible1), + libelf1 (= 0.170-0.4), + libfdisk1 (= 2.32-0.1), + libffi6 (= 3.2.1-8), + libfile-stripnondeterminism-perl (= 0.042-1), + libfreetype6 (= 2.8.1-2), + libgcc-7-dev (= 7.3.0-26+really21.0~reproducible0), + libgcc1 (= 1:8.1.0-6), + libgcrypt20 (= 1.8.3-1), + libgdbm-compat4 (= 1.14.1-6+b1), + libgdbm5 (= 1.14.1-6+b1), + libglib2.0-0 (= 2.56.1-2), + libgmp10 (= 2:6.1.2+dfsg-3), + libgomp1 (= 8.1.0-6), + libgpg-error0 (= 1.31-1), + libgraphite2-3 (= 1.3.11-2), + libharfbuzz0b (= 1.7.6-1+b1), + libicu-le-hb0 (= 1.0.3+git161113-5), + libicu60 (= 60.2-6), + libisl19 (= 0.19-1), + libitm1 (= 8.1.0-6), + liblsan0 (= 8.1.0-6), + liblz4-1 (= 1.8.2-1), + liblzma5 (= 5.2.2-1.3), + libmagic-mgc (= 1:5.33-3), + libmagic1 (= 1:5.33-3), + libmount1 (= 2.32-0.1), + libmpc3 (= 1.1.0-1), + libmpfr6 (= 4.0.1-1), + libmpx2 (= 8.1.0-6), + libncurses6 (= 6.1+20180210-4), + libncursesw6 (= 6.1+20180210-4), + libpam-modules (= 1.1.8-3.7), + libpam-modules-bin (= 1.1.8-3.7), + libpam-runtime (= 1.1.8-3.7), + libpam0g (= 1.1.8-3.7), + libpcre16-3 (= 2:8.39-9), + libpcre3 (= 2:8.39-9), + libpcre3-dev (= 2:8.39-9), + libpcre32-3 (= 2:8.39-9), + libpcrecpp0v5 (= 2:8.39-9), + libperl5.26 (= 5.26.2-6), + libpipeline1 (= 1.5.0-1), + libpng16-16 (= 1.6.34-1), + libquadmath0 (= 8.1.0-6), + libseccomp2 (= 2.3.3-2), + libselinux1 (= 2.8-1), + libsigsegv2 (= 2.12-2), + libsmartcols1 (= 2.32-0.1), + libstdc++-7-dev (= 7.3.0-26+really21.0~reproducible0), + libstdc++6 (= 8.1.0-6), + libsystemd0 (= 238-5), + libtimedate-perl (= 2.3000-2), + libtinfo6 (= 6.1+20180210-4), + libtool (= 2.4.6-2.1), + libtsan0 (= 8.1.0-6), + libubsan0 (= 7.3.0-26+really21.0~reproducible0), + libudev1 (= 238-5), + libunistring2 (= 0.9.8-1), + libuuid1 (= 2.32-0.1), + libxml2 (= 2.9.4+dfsg1-7), + linux-libc-dev (= 4.16.12-1), + login (= 1:4.5-1), + m4 (= 1.4.18-1), + make (= 4.2.1-1), + man-db (= 2.8.3-2), + mawk (= 1.3.3-17+b3), + ncurses-base (= 6.1+20180210-4), + ncurses-bin (= 6.1+20180210-4), + patch (= 2.7.6-2), + perl (= 5.26.2-6), + perl-base (= 5.26.2-6), + perl-modules-5.26 (= 5.26.2-6), + pkg-config (= 0.29-4+b1), + po-debconf (= 1.0.20), + sed (= 4.4-2), + sysvinit-utils (= 2.88dsf-59.10), + tar (= 1.30+dfsg-2), + util-linux (= 2.32-0.1), + xz-utils (= 5.2.2-1.3), + zlib1g (= 1:1.2.11.dfsg-1) +Environment: + BUILD_PATH_PREFIX_MAP="hardlink_0.3.0=/build/hardlink-0.3.0/2nd" + DEB_BUILD_OPTIONS="buildinfo=+all parallel=16" + LANG="C" + LC_ALL="C" + SOURCE_DATE_EPOCH="1411647982" diff --git a/deb/testdata/changes/hardlink_0.2.1_amd64.changes b/deb/testdata/changes/hardlink_0.2.1_amd64.changes new file mode 100644 index 000000000..dcc80c023 --- /dev/null +++ b/deb/testdata/changes/hardlink_0.2.1_amd64.changes @@ -0,0 +1,34 @@ +Format: 1.8 +Date: Sat, 12 May 2014 12:57:02 +0200 +Source: hardlink +Binary: hardlink +Architecture: source amd64 +Version: 0.2.1 +Distribution: unstable +Urgency: low +Maintainer: Julian Andres Klode +Changed-By: Aptly Tester (don't use it) +Description: + hardlink - Hardlinks multiple copies of the same file +Changes: + hardlink (0.2.1) unstable; urgency=low + . + * Update just to try it out :) +Checksums-Sha1: + d20d6820bfccf5e3a5b120eedabba96e71da60ff 703 hardlink_0.2.1.dsc + 6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz + 1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb + 06c38a55e81907e573641d7f979f428583bd3165 4885 hardlink_0.2.1_amd64.buildinfo + be2b66e32b29ab654190e7ecb4cc31f48ec061cb 12084 hardlink_0.2.0_i386.deb +Checksums-Sha256: + 19d08cfadd58aee05fd06aca261a873bafeb55cac58bf4916cc070f5821803e7 703 hardlink_0.2.1.dsc + 4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz + 668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb + 2a4905626b8664868b712a5b3d21f44c2665d17f9a4b67dc2e2bfd03f4ec54ee 4885 hardlink_0.2.1_amd64.buildinfo + a9d657d9413029e484c2a8c059c95a3e31eb1b47eca96455c1b9c330352293c9 12084 hardlink_0.2.0_i386.deb +Files: + b75fe0616f24deb28a3017c1dbae219a 703 utils optional hardlink_0.2.1.dsc + 8e2caa4d82f228bac08dc9a38bc6edb3 12516 utils optional hardlink_0.2.1.tar.gz + 2081e20b36c47f82811c25841cc0e41b 12468 utils optional hardlink_0.2.1_amd64.deb + 9468a19700d038fa6cd10c5e42063083 12084 utils optional hardlink_0.2.0_i386.deb + 490174686848eca6da4e5f79d899efe7 4885 utils optional hardlink_0.2.1_amd64.buildinfo diff --git a/deb/testdata/changes/hardlink_0.2.1_amd64.deb b/deb/testdata/changes/hardlink_0.2.1_amd64.deb new file mode 100644 index 0000000000000000000000000000000000000000..739d28492e18261120b7bdcde635f5a8639d6b00 GIT binary patch literal 12468 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