diff --git a/internal/setup/setup.go b/internal/setup/setup.go index c47c0507..6f5ffda8 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -18,10 +18,9 @@ import ( // Release is a collection of package slices targeting a particular // distribution version. type Release struct { - Path string - Packages map[string]*Package - Archives map[string]*Archive - DefaultArchive string + Path string + Packages map[string]*Package + Archives map[string]*Archive } // Archive is the location from which binary packages are obtained. @@ -34,10 +33,9 @@ type Archive struct { // Package holds a collection of slices that represent parts of themselves. type Package struct { - Name string - Path string - Archive string - Slices map[string]*Slice + Name string + Path string + Slices map[string]*Slice } // Slice holds the details about a package slice. @@ -306,9 +304,6 @@ func readSlices(release *Release, baseDir, dirName string) error { if err != nil { return err } - if pkg.Archive == "" { - pkg.Archive = release.DefaultArchive - } release.Packages[pkg.Name] = pkg } @@ -326,7 +321,6 @@ type yamlArchive struct { Version string `yaml:"version"` Suites []string `yaml:"suites"` Components []string `yaml:"components"` - Default bool `yaml:"default"` } type yamlPackage struct { @@ -428,14 +422,6 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { if len(details.Components) == 0 { return nil, fmt.Errorf("%s: archive %q missing components field", fileName, archiveName) } - if len(yamlVar.Archives) == 1 { - details.Default = true - } else if details.Default && release.DefaultArchive != "" { - return nil, fmt.Errorf("%s: more than one default archive: %s, %s", fileName, release.DefaultArchive, archiveName) - } - if details.Default { - release.DefaultArchive = archiveName - } release.Archives[archiveName] = &Archive{ Name: archiveName, Version: details.Version, @@ -464,7 +450,6 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro if yamlPkg.Name != pkg.Name { return nil, fmt.Errorf("%s: filename and 'package' field (%q) disagree", pkgPath, yamlPkg.Name) } - pkg.Archive = yamlPkg.Archive zeroPath := yamlPath{} for sliceName, yamlSlice := range yamlPkg.Slices { diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 43824d20..10b39269 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -62,8 +62,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -74,10 +72,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, }, @@ -105,8 +102,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -117,9 +112,8 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -166,8 +160,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -178,9 +170,8 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -426,8 +417,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -438,9 +427,8 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -640,8 +628,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -652,9 +638,8 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -679,8 +664,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -691,9 +674,8 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -719,8 +701,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "ubuntu", - Archives: map[string]*setup.Archive{ "ubuntu": { Name: "ubuntu", @@ -731,9 +711,8 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "ubuntu", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -757,7 +736,6 @@ var setupTests = []setupTest{{ version: 22.04 components: [main, universe] suites: [jammy] - default: true bar: version: 22.04 components: [universe] @@ -768,8 +746,6 @@ var setupTests = []setupTest{{ `, }, release: &setup.Release{ - DefaultArchive: "foo", - Archives: map[string]*setup.Archive{ "foo": { Name: "foo", @@ -786,10 +762,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Archive: "foo", - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, }, diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 2b684b5d..68a677f4 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -59,7 +59,6 @@ func Run(options *RunOptions) error { syscall.Umask(oldUmask) }() - release := options.Selection.Release targetDir := filepath.Clean(options.TargetDir) targetDirAbs := targetDir if !filepath.IsAbs(targetDirAbs) { @@ -74,15 +73,23 @@ func Run(options *RunOptions) error { for _, slice := range options.Selection.Slices { extractPackage := extract[slice.Package] if extractPackage == nil { - archiveName := release.Packages[slice.Package].Archive - archive := options.Archives[archiveName] - if archive == nil { - return fmt.Errorf("archive %q not defined", archiveName) + var selectedVersion string + var selectedArchive archive.Archive + for _, currentArchive := range options.Archives { + pkgInfo := currentArchive.Info(slice.Package) + if pkgInfo == nil { + continue + } + currentVersion := pkgInfo.Version() + if selectedVersion == "" || deb.CompareVersions(selectedVersion, currentVersion) < 0 { + selectedVersion = currentVersion + selectedArchive = currentArchive + } } - if !archive.Exists(slice.Package) { + if selectedVersion == "" { return fmt.Errorf("slice package %q missing from archive", slice.Package) } - archives[slice.Package] = archive + archives[slice.Package] = selectedArchive extractPackage = make(map[string][]deb.ExtractInfo) extract[slice.Package] = extractPackage } diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index 9433c27e..a5409459 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -509,7 +509,6 @@ var slicerTests = []slicerTest{{ foo: version: 22.04 components: [main, universe] - default: true bar: version: 22.04 components: [main] @@ -563,7 +562,6 @@ var slicerTests = []slicerTest{{ version: 1 suites: [main] components: [main, universe] - default: true hadrons: version: 1 suites: [main] @@ -578,7 +576,6 @@ var slicerTests = []slicerTest{{ `, "slices/mydir/proton.yaml": ` package: proton - archive: hadrons slices: mass: contents: @@ -599,6 +596,97 @@ var slicerTests = []slicerTest{{ "/usr/share/doc/electron/": "dir 0755", "/usr/share/doc/electron/copyright": "file 0644 empty", }, +}, { + summary: "Can pick latest packages from multiple archives", + pkgs: map[string]map[string]testPackage{ + "vertebrates": { + "cheetah": testPackage{ + info: map[string]string{ + "Version": "109.4", + }, + content: testutil.MustMakeDeb([]testutil.TarEntry{ + DIR(0755, "./"), + DIR(0755, "./speed/"), + REG(0644, "./speed/cheetah", "109.4 km/h\n"), + }), + }, + "ostrich": testPackage{ + info: map[string]string{ + "Version": "100.0", + }, + content: testutil.MustMakeDeb([]testutil.TarEntry{ + DIR(0755, "./"), + DIR(0755, "./speed/"), + REG(0644, "./speed/ostrich", "100.0 km/h\n"), + }), + }, + }, + "mammals": { + "cheetah": testPackage{ + info: map[string]string{ + "Version": "120.7", + }, + content: testutil.MustMakeDeb([]testutil.TarEntry{ + DIR(0755, "./"), + DIR(0755, "./speed/"), + REG(0644, "./speed/cheetah", "120.7 km/h\n"), + }), + }, + }, + "birds": { + "ostrich": testPackage{ + info: map[string]string{ + "Version": "90.0", + }, + content: testutil.MustMakeDeb([]testutil.TarEntry{ + DIR(0755, "./"), + DIR(0755, "./speed/"), + REG(0644, "./speed/ostrich", "90.0 km/h\n"), + }), + }, + }, + }, + slices: []setup.SliceKey{ + {"cheetah", "speed"}, + {"ostrich", "speed"}, + }, + release: map[string]string{ + "chisel.yaml": ` + format: chisel-v1 + archives: + vertebrates: + version: 1 + suites: [main] + components: [main, universe] + mammals: + version: 1 + suites: [main] + components: [main] + birds: + version: 1 + suites: [main] + components: [main] + `, + "slices/mydir/cheetah.yaml": ` + package: cheetah + slices: + speed: + contents: + /speed/cheetah: + `, + "slices/mydir/ostrich.yaml": ` + package: ostrich + slices: + speed: + contents: + /speed/ostrich: + `, + }, + result: map[string]string{ + "/speed/": "dir 0755", + "/speed/cheetah": "file 0644 e98b0879", + "/speed/ostrich": "file 0644 c8fa2806", + }, }} const defaultChiselYaml = `