From 9d27e5c80098a36c337be40ba5febc3951e29b78 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Wed, 27 May 2026 16:06:36 +0200 Subject: [PATCH 01/16] feat: support bin packages parsing --- internal/setup/setup.go | 34 ++++- internal/setup/setup_test.go | 261 ++++++++++++++++++++++++++++++++++- internal/setup/yaml.go | 65 ++++++++- internal/slicer/slicer.go | 16 ++- 4 files changed, 363 insertions(+), 13 deletions(-) diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 6ed24abe..ab85588c 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -16,6 +16,19 @@ import ( "github.com/canonical/chisel/internal/strdist" ) +// StoreKind identifies the backend type of a store. +type StoreKind string + +const StoreBin StoreKind = "bin" + +// Store is the location from which binary packages are obtained via a store API. +type Store struct { + Name string + Kind StoreKind + Version string + DefaultPrefix string +} + // Release is a collection of package slices targeting a particular // distribution version. type Release struct { @@ -23,6 +36,7 @@ type Release struct { Path string Packages map[string]*Package Archives map[string]*Archive + Stores map[string]*Store Maintenance *Maintenance } @@ -51,10 +65,12 @@ 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 + Archive string + Store string + DefaultTrack string + Slices map[string]*Slice } // Slice holds the details about a package slice. @@ -337,6 +353,16 @@ func (r *Release) validate() error { } } + // Check that stores referenced in packages are defined. + for _, pkg := range r.Packages { + if pkg.Store == "" { + continue + } + if _, ok := r.Stores[pkg.Store]; !ok { + return fmt.Errorf("%s: package refers to undefined store %q", pkg.Path, pkg.Store) + } + } + return nil } diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index d669943f..3c579213 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -3896,6 +3896,195 @@ var setupTests = []setupTest{{ `, }, relerror: `package "mypkg" slices defined more than once: slices/dir1/mypkg.yaml and slices/dir2/mypkg.yaml`, +}, { + summary: "Store package is parsed correctly", + input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, + "slices/bin/mypkg.yaml": ` + package: mypkg + store: bin + default-track: "3.0" + `, + }, + release: &setup.Release{ + Format: "v3", + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "26.10", + Suites: []string{"stonking"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, + }, + }, + Stores: map[string]*setup.Store{ + "bin": { + Name: "bin", + Kind: setup.StoreBin, + Version: "26.10", + DefaultPrefix: "bin-", + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/bin/mypkg.yaml", + Store: "bin", + DefaultTrack: "3.0", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Store and archive are mutually exclusive", + input: map[string]string{ + "slices/bin/mypkg.yaml": ` + package: mypkg + archive: ubuntu + store: bin + default-track: "3.0" + `, + }, + relerror: `cannot parse package "mypkg": both 'store' and 'archive' fields are set`, +}, { + summary: "Store package missing default-track", + input: map[string]string{ + "slices/bin/mypkg.yaml": ` + package: mypkg + store: bin + `, + }, + relerror: `cannot parse package "mypkg": 'default-track' is required when 'store' is set`, +}, { + summary: "default-track without store", + input: map[string]string{ + "slices/bin/mypkg.yaml": ` + package: mypkg + default-track: "3.0" + `, + }, + relerror: `cannot parse package "mypkg": 'store' is required when 'default-track' is set`, +}, { + summary: "default-track must not contain /", + input: map[string]string{ + "slices/bin/mypkg.yaml": ` + package: mypkg + store: bin + default-track: "3.0/stable" + `, + }, + relerror: `cannot parse package "mypkg": 'default-track' must be a track name without /`, +}, { + summary: "Package store references undefined store", + input: map[string]string{ + "slices/bin/mypkg.yaml": ` + package: mypkg + store: no-such-store + default-track: "3.0" + `, + }, + relerror: `slices/bin/mypkg.yaml: package refers to undefined store "no-such-store"`, +}, { + summary: "Store with invalid kind", + input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + mystore: + kind: unknown-kind + version: 26.10 + default-prefix: "pfx-" + `, + }, + relerror: `chisel.yaml: store "mystore" has invalid kind "unknown-kind"`, +}, { + summary: "Store missing version", + input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + default-prefix: "bin-" + `, + }, + relerror: `chisel.yaml: store "bin" missing version field`, +}, { + summary: "Store missing default-prefix", + input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + `, + }, + relerror: `chisel.yaml: store "bin" missing default-prefix field`, }} func (s *S) TestParseRelease(c *C) { @@ -3998,9 +4187,9 @@ func runParseReleaseTests(c *C, tests []setupTest) { dir := c.MkDir() for path, data := range test.input { fpath := filepath.Join(dir, path) - err := os.MkdirAll(filepath.Dir(fpath), 0755) + err := os.MkdirAll(filepath.Dir(fpath), 0o755) c.Assert(err, IsNil) - err = os.WriteFile(fpath, testutil.Reindent(data), 0644) + err = os.WriteFile(fpath, testutil.Reindent(data), 0o644) c.Assert(err, IsNil) } @@ -4045,6 +4234,40 @@ func runParseReleaseTests(c *C, tests []setupTest) { } } +func (s *S) TestStoresNotSupportedInOldFormats(c *C) { + for _, format := range []string{"v1", "v2"} { + c.Logf("Format: %s", format) + chiselYaml := ` + format: ` + format + ` + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 22.04 + default-prefix: "bin-" + ` + dir := c.MkDir() + err := os.WriteFile(filepath.Join(dir, "chisel.yaml"), testutil.Reindent(chiselYaml), 0o644) + c.Assert(err, IsNil) + err = os.MkdirAll(filepath.Join(dir, "slices"), 0o755) + c.Assert(err, IsNil) + _, err = setup.ReadRelease(dir) + c.Assert(err, ErrorMatches, `chisel.yaml: stores is not supported in format "`+format+`"`) + } +} + func (s *S) TestPackageMarshalYAML(c *C) { for _, test := range setupTests { c.Logf("Summary: %s", test.summary) @@ -4232,6 +4455,40 @@ func (s *S) TestPackageYAMLFormat(c *C) { mypkg_three: {arch: i386} `, }, + }, { + summary: "Store package fields", + input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t\t") + ` + `, + "slices/bin/mypkg.yaml": ` + package: mypkg + store: bin + default-track: "3.0" + slices: + myslice: + contents: + /usr/bin/mypkg: {} + `, + }, }} for _, test := range tests { diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index cefe86cb..b9b6d2fd 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -35,6 +35,7 @@ type yamlRelease struct { // fields that break said compatibility (e.g. "pro" archives) and merged // together with "archives". V2Archives map[string]yamlArchive `yaml:"v2-archives"` + Stores map[string]yamlStore `yaml:"stores"` } const ( @@ -52,9 +53,17 @@ type yamlArchive struct { PubKeys []string `yaml:"public-keys"` } +type yamlStore struct { + Kind string `yaml:"kind"` + Version string `yaml:"version"` + DefaultPrefix string `yaml:"default-prefix"` +} + type yamlPackage struct { - Name string `yaml:"package"` - Archive string `yaml:"archive,omitempty"` + Name string `yaml:"package"` + Archive string `yaml:"archive,omitempty"` + Store string `yaml:"store,omitempty"` + DefaultTrack string `yaml:"default-track,omitempty"` // For backwards-compatibility reasons with v1 and v2, essential needs // custom logic to be parsed. See [yamlEssentialListMap]. Essential yamlEssentialListMap `yaml:"essential,omitempty"` @@ -433,6 +442,33 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { release.Archives[archiveName] = details } + // Parse stores. + if len(yamlVar.Stores) > 0 && (release.Format == "v1" || release.Format == "v2") { + return nil, fmt.Errorf("%s: stores is not supported in format %q", fileName, release.Format) + } + if len(yamlVar.Stores) > 0 { + release.Stores = make(map[string]*Store, len(yamlVar.Stores)) + } + for storeName, details := range yamlVar.Stores { + switch StoreKind(details.Kind) { + case StoreBin: + default: + return nil, fmt.Errorf("%s: store %q has invalid kind %q", fileName, storeName, details.Kind) + } + if details.Version == "" { + return nil, fmt.Errorf("%s: store %q missing version field", fileName, storeName) + } + if details.DefaultPrefix == "" { + return nil, fmt.Errorf("%s: store %q missing default-prefix field", fileName, storeName) + } + release.Stores[storeName] = &Store{ + Name: storeName, + Kind: StoreKind(details.Kind), + Version: details.Version, + DefaultPrefix: details.DefaultPrefix, + } + } + return release, err } @@ -480,6 +516,23 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } } + if yamlPkg.Store != "" && yamlPkg.Archive != "" { + return nil, fmt.Errorf("cannot parse package %q: both 'store' and 'archive' fields are set", pkgName) + } + if yamlPkg.Store != "" { + if yamlPkg.DefaultTrack == "" { + return nil, fmt.Errorf("cannot parse package %q: 'default-track' is required when 'store' is set", pkgName) + } + if strings.Contains(yamlPkg.DefaultTrack, "/") { + return nil, fmt.Errorf("cannot parse package %q: 'default-track' must be a track name without /", pkgName) + } + pkg.Store = yamlPkg.Store + pkg.DefaultTrack = yamlPkg.DefaultTrack + } else { + if yamlPkg.DefaultTrack != "" { + return nil, fmt.Errorf("cannot parse package %q: 'store' is required when 'default-track' is set", pkgName) + } + } pkg.Archive = yamlPkg.Archive zeroPath := yamlPath{} for sliceName, yamlSlice := range yamlPkg.Slices { @@ -690,9 +743,11 @@ func sliceToYAML(s *Slice) (*yamlSlice, error) { // packageToYAML converts a Package object to a yamlPackage object. func packageToYAML(p *Package) (*yamlPackage, error) { pkg := &yamlPackage{ - Name: p.Name, - Archive: p.Archive, - Slices: make(map[string]yamlSlice, len(p.Slices)), + Name: p.Name, + Archive: p.Archive, + Store: p.Store, + DefaultTrack: p.DefaultTrack, + Slices: make(map[string]yamlSlice, len(p.Slices)), } for name, slice := range p.Slices { yamlSlice, err := sliceToYAML(slice) diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 9d3447fb..ce54bb27 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -95,6 +95,13 @@ func Run(options *RunOptions) error { return err } + // Build a map from package name to architecture. + pkgArch := make(map[string]string) + for pkg, a := range pkgArchive { + pkgArch[pkg] = a.Options().Arch + } + // TODO Handle packages coming from a store as well when we support them. + prefers, err := options.Selection.Prefers() if err != nil { return err @@ -108,7 +115,7 @@ func Run(options *RunOptions) error { extractPackage = make(map[string][]deb.ExtractInfo) extract[slice.Package] = extractPackage } - arch := pkgArchive[slice.Package].Options().Arch + arch := pkgArch[slice.Package] for targetPath, pathInfo := range slice.Contents { if targetPath == "" { continue @@ -269,7 +276,7 @@ func Run(options *RunOptions) error { // them to the appropriate slices. relPaths := map[string][]*setup.Slice{} for _, slice := range options.Selection.Slices { - arch := pkgArchive[slice.Package].Options().Arch + arch := pkgArch[slice.Package] for relPath, pathInfo := range slice.Contents { if len(pathInfo.Arch) > 0 && !slices.Contains(pathInfo.Arch, arch) { continue @@ -512,6 +519,11 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel continue } pkg := selection.Release.Packages[s.Package] + if pkg.Store != "" { + // Packages coming from a store are not fetched from an archive, + // so we skip them here. + continue + } var candidates []*setup.Archive if pkg.Archive == "" { From 6b4654ad0dba8a182cf4ddf2ee0d9aa57f7e4b82 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Wed, 27 May 2026 16:19:07 +0200 Subject: [PATCH 02/16] fix: correct style fix Signed-off-by: Paul Mars --- internal/setup/setup_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 3c579213..8328651a 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -4187,9 +4187,9 @@ func runParseReleaseTests(c *C, tests []setupTest) { dir := c.MkDir() for path, data := range test.input { fpath := filepath.Join(dir, path) - err := os.MkdirAll(filepath.Dir(fpath), 0o755) + err := os.MkdirAll(filepath.Dir(fpath), 0755) c.Assert(err, IsNil) - err = os.WriteFile(fpath, testutil.Reindent(data), 0o644) + err = os.WriteFile(fpath, testutil.Reindent(data), 0644) c.Assert(err, IsNil) } From c9e66c56280e95a8cba9cc85d47ba27656a9f608 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Wed, 27 May 2026 16:21:10 +0200 Subject: [PATCH 03/16] fix: lint Signed-off-by: Paul Mars --- internal/slicer/slicer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index ce54bb27..86562b8b 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -101,7 +101,7 @@ func Run(options *RunOptions) error { pkgArch[pkg] = a.Options().Arch } // TODO Handle packages coming from a store as well when we support them. - + prefers, err := options.Selection.Prefers() if err != nil { return err From a5ca31239c3da7072996ee5714748bfd8d95616d Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Thu, 28 May 2026 08:31:02 +0200 Subject: [PATCH 04/16] ci: rerun From 48b74d8b659f611ea8dea7cb4655cf4012ea268b Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Fri, 29 May 2026 15:30:47 +0200 Subject: [PATCH 05/16] fix: fully qualified slice names Co-authored-by: Copilot Signed-off-by: Paul Mars --- cmd/chisel/cmd_info.go | 2 +- internal/apacheutil/util.go | 22 +++- internal/apacheutil/util_test.go | 52 +++++++++ internal/setup/setup.go | 110 +++++++++++++------ internal/setup/setup_test.go | 175 +++++++++++++++++++++++++------ internal/setup/yaml.go | 8 +- internal/slicer/slicer.go | 36 ++++--- internal/slicer/slicer_test.go | 160 ++++++++++++++-------------- 8 files changed, 395 insertions(+), 170 deletions(-) diff --git a/cmd/chisel/cmd_info.go b/cmd/chisel/cmd_info.go index fa5485c6..228d8f1b 100644 --- a/cmd/chisel/cmd_info.go +++ b/cmd/chisel/cmd_info.go @@ -83,7 +83,7 @@ func selectPackageSlices(release *setup.Release, queries []string) (packages []* allPkgSlices := make(map[string]bool) sliceExists := func(key setup.SliceKey) bool { - pkg, ok := release.Packages[key.Package] + pkg, ok := release.Packages[key.MapKey()] if !ok { return false } diff --git a/internal/apacheutil/util.go b/internal/apacheutil/util.go index 7e0f8e6d..2ad9a364 100644 --- a/internal/apacheutil/util.go +++ b/internal/apacheutil/util.go @@ -9,10 +9,24 @@ import ( type SliceKey struct { Package string + Kind string Slice string } -func (s SliceKey) String() string { return s.Package + "_" + s.Slice } +func (s SliceKey) String() string { + if s.Kind != "" { + return s.Kind + "/" + s.Package + "_" + s.Slice + } + return s.Package + "_" + s.Slice +} + +// MapKey returns the qualified package key used for Release.Packages lookups. +func (s SliceKey) MapKey() string { + if s.Kind != "" { + return s.Kind + "/" + s.Package + } + return s.Package +} // FnameExp matches the slice definition file basename. var FnameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})\.yaml$`) @@ -20,13 +34,13 @@ var FnameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})\.yaml$`) // SnameExp matches only the slice name, without the leading package name. var SnameExp = regexp.MustCompile(`^([a-z](?:-?[a-z0-9]){2,})$`) -// knameExp matches the slice full name in pkg_slice format. -var knameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})_([a-z](?:-?[a-z0-9]){2,})$`) +// knameExp matches the slice full name in pkg_slice or kind/pkg_slice format. +var knameExp = regexp.MustCompile(`^(?:([a-z0-9](?:-?[.a-z0-9+]){0,})/)?([a-z0-9](?:-?[.a-z0-9+]){1,})_([a-z](?:-?[a-z0-9]){2,})$`) func ParseSliceKey(sliceKey string) (SliceKey, error) { match := knameExp.FindStringSubmatch(sliceKey) if match == nil { return SliceKey{}, fmt.Errorf("invalid slice reference: %q", sliceKey) } - return SliceKey{match[1], match[2]}, nil + return SliceKey{Package: match[2], Kind: match[1], Slice: match[3]}, nil } diff --git a/internal/apacheutil/util_test.go b/internal/apacheutil/util_test.go index 6289473c..752af2eb 100644 --- a/internal/apacheutil/util_test.go +++ b/internal/apacheutil/util_test.go @@ -78,6 +78,15 @@ var sliceKeyTests = []struct { }, { input: "..._bar", err: `invalid slice reference: "\.\.\._bar"`, +}, { + input: "bin/curl_bins", + expected: apacheutil.SliceKey{Package: "curl", Kind: "bin", Slice: "bins"}, +}, { + input: "bin/g++_bins", + expected: apacheutil.SliceKey{Package: "g++", Kind: "bin", Slice: "bins"}, +}, { + input: "b/curl_bins", + expected: apacheutil.SliceKey{Package: "curl", Kind: "b", Slice: "bins"}, }, { input: "white space_no-whitespace", err: `invalid slice reference: "white space_no-whitespace"`, @@ -94,3 +103,46 @@ func (s *S) TestParseSliceKey(c *C) { c.Assert(key, DeepEquals, test.expected) } } + +var sliceKeyStringTests = []struct { + key apacheutil.SliceKey + expected string +}{{ + key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, + expected: "curl_bins", +}, { + key: apacheutil.SliceKey{Package: "curl", Kind: "bin", Slice: "bins"}, + expected: "bin/curl_bins", +}, { + key: apacheutil.SliceKey{Package: "g++", Kind: "bin", Slice: "bins"}, + expected: "bin/g++_bins", +}} + +func (s *S) TestSliceKeyString(c *C) { + for _, test := range sliceKeyStringTests { + c.Assert(test.key.String(), Equals, test.expected) + } +} + +var sliceKeyMapKeyTests = []struct { + key apacheutil.SliceKey + expected string +}{{ + key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, + expected: "curl", +}, { + key: apacheutil.SliceKey{Package: "curl", Kind: "bin", Slice: "bins"}, + expected: "bin/curl", +}, { + key: apacheutil.SliceKey{Package: "curl", Kind: "bin"}, + expected: "bin/curl", +}, { + key: apacheutil.SliceKey{Package: "curl"}, + expected: "curl", +}} + +func (s *S) TestSliceKeyMapKey(c *C) { + for _, test := range sliceKeyMapKeyTests { + c.Assert(test.key.MapKey(), Equals, test.expected) + } +} diff --git a/internal/setup/setup.go b/internal/setup/setup.go index ab85588c..dd649b42 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -76,6 +76,7 @@ type Package struct { // Slice holds the details about a package slice. type Slice struct { Package string + Kind string Name string Hint string Essential map[SliceKey]EssentialInfo @@ -149,7 +150,34 @@ func ParseSliceKey(sliceKey string) (SliceKey, error) { return apacheutil.ParseSliceKey(sliceKey) } -func (s *Slice) String() string { return s.Package + "_" + s.Name } +// pkgKind returns the Kind value for a package based on its store reference. +func pkgKind(release *Release, pkg *Package) string { + if pkg.Store == "" { + return "" + } + store := release.Stores[pkg.Store] + if store == nil { + return "" + } + return string(store.Kind) +} + +// pkgMapKey returns the qualified key for a package used as the +// Release.Packages map key. +func pkgMapKey(name, kind string) string { + if kind != "" { + return kind + "/" + name + } + return name +} + +func (s *Slice) String() string { + return SliceKey{Package: s.Package, Kind: s.Kind, Slice: s.Name}.String() +} + +func (s *Slice) MapKey() string { + return SliceKey{Package: s.Package, Kind: s.Kind}.MapKey() +} // Selection holds the required configuration to create a Build for a selection // of slices from a Release. It's still an abstract proposal in the sense that @@ -176,16 +204,18 @@ func (s *Selection) Prefers() (map[string]*Package, error) { if !hasPrefers { continue } + sliceKey := pkgMapKey(slice.Package, slice.Kind) old, ok := pathPreferredPkg[path] if !ok { - pathPreferredPkg[path] = s.Release.Packages[slice.Package] + pathPreferredPkg[path] = s.Release.Packages[sliceKey] continue } - if old.Name == slice.Package { + oldKey := pkgMapKey(old.Name, pkgKind(s.Release, old)) + if oldKey == sliceKey { // Skip if the package was already recorded. continue } - preferred, err := preferredPathPackage(path, old.Name, slice.Package, prefers) + preferred, err := preferredPathPackage(path, oldKey, sliceKey, prefers) if err != nil { // Note: we have checked above that the path has prefers and // they are different packages so the error cannot be @@ -238,13 +268,16 @@ func (r *Release) validate() error { // cannot validate that they are the same without downloading the package. paths := make(map[string][]*Slice) for _, pkg := range r.Packages { + kind := pkgKind(r, pkg) for _, new := range pkg.Slices { - keys = append(keys, SliceKey{pkg.Name, new.Name}) + keys = append(keys, SliceKey{Package: pkg.Name, Kind: kind, Slice: new.Name}) + newKey := pkgMapKey(new.Package, new.Kind) for newPath, newInfo := range new.Contents { if oldSlices, ok := paths[newPath]; ok { for _, old := range oldSlices { - if new.Package != old.Package { - _, err := preferredPathPackage(newPath, new.Package, old.Package, prefers) + oldKey := pkgMapKey(old.Package, old.Kind) + if newKey != oldKey { + _, err := preferredPathPackage(newPath, newKey, oldKey, prefers) if err == nil { continue } else if err != preferNone { @@ -253,8 +286,8 @@ func (r *Release) validate() error { } oldInfo := old.Contents[newPath] - if !newInfo.SameContent(&oldInfo) || (newInfo.Kind == CopyPath || newInfo.Kind == GlobPath) && new.Package != old.Package { - if old.Package > new.Package || old.Package == new.Package && old.Name > new.Name { + if !newInfo.SameContent(&oldInfo) || (newInfo.Kind == CopyPath || newInfo.Kind == GlobPath) && newKey != oldKey { + if oldKey > newKey || oldKey == newKey && old.Name > new.Name { old, new = new, old } return fmt.Errorf("slices %s and %s conflict on %s", old, new, newPath) @@ -277,7 +310,7 @@ func (r *Release) validate() error { found := false for _, slice := range paths[skey.path] { - if slice.Package == skey.pkg { + if pkgMapKey(slice.Package, slice.Kind) == skey.pkg { found = true break } @@ -302,14 +335,16 @@ func (r *Release) validate() error { } for _, new := range newSlices { newInfo := new.Contents[newPath] + newKey := pkgMapKey(new.Package, new.Kind) + oldKey := pkgMapKey(old.Package, old.Kind) if oldInfo.Kind == GlobPath && (newInfo.Kind == GlobPath || newInfo.Kind == CopyPath) { - if new.Package == old.Package { + if newKey == oldKey { continue } } if strdist.GlobPath(newPath, oldPath) { - if (old.Package > new.Package) || (old.Package == new.Package && old.Name > new.Name) || - (old.Package == new.Package && old.Name == new.Name && oldPath > newPath) { + if (oldKey > newKey) || (oldKey == newKey && old.Name > new.Name) || + (oldKey == newKey && old.Name == new.Name && oldPath > newPath) { old, new = new, old oldPath, newPath = newPath, oldPath } @@ -372,10 +407,9 @@ func (r *Release) validate() error { // If arch is supplied, essential(s) not specific to that arch are not // considered. func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, error) { - // Preprocess the list to improve error messages. for _, key := range keys { - if pkg, ok := pkgs[key.Package]; !ok { + if pkg, ok := pkgs[key.MapKey()]; !ok { return nil, fmt.Errorf("slices of package %q not found", key.Package) } else if _, ok := pkg.Slices[key.Slice]; !ok { return nil, fmt.Errorf("slice %s not found", key) @@ -393,7 +427,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } seen[key] = true - pkg := pkgs[key.Package] + pkg := pkgs[key.MapKey()] slice := pkg.Slices[key.Slice] fqslice := slice.String() predecessors := successors[fqslice] @@ -402,7 +436,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } fqreq := req.String() - if reqpkg, ok := pkgs[req.Package]; !ok || reqpkg.Slices[req.Slice] == nil { + if reqpkg, ok := pkgs[req.MapKey()]; !ok || reqpkg.Slices[req.Slice] == nil { return nil, fmt.Errorf("%s requires %s, but slice is missing", fqslice, fqreq) } predecessors = append(predecessors, fqreq) @@ -417,9 +451,11 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, if len(names) > 1 { return nil, fmt.Errorf("essential loop detected: %s", strings.Join(names, ", ")) } - name := names[0] - dot := strings.IndexByte(name, '_') - order = append(order, SliceKey{name[:dot], name[dot+1:]}) + key, err := ParseSliceKey(names[0]) + if err != nil { + return nil, fmt.Errorf("internal error: cannot parse slice key %q", names[0]) + } + order = append(order, key) } return order, nil @@ -467,9 +503,6 @@ func readSlices(release *Release, baseDir, dirName string) error { pkgName := match[1] pkgPath := filepath.Join(dirName, entry.Name()) - if pkg, ok := release.Packages[pkgName]; ok { - return fmt.Errorf("package %q slices defined more than once: %s and %s", pkgName, pkg.Path, stripBase(baseDir, pkgPath)) - } data, err := os.ReadFile(pkgPath) if err != nil { // Errors from package os generally include the path. @@ -481,7 +514,20 @@ func readSlices(release *Release, baseDir, dirName string) error { return err } - release.Packages[pkg.Name] = pkg + // Derive the package Kind from its store reference. + kind := pkgKind(release, pkg) + + // Set Kind on all slices in the package. + for _, slice := range pkg.Slices { + slice.Kind = kind + } + + // Use the qualified key for the Packages map. + mapKey := pkgMapKey(pkg.Name, kind) + if existing, ok := release.Packages[mapKey]; ok { + return fmt.Errorf("package %q slices defined more than once: %s and %s", pkgName, existing.Path, stripBase(baseDir, pkgPath)) + } + release.Packages[mapKey] = pkg } return nil } @@ -514,7 +560,7 @@ func Select(release *Release, slices []SliceKey, arch string) (*Selection, error } selection.Slices = make([]*Slice, len(sorted)) for i, key := range sorted { - selection.Slices[i] = release.Packages[key.Package].Slices[key.Slice] + selection.Slices[i] = release.Packages[key.MapKey()].Slices[key.Slice] } for _, new := range selection.Slices { @@ -546,32 +592,32 @@ type preferKey struct { func (r *Release) prefers() (map[preferKey]string, error) { prefers := make(map[preferKey]string) - for _, pkg := range r.Packages { + for mapKey, pkg := range r.Packages { for _, slice := range pkg.Slices { for path, info := range slice.Contents { if info.Prefer != "" { if _, ok := r.Packages[info.Prefer]; !ok { return nil, fmt.Errorf("slice %s path %s 'prefer' refers to undefined package %q", slice, path, info.Prefer) } - tkey := preferKey{preferTarget, path, pkg.Name} + tkey := preferKey{preferTarget, path, mapKey} skey := preferKey{preferSource, path, info.Prefer} if target, ok := prefers[tkey]; ok { if target != info.Prefer { pkg1, pkg2 := sortPair(target, info.Prefer) return nil, fmt.Errorf("package %q has conflicting prefers for %s: %s != %s", - pkg.Name, path, pkg1, pkg2) + mapKey, path, pkg1, pkg2) } } else if source, ok := prefers[skey]; ok { - if source != pkg.Name { - pkg1, pkg2 := sortPair(source, pkg.Name) + if source != mapKey { + pkg1, pkg2 := sortPair(source, mapKey) return nil, fmt.Errorf("packages %q and %q cannot both prefer %q for %s", pkg1, pkg2, info.Prefer, path) } } else { prefers[tkey] = info.Prefer - prefers[skey] = pkg.Name + prefers[skey] = mapKey // Sample package that requires this path to be in a prefer relationship. - prefers[preferKey{preferSource, path, ""}] = pkg.Name + prefers[preferKey{preferSource, path, ""}] = mapKey } } } diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 8328651a..a3b48b87 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -150,7 +150,7 @@ var setupTests = []setupTest{{ "/file/path2": {Kind: "copy", Info: "/other/path"}, "/file/path3": {Kind: "symlink", Info: "/other/path"}, "/file/path4": {Kind: "text", Info: "content", Until: "mutate"}, - "/file/path5": {Kind: "copy", Mode: 0755, Mutable: true}, + "/file/path5": {Kind: "copy", Mode: 0o755, Mutable: true}, "/file/path6/": {Kind: "dir"}, }, }, @@ -158,7 +158,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "myslice1"}: {}, + {Package: "mypkg", Slice: "myslice1"}: {}, }, Contents: map[string]setup.PathInfo{ "/another/path": {Kind: "copy"}, @@ -421,7 +421,7 @@ var setupTests = []setupTest{{ myslice2: {essential: [mypkg1_myslice1]} `, }, - selslices: []setup.SliceKey{{"mypkg1", "myslice1"}}, + selslices: []setup.SliceKey{{Package: "mypkg1", Slice: "myslice1"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg1", @@ -444,7 +444,7 @@ var setupTests = []setupTest{{ myslice2: {essential: [mypkg1_myslice1]} `, }, - selslices: []setup.SliceKey{{"mypkg2", "myslice2"}}, + selslices: []setup.SliceKey{{Package: "mypkg2", Slice: "myslice2"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg1", @@ -453,7 +453,7 @@ var setupTests = []setupTest{{ Package: "mypkg2", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg1", "myslice1"}: {}, + {Package: "mypkg1", Slice: "myslice1"}: {}, }, }}, }, @@ -483,7 +483,7 @@ var setupTests = []setupTest{{ /path3: {symlink: /link} `, }, - selslices: []setup.SliceKey{{"mypkg1", "myslice1"}, {"mypkg1", "myslice2"}, {"mypkg2", "myslice1"}}, + selslices: []setup.SliceKey{{Package: "mypkg1", Slice: "myslice1"}, {Package: "mypkg1", Slice: "myslice2"}, {Package: "mypkg2", Slice: "myslice1"}}, }, { summary: "Conflicting paths across slices", input: map[string]string{ @@ -1472,7 +1472,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "slice2"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, }, }, "slice2": { @@ -1483,16 +1483,16 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice3", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "slice2"}: {}, - {"mypkg", "slice1"}: {}, - {"mypkg", "slice4"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, + {Package: "mypkg", Slice: "slice1"}: {}, + {Package: "mypkg", Slice: "slice4"}: {}, }, }, "slice4": { Package: "mypkg", Name: "slice4", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "slice2"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, }, }, }, @@ -1545,16 +1545,16 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"myotherpkg", "slice2"}: {}, - {"mypkg", "slice2"}: {}, - {"myotherpkg", "slice1"}: {}, + {Package: "myotherpkg", Slice: "slice2"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, + {Package: "myotherpkg", Slice: "slice1"}: {}, }, }, "slice2": { Package: "mypkg", Name: "slice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"myotherpkg", "slice2"}: {}, + {Package: "myotherpkg", Slice: "slice2"}: {}, }, }, }, @@ -1739,7 +1739,7 @@ var setupTests = []setupTest{{ EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), }, }, - selslices: []setup.SliceKey{{"mypkg", "myslice"}}, + selslices: []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg", @@ -1792,7 +1792,7 @@ var setupTests = []setupTest{{ EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), }, }, - selslices: []setup.SliceKey{{"mypkg", "myslice"}}, + selslices: []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}}, selerror: `slice mypkg_myslice has invalid 'generate' for path /dir/\*\*: "foo"`, }, { summary: "Paths with generate: manifest must have trailing /**", @@ -2407,10 +2407,10 @@ var setupTests = []setupTest{{ }, { summary: "Path conflicts with 'prefer'", selslices: []setup.SliceKey{ - {"mypkg1", "myslice1"}, - {"mypkg1", "myslice2"}, - {"mypkg2", "myslice1"}, - {"mypkg3", "myslice1"}, + {Package: "mypkg1", Slice: "myslice1"}, + {Package: "mypkg1", Slice: "myslice2"}, + {Package: "mypkg2", Slice: "myslice1"}, + {Package: "mypkg3", Slice: "myslice1"}, }, input: map[string]string{ "slices/mydir/mypkg1.yaml": ` @@ -2514,9 +2514,9 @@ var setupTests = []setupTest{{ }, { summary: "Path conflicts with 'prefer' depends on selection", selslices: []setup.SliceKey{ - {"mypkg1", "myslice1"}, - {"mypkg1", "myslice2"}, - {"mypkg2", "myslice1"}, + {Package: "mypkg1", Slice: "myslice1"}, + {Package: "mypkg1", Slice: "myslice2"}, + {Package: "mypkg2", Slice: "myslice1"}, }, input: map[string]string{ "slices/mydir/mypkg1.yaml": ` @@ -3664,24 +3664,24 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "myslice2"}: {Arch: []string{"amd64"}}, - {"mypkg", "myslice3"}: {Arch: []string{"amd64", "arm64"}}, - {"mypkg", "myslice4"}: {Arch: []string{"amd64", "i386"}}, - {"mypkg", "myslice5"}: {Arch: nil}, + {Package: "mypkg", Slice: "myslice2"}: {Arch: []string{"amd64"}}, + {Package: "mypkg", Slice: "myslice3"}: {Arch: []string{"amd64", "arm64"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice5"}: {Arch: nil}, }, }, "myslice2": { Package: "mypkg", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, "myslice3": { Package: "mypkg", Name: "myslice3", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, "myslice4": { @@ -3693,7 +3693,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice5", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {"mypkg", "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, }, @@ -3947,7 +3947,7 @@ var setupTests = []setupTest{{ }, }, Packages: map[string]*setup.Package{ - "mypkg": { + "bin/mypkg": { Name: "mypkg", Path: "slices/bin/mypkg.yaml", Store: "bin", @@ -4085,6 +4085,115 @@ var setupTests = []setupTest{{ `, }, relerror: `chisel.yaml: store "bin" missing default-prefix field`, +}, { + summary: "Same-named package in archive and store", + input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, + "slices/curl.yaml": ` + package: curl + slices: + libs: + contents: + /usr/lib/libcurl.so: + bins: + contents: + /usr/bin/curl: + `, + "slices/bin/curl.yaml": ` + package: curl + store: bin + default-track: "3.0" + slices: + bins: + contents: + /usr/bin/curl-bin: + `, + }, + release: &setup.Release{ + Format: "v3", + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "26.10", + Suites: []string{"stonking"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, + }, + }, + Stores: map[string]*setup.Store{ + "bin": { + Name: "bin", + Kind: setup.StoreBin, + Version: "26.10", + DefaultPrefix: "bin-", + }, + }, + Packages: map[string]*setup.Package{ + "curl": { + Name: "curl", + Path: "slices/curl.yaml", + Slices: map[string]*setup.Slice{ + "libs": { + Package: "curl", + Kind: "", + Name: "libs", + Contents: map[string]setup.PathInfo{ + "/usr/lib/libcurl.so": {Kind: setup.CopyPath}, + }, + }, + "bins": { + Package: "curl", + Kind: "", + Name: "bins", + Contents: map[string]setup.PathInfo{ + "/usr/bin/curl": {Kind: setup.CopyPath}, + }, + }, + }, + }, + "bin/curl": { + Name: "curl", + Path: "slices/bin/curl.yaml", + Store: "bin", + DefaultTrack: "3.0", + Slices: map[string]*setup.Slice{ + "bins": { + Package: "curl", + Kind: "bin", + Name: "bins", + Contents: map[string]setup.PathInfo{ + "/usr/bin/curl-bin": {Kind: setup.CopyPath}, + }, + }, + }, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, }} func (s *S) TestParseRelease(c *C) { @@ -4589,7 +4698,7 @@ func (s *S) TestSelectEmptyArch(c *C) { release, err := setup.ReadRelease(dir) c.Assert(err, IsNil) - selslice := []setup.SliceKey{{"mypkg", "myslice"}} + selslice := []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}} selection, err := setup.Select(release, selslice, "") c.Assert(err, IsNil) diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index b9b6d2fd..36335b19 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -496,7 +496,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != listEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{pkgName, sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{Package: pkgName, Slice: sliceName}) } } } else { @@ -508,10 +508,10 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.V3Essential != nil { - return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{pkgName, sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkgName, Slice: sliceName}) } if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{pkgName, sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkgName, Slice: sliceName}) } } } @@ -544,7 +544,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error return !unicode.IsPrint(r) }) if len(yamlSlice.Hint) > 40 || hintNotPrintable { - return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{pkgName, sliceName}, yamlSlice.Hint) + return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkgName, Slice: sliceName}, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 86562b8b..8fefa4b5 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -95,10 +95,10 @@ func Run(options *RunOptions) error { return err } - // Build a map from package name to architecture. + // Build a map from package map key to architecture. pkgArch := make(map[string]string) - for pkg, a := range pkgArchive { - pkgArch[pkg] = a.Options().Arch + for pkgKey, a := range pkgArchive { + pkgArch[pkgKey] = a.Options().Arch } // TODO Handle packages coming from a store as well when we support them. @@ -110,12 +110,13 @@ func Run(options *RunOptions) error { // Build information to process the selection. extract := make(map[string]map[string][]deb.ExtractInfo) for _, slice := range options.Selection.Slices { - extractPackage := extract[slice.Package] + sliceKey := slice.MapKey() + extractPackage := extract[sliceKey] if extractPackage == nil { extractPackage = make(map[string][]deb.ExtractInfo) - extract[slice.Package] = extractPackage + extract[sliceKey] = extractPackage } - arch := pkgArch[slice.Package] + arch := pkgArch[sliceKey] for targetPath, pathInfo := range slice.Contents { if targetPath == "" { continue @@ -156,15 +157,16 @@ func Run(options *RunOptions) error { packages := make(map[string]io.ReadSeekCloser) var pkgInfos []*archive.PackageInfo for _, slice := range options.Selection.Slices { - if packages[slice.Package] != nil { + sliceKey := slice.MapKey() + if packages[sliceKey] != nil { continue } - reader, info, err := pkgArchive[slice.Package].Fetch(slice.Package) + reader, info, err := pkgArchive[sliceKey].Fetch(slice.Package) if err != nil { return err } defer reader.Close() - packages[slice.Package] = reader + packages[sliceKey] = reader pkgInfos = append(pkgInfos, info) } @@ -241,18 +243,19 @@ func Run(options *RunOptions) error { // Extract all packages, also using the selection order. for _, slice := range options.Selection.Slices { - reader := packages[slice.Package] + sliceKey := slice.MapKey() + reader := packages[sliceKey] if reader == nil { continue } err := deb.Extract(reader, &deb.ExtractOptions{ Package: slice.Package, - Extract: extract[slice.Package], + Extract: extract[sliceKey], TargetDir: targetDir, Create: create, }) reader.Close() - packages[slice.Package] = nil + packages[sliceKey] = nil if err != nil { return err } @@ -276,7 +279,7 @@ func Run(options *RunOptions) error { // them to the appropriate slices. relPaths := map[string][]*setup.Slice{} for _, slice := range options.Selection.Slices { - arch := pkgArch[slice.Package] + arch := pkgArch[slice.MapKey()] for relPath, pathInfo := range slice.Contents { if len(pathInfo.Arch) > 0 && !slices.Contains(pathInfo.Arch, arch) { continue @@ -515,10 +518,11 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel pkgArchive := make(map[string]archive.Archive) for _, s := range selection.Slices { - if _, ok := pkgArchive[s.Package]; ok { + sliceKey := s.MapKey() + if _, ok := pkgArchive[sliceKey]; ok { continue } - pkg := selection.Release.Packages[s.Package] + pkg := selection.Release.Packages[sliceKey] if pkg.Store != "" { // Packages coming from a store are not fetched from an archive, // so we skip them here. @@ -545,7 +549,7 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel if chosen == nil { return nil, fmt.Errorf("cannot find package %q in archive(s)", pkg.Name) } - pkgArchive[pkg.Name] = chosen + pkgArchive[sliceKey] = chosen } return pkgArchive, nil } diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index 8d3cf775..8935014f 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -78,7 +78,7 @@ var testPackageCopyrightEntries = []testutil.TarEntry{ var slicerTests = []slicerTest{{ summary: "Basic slicing", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -111,7 +111,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Glob extraction", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -133,7 +133,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new file under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -153,7 +153,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new nested file under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -174,7 +174,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new directory under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -194,7 +194,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new file using glob and preserve parent directory permissions", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -218,7 +218,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Conditional architecture", arch: "amd64", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -249,7 +249,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Copyright is not installed implicitly", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", // Add the copyright entries to the package. @@ -274,8 +274,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages", slices: []setup.SliceKey{ - {"test-package", "myslice"}, - {"other-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}, + {Package: "other-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.PackageData["test-package"], @@ -317,9 +317,9 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages, explicit path has preference over implicit parent", slices: []setup.SliceKey{ - {"a-implicit-parent", "myslice"}, - {"b-explicit-dir", "myslice"}, - {"c-implicit-parent", "myslice"}}, + {Package: "a-implicit-parent", Slice: "myslice"}, + {Package: "b-explicit-dir", Slice: "myslice"}, + {Package: "c-implicit-parent", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "a-implicit-parent", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -376,8 +376,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Valid same file in two slices in different packages", slices: []setup.SliceKey{ - {"test-package", "myslice"}, - {"other-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}, + {Package: "other-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.PackageData["test-package"], @@ -409,7 +409,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: write a file", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -430,7 +430,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: read a file", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -456,7 +456,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: use 'until' to remove file after mutate", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -480,7 +480,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: use 'until' to remove wildcard after mutate", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -498,7 +498,7 @@ var slicerTests = []slicerTest{{ manifestPaths: map[string]string{}, }, { summary: "Script: 'until' does not remove non-empty directories", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -519,7 +519,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: writing same contents to existing file does not set the final hash in report", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -540,7 +540,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: cannot write non-mutable files", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -555,7 +555,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/text-file`, }, { summary: "Script: cannot write to unlisted file", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -569,7 +569,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/text-file`, }, { summary: "Script: cannot write to directory", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -584,7 +584,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/`, }, { summary: "Script: cannot read unlisted content", - slices: []setup.SliceKey{{"test-package", "myslice2"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice2"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -600,7 +600,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice2: cannot read file which is not selected: /dir/text-file`, }, { summary: "Script: can read globbed content", - slices: []setup.SliceKey{{"test-package", "myslice1"}, {"test-package", "myslice2"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice1"}, {Package: "test-package", Slice: "myslice2"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -615,7 +615,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Relative content root directory must not error", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -636,7 +636,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Can list parent directories of normal paths", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -655,7 +655,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot list unselected directory", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -670,7 +670,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot list directory which is not selected: /a/d/`, }, { summary: "Cannot list file path as a directory", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -685,7 +685,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: content is not a directory: /a/b/c`, }, { summary: "Can list parent directories of globs", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -699,7 +699,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot list directories not matched by glob", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -714,7 +714,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot list directory which is not selected: /other-dir/`, }, { summary: "Duplicate copyright symlink is ignored", - slices: []setup.SliceKey{{"copyright-symlink-openssl", "bins"}}, + slices: []setup.SliceKey{{Package: "copyright-symlink-openssl", Slice: "bins"}}, pkgs: []*testutil.TestPackage{{ Name: "copyright-symlink-openssl", Data: testutil.MustMakeDeb(packageEntries["copyright-symlink-openssl"]), @@ -746,7 +746,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Can list unclean directory paths", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -765,7 +765,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot read directories", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -780,7 +780,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: content is not a file: /x/y`, }, { summary: "Multiple archives with priority", - slices: []setup.SliceKey{{"test-package", "myslice"}, {"other-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}, {Package: "other-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", @@ -864,7 +864,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Pinned archive bypasses higher priority", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", @@ -932,7 +932,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Pinned archive does not have the package", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -978,7 +978,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "No archives have the package", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{}, release: map[string]string{ "chisel.yaml": ` @@ -1015,7 +1015,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "Negative priority archives are ignored when not explicitly pinned in package", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1052,7 +1052,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "Negative priority archive explicitly pinned in package", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", @@ -1102,8 +1102,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Multiple slices of same package", slices: []setup.SliceKey{ - {"test-package", "myslice1"}, - {"test-package", "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1140,8 +1140,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Same glob in several entries with until:mutate and reading from script", slices: []setup.SliceKey{ - {"test-package", "myslice1"}, - {"test-package", "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1186,8 +1186,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping globs, until:mutate and reading from script", slices: []setup.SliceKey{ - {"test-package", "myslice2"}, - {"test-package", "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1232,8 +1232,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on entry and reading from script", slices: []setup.SliceKey{ - {"test-package", "myslice1"}, - {"test-package", "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1278,8 +1278,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on glob and reading from script", slices: []setup.SliceKey{ - {"test-package", "myslice1"}, - {"test-package", "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1307,8 +1307,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on both and reading from script", slices: []setup.SliceKey{ - {"test-package", "myslice1"}, - {"test-package", "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1331,8 +1331,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Content not created in packages with until:mutate on one and reading from script", slices: []setup.SliceKey{ - {"test-package", "myslice1"}, - {"test-package", "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1355,8 +1355,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages, both are recorded", slices: []setup.SliceKey{ - {"test-package", "myslice"}, - {"other-package", "myslice"}, + {Package: "test-package", Slice: "myslice"}, + {Package: "other-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1392,7 +1392,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Two packages, only one is selected and recorded", slices: []setup.SliceKey{ - {"test-package", "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1426,7 +1426,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Relative paths are properly trimmed during extraction", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1457,7 +1457,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Producing a manifest is not mandatory", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, hackopt: func(c *C, opts *slicer.RunOptions) { // Remove the manifest slice that the tests add automatically. var index int @@ -1479,7 +1479,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "No valid archives defined due to invalid pro value", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "chisel.yaml": ` format: v1 @@ -1506,8 +1506,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Valid hard link in two slices in the same package", slices: []setup.SliceKey{ - {"test-package", "slice1"}, - {"test-package", "slice2"}}, + {Package: "test-package", Slice: "slice1"}, + {Package: "test-package", Slice: "slice2"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1540,7 +1540,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link entries can be extracted without extracting the regular file", slices: []setup.SliceKey{ - {"test-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1570,7 +1570,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link identifier for different groups", slices: []setup.SliceKey{ - {"test-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1605,7 +1605,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Single hard link entry can be extracted without regular file and no hard links are created", slices: []setup.SliceKey{ - {"test-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1632,7 +1632,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link to symlink does not follow symlink", slices: []setup.SliceKey{ - {"test-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1664,8 +1664,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link identifiers are unique across packages", slices: []setup.SliceKey{ - {"test-package1", "myslice"}, - {"test-package2", "myslice"}, + {Package: "test-package1", Slice: "myslice"}, + {Package: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", @@ -1715,7 +1715,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Mutations for hard links are forbidden", slices: []setup.SliceKey{ - {"test-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1740,7 +1740,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard links can be marked as mutable, but not mutated", slices: []setup.SliceKey{ - {"test-package", "myslice"}}, + {Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1769,7 +1769,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Hard links cannot escape the target directory", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1789,7 +1789,7 @@ var slicerTests = []slicerTest{{ error: `cannot extract from package "test-package": invalid link target /etc/group`, }, { summary: "Cannot extract outside of target directory", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1810,8 +1810,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Extract conflicting paths with prefer from proper package", slices: []setup.SliceKey{ - {"test-package1", "myslice"}, - {"test-package2", "myslice"}, + {Package: "test-package1", Slice: "myslice"}, + {Package: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", @@ -1871,8 +1871,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Warning when implicit parent directories conflict", slices: []setup.SliceKey{ - {"test-package1", "myslice"}, - {"test-package2", "myslice"}, + {Package: "test-package1", Slice: "myslice"}, + {Package: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", @@ -1910,7 +1910,7 @@ var slicerTests = []slicerTest{{ logOutput: `(?s).*Warning: Path "/parent/" has diverging modes in different packages\. Please report\..*`, }, { summary: "Arch specific slice is not installed when it does not match requested arch", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, arch: "amd64", release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1929,7 +1929,7 @@ var slicerTests = []slicerTest{{ manifestPaths: map[string]string{}, }, { summary: "Arch specific slice is installed when it matches requested arch", - slices: []setup.SliceKey{{"test-package", "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, arch: "arm64", release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1953,7 +1953,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Transitive essential", - slices: []setup.SliceKey{{"test-package", "first"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "first"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package From d95f603e4d922a7a7ca1ea4338d11d84f90214ed Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Mon, 1 Jun 2026 16:26:29 +0200 Subject: [PATCH 06/16] style: rename to avoid confusion Signed-off-by: Paul Mars --- cmd/chisel/cmd_info.go | 2 +- internal/apacheutil/util.go | 4 +-- internal/apacheutil/util_test.go | 8 +++--- internal/setup/setup.go | 42 ++++++++++++++++---------------- internal/slicer/slicer.go | 34 +++++++++++++------------- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/cmd/chisel/cmd_info.go b/cmd/chisel/cmd_info.go index 228d8f1b..534dc6df 100644 --- a/cmd/chisel/cmd_info.go +++ b/cmd/chisel/cmd_info.go @@ -83,7 +83,7 @@ func selectPackageSlices(release *setup.Release, queries []string) (packages []* allPkgSlices := make(map[string]bool) sliceExists := func(key setup.SliceKey) bool { - pkg, ok := release.Packages[key.MapKey()] + pkg, ok := release.Packages[key.PkgKey()] if !ok { return false } diff --git a/internal/apacheutil/util.go b/internal/apacheutil/util.go index 2ad9a364..37e1e4e4 100644 --- a/internal/apacheutil/util.go +++ b/internal/apacheutil/util.go @@ -20,8 +20,8 @@ func (s SliceKey) String() string { return s.Package + "_" + s.Slice } -// MapKey returns the qualified package key used for Release.Packages lookups. -func (s SliceKey) MapKey() string { +// PkgKey returns the qualified package key used for Release.Packages lookups. +func (s SliceKey) PkgKey() string { if s.Kind != "" { return s.Kind + "/" + s.Package } diff --git a/internal/apacheutil/util_test.go b/internal/apacheutil/util_test.go index 752af2eb..db4ef7cb 100644 --- a/internal/apacheutil/util_test.go +++ b/internal/apacheutil/util_test.go @@ -124,7 +124,7 @@ func (s *S) TestSliceKeyString(c *C) { } } -var sliceKeyMapKeyTests = []struct { +var sliceKeyPkgKeyTests = []struct { key apacheutil.SliceKey expected string }{{ @@ -141,8 +141,8 @@ var sliceKeyMapKeyTests = []struct { expected: "curl", }} -func (s *S) TestSliceKeyMapKey(c *C) { - for _, test := range sliceKeyMapKeyTests { - c.Assert(test.key.MapKey(), Equals, test.expected) +func (s *S) TestSliceKeyPkgKey(c *C) { + for _, test := range sliceKeyPkgKeyTests { + c.Assert(test.key.PkgKey(), Equals, test.expected) } } diff --git a/internal/setup/setup.go b/internal/setup/setup.go index dd649b42..8815f42b 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -162,9 +162,9 @@ func pkgKind(release *Release, pkg *Package) string { return string(store.Kind) } -// pkgMapKey returns the qualified key for a package used as the +// pkgKey returns the qualified key for a package used as the // Release.Packages map key. -func pkgMapKey(name, kind string) string { +func pkgKey(name, kind string) string { if kind != "" { return kind + "/" + name } @@ -175,8 +175,8 @@ func (s *Slice) String() string { return SliceKey{Package: s.Package, Kind: s.Kind, Slice: s.Name}.String() } -func (s *Slice) MapKey() string { - return SliceKey{Package: s.Package, Kind: s.Kind}.MapKey() +func (s *Slice) PkgKey() string { + return SliceKey{Package: s.Package, Kind: s.Kind}.PkgKey() } // Selection holds the required configuration to create a Build for a selection @@ -204,18 +204,18 @@ func (s *Selection) Prefers() (map[string]*Package, error) { if !hasPrefers { continue } - sliceKey := pkgMapKey(slice.Package, slice.Kind) + sPkgKey := pkgKey(slice.Package, slice.Kind) old, ok := pathPreferredPkg[path] if !ok { - pathPreferredPkg[path] = s.Release.Packages[sliceKey] + pathPreferredPkg[path] = s.Release.Packages[sPkgKey] continue } - oldKey := pkgMapKey(old.Name, pkgKind(s.Release, old)) - if oldKey == sliceKey { + oldKey := pkgKey(old.Name, pkgKind(s.Release, old)) + if oldKey == sPkgKey { // Skip if the package was already recorded. continue } - preferred, err := preferredPathPackage(path, oldKey, sliceKey, prefers) + preferred, err := preferredPathPackage(path, oldKey, sPkgKey, prefers) if err != nil { // Note: we have checked above that the path has prefers and // they are different packages so the error cannot be @@ -271,11 +271,11 @@ func (r *Release) validate() error { kind := pkgKind(r, pkg) for _, new := range pkg.Slices { keys = append(keys, SliceKey{Package: pkg.Name, Kind: kind, Slice: new.Name}) - newKey := pkgMapKey(new.Package, new.Kind) + newKey := pkgKey(new.Package, new.Kind) for newPath, newInfo := range new.Contents { if oldSlices, ok := paths[newPath]; ok { for _, old := range oldSlices { - oldKey := pkgMapKey(old.Package, old.Kind) + oldKey := pkgKey(old.Package, old.Kind) if newKey != oldKey { _, err := preferredPathPackage(newPath, newKey, oldKey, prefers) if err == nil { @@ -310,7 +310,7 @@ func (r *Release) validate() error { found := false for _, slice := range paths[skey.path] { - if pkgMapKey(slice.Package, slice.Kind) == skey.pkg { + if pkgKey(slice.Package, slice.Kind) == skey.pkg { found = true break } @@ -335,8 +335,8 @@ func (r *Release) validate() error { } for _, new := range newSlices { newInfo := new.Contents[newPath] - newKey := pkgMapKey(new.Package, new.Kind) - oldKey := pkgMapKey(old.Package, old.Kind) + newKey := pkgKey(new.Package, new.Kind) + oldKey := pkgKey(old.Package, old.Kind) if oldInfo.Kind == GlobPath && (newInfo.Kind == GlobPath || newInfo.Kind == CopyPath) { if newKey == oldKey { continue @@ -409,7 +409,7 @@ func (r *Release) validate() error { func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, error) { // Preprocess the list to improve error messages. for _, key := range keys { - if pkg, ok := pkgs[key.MapKey()]; !ok { + if pkg, ok := pkgs[key.PkgKey()]; !ok { return nil, fmt.Errorf("slices of package %q not found", key.Package) } else if _, ok := pkg.Slices[key.Slice]; !ok { return nil, fmt.Errorf("slice %s not found", key) @@ -427,7 +427,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } seen[key] = true - pkg := pkgs[key.MapKey()] + pkg := pkgs[key.PkgKey()] slice := pkg.Slices[key.Slice] fqslice := slice.String() predecessors := successors[fqslice] @@ -436,7 +436,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } fqreq := req.String() - if reqpkg, ok := pkgs[req.MapKey()]; !ok || reqpkg.Slices[req.Slice] == nil { + if reqpkg, ok := pkgs[req.PkgKey()]; !ok || reqpkg.Slices[req.Slice] == nil { return nil, fmt.Errorf("%s requires %s, but slice is missing", fqslice, fqreq) } predecessors = append(predecessors, fqreq) @@ -523,11 +523,11 @@ func readSlices(release *Release, baseDir, dirName string) error { } // Use the qualified key for the Packages map. - mapKey := pkgMapKey(pkg.Name, kind) - if existing, ok := release.Packages[mapKey]; ok { + pkgMapKey := pkgKey(pkg.Name, kind) + if existing, ok := release.Packages[pkgMapKey]; ok { return fmt.Errorf("package %q slices defined more than once: %s and %s", pkgName, existing.Path, stripBase(baseDir, pkgPath)) } - release.Packages[mapKey] = pkg + release.Packages[pkgMapKey] = pkg } return nil } @@ -560,7 +560,7 @@ func Select(release *Release, slices []SliceKey, arch string) (*Selection, error } selection.Slices = make([]*Slice, len(sorted)) for i, key := range sorted { - selection.Slices[i] = release.Packages[key.MapKey()].Slices[key.Slice] + selection.Slices[i] = release.Packages[key.PkgKey()].Slices[key.Slice] } for _, new := range selection.Slices { diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 8fefa4b5..2a771169 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -110,13 +110,13 @@ func Run(options *RunOptions) error { // Build information to process the selection. extract := make(map[string]map[string][]deb.ExtractInfo) for _, slice := range options.Selection.Slices { - sliceKey := slice.MapKey() - extractPackage := extract[sliceKey] + pkgKey := slice.PkgKey() + extractPackage := extract[pkgKey] if extractPackage == nil { extractPackage = make(map[string][]deb.ExtractInfo) - extract[sliceKey] = extractPackage + extract[pkgKey] = extractPackage } - arch := pkgArch[sliceKey] + arch := pkgArch[pkgKey] for targetPath, pathInfo := range slice.Contents { if targetPath == "" { continue @@ -157,16 +157,16 @@ func Run(options *RunOptions) error { packages := make(map[string]io.ReadSeekCloser) var pkgInfos []*archive.PackageInfo for _, slice := range options.Selection.Slices { - sliceKey := slice.MapKey() - if packages[sliceKey] != nil { + pkgKey := slice.PkgKey() + if packages[pkgKey] != nil { continue } - reader, info, err := pkgArchive[sliceKey].Fetch(slice.Package) + reader, info, err := pkgArchive[pkgKey].Fetch(slice.Package) if err != nil { return err } defer reader.Close() - packages[sliceKey] = reader + packages[pkgKey] = reader pkgInfos = append(pkgInfos, info) } @@ -243,19 +243,19 @@ func Run(options *RunOptions) error { // Extract all packages, also using the selection order. for _, slice := range options.Selection.Slices { - sliceKey := slice.MapKey() - reader := packages[sliceKey] + pkgKey := slice.PkgKey() + reader := packages[pkgKey] if reader == nil { continue } err := deb.Extract(reader, &deb.ExtractOptions{ Package: slice.Package, - Extract: extract[sliceKey], + Extract: extract[pkgKey], TargetDir: targetDir, Create: create, }) reader.Close() - packages[sliceKey] = nil + packages[pkgKey] = nil if err != nil { return err } @@ -279,7 +279,7 @@ func Run(options *RunOptions) error { // them to the appropriate slices. relPaths := map[string][]*setup.Slice{} for _, slice := range options.Selection.Slices { - arch := pkgArch[slice.MapKey()] + arch := pkgArch[slice.PkgKey()] for relPath, pathInfo := range slice.Contents { if len(pathInfo.Arch) > 0 && !slices.Contains(pathInfo.Arch, arch) { continue @@ -518,11 +518,11 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel pkgArchive := make(map[string]archive.Archive) for _, s := range selection.Slices { - sliceKey := s.MapKey() - if _, ok := pkgArchive[sliceKey]; ok { + pkgKey := s.PkgKey() + if _, ok := pkgArchive[pkgKey]; ok { continue } - pkg := selection.Release.Packages[sliceKey] + pkg := selection.Release.Packages[pkgKey] if pkg.Store != "" { // Packages coming from a store are not fetched from an archive, // so we skip them here. @@ -549,7 +549,7 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel if chosen == nil { return nil, fmt.Errorf("cannot find package %q in archive(s)", pkg.Name) } - pkgArchive[sliceKey] = chosen + pkgArchive[pkgKey] = chosen } return pkgArchive, nil } From 9b083fcb5f21afde8affb7e51f3b86d346a346d1 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 13:36:26 +0200 Subject: [PATCH 07/16] fix: start renaming to realname Signed-off-by: Paul Mars --- cmd/chisel/cmd_info.go | 4 +- internal/apacheutil/util.go | 24 +- internal/apacheutil/util_test.go | 59 ++--- internal/manifestutil/manifestutil.go | 6 +- internal/setup/setup.go | 106 ++++----- internal/setup/setup_test.go | 130 ++++------ internal/setup/yaml.go | 28 +-- internal/slicer/slicer.go | 49 ++-- internal/slicer/slicer_test.go | 326 +++++++++++++------------- 9 files changed, 343 insertions(+), 389 deletions(-) diff --git a/cmd/chisel/cmd_info.go b/cmd/chisel/cmd_info.go index 534dc6df..4a08d969 100644 --- a/cmd/chisel/cmd_info.go +++ b/cmd/chisel/cmd_info.go @@ -83,7 +83,7 @@ func selectPackageSlices(release *setup.Release, queries []string) (packages []* allPkgSlices := make(map[string]bool) sliceExists := func(key setup.SliceKey) bool { - pkg, ok := release.Packages[key.PkgKey()] + pkg, ok := release.Packages[key.RealName] if !ok { return false } @@ -98,7 +98,7 @@ func selectPackageSlices(release *setup.Release, queries []string) (packages []* notFound = append(notFound, query) continue } - pkg, slice = key.Package, key.Slice + pkg, slice = key.RealName, key.Slice } else { if _, ok := release.Packages[query]; !ok { notFound = append(notFound, query) diff --git a/internal/apacheutil/util.go b/internal/apacheutil/util.go index 37e1e4e4..8beaf2be 100644 --- a/internal/apacheutil/util.go +++ b/internal/apacheutil/util.go @@ -8,24 +8,12 @@ import ( ) type SliceKey struct { - Package string - Kind string - Slice string + RealName string + Slice string } func (s SliceKey) String() string { - if s.Kind != "" { - return s.Kind + "/" + s.Package + "_" + s.Slice - } - return s.Package + "_" + s.Slice -} - -// PkgKey returns the qualified package key used for Release.Packages lookups. -func (s SliceKey) PkgKey() string { - if s.Kind != "" { - return s.Kind + "/" + s.Package - } - return s.Package + return s.RealName + "_" + s.Slice } // FnameExp matches the slice definition file basename. @@ -34,13 +22,13 @@ var FnameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})\.yaml$`) // SnameExp matches only the slice name, without the leading package name. var SnameExp = regexp.MustCompile(`^([a-z](?:-?[a-z0-9]){2,})$`) -// knameExp matches the slice full name in pkg_slice or kind/pkg_slice format. -var knameExp = regexp.MustCompile(`^(?:([a-z0-9](?:-?[.a-z0-9+]){0,})/)?([a-z0-9](?:-?[.a-z0-9+]){1,})_([a-z](?:-?[a-z0-9]){2,})$`) +// knameExp matches the slice full name in pkg_slice format. +var knameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})_([a-z](?:-?[a-z0-9]){2,})$`) func ParseSliceKey(sliceKey string) (SliceKey, error) { match := knameExp.FindStringSubmatch(sliceKey) if match == nil { return SliceKey{}, fmt.Errorf("invalid slice reference: %q", sliceKey) } - return SliceKey{Package: match[2], Kind: match[1], Slice: match[3]}, nil + return SliceKey{RealName: match[1], Slice: match[2]}, nil } diff --git a/internal/apacheutil/util_test.go b/internal/apacheutil/util_test.go index db4ef7cb..4acab2cb 100644 --- a/internal/apacheutil/util_test.go +++ b/internal/apacheutil/util_test.go @@ -14,34 +14,34 @@ var sliceKeyTests = []struct { err string }{{ input: "foo_bar", - expected: apacheutil.SliceKey{Package: "foo", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "foo", Slice: "bar"}, }, { input: "fo_bar", - expected: apacheutil.SliceKey{Package: "fo", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "fo", Slice: "bar"}, }, { input: "1234_bar", - expected: apacheutil.SliceKey{Package: "1234", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "1234", Slice: "bar"}, }, { input: "foo1.1-2-3_bar", - expected: apacheutil.SliceKey{Package: "foo1.1-2-3", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "foo1.1-2-3", Slice: "bar"}, }, { input: "foo-pkg_dashed-slice-name", - expected: apacheutil.SliceKey{Package: "foo-pkg", Slice: "dashed-slice-name"}, + expected: apacheutil.SliceKey{RealName: "foo-pkg", Slice: "dashed-slice-name"}, }, { input: "foo+_bar", - expected: apacheutil.SliceKey{Package: "foo+", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "foo+", Slice: "bar"}, }, { input: "foo_slice123", - expected: apacheutil.SliceKey{Package: "foo", Slice: "slice123"}, + expected: apacheutil.SliceKey{RealName: "foo", Slice: "slice123"}, }, { input: "g++_bins", - expected: apacheutil.SliceKey{Package: "g++", Slice: "bins"}, + expected: apacheutil.SliceKey{RealName: "g++", Slice: "bins"}, }, { input: "a+_bar", - expected: apacheutil.SliceKey{Package: "a+", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "a+", Slice: "bar"}, }, { input: "a._bar", - expected: apacheutil.SliceKey{Package: "a.", Slice: "bar"}, + expected: apacheutil.SliceKey{RealName: "a.", Slice: "bar"}, }, { input: "foo_ba", err: `invalid slice reference: "foo_ba"`, @@ -78,15 +78,6 @@ var sliceKeyTests = []struct { }, { input: "..._bar", err: `invalid slice reference: "\.\.\._bar"`, -}, { - input: "bin/curl_bins", - expected: apacheutil.SliceKey{Package: "curl", Kind: "bin", Slice: "bins"}, -}, { - input: "bin/g++_bins", - expected: apacheutil.SliceKey{Package: "g++", Kind: "bin", Slice: "bins"}, -}, { - input: "b/curl_bins", - expected: apacheutil.SliceKey{Package: "curl", Kind: "b", Slice: "bins"}, }, { input: "white space_no-whitespace", err: `invalid slice reference: "white space_no-whitespace"`, @@ -108,14 +99,14 @@ var sliceKeyStringTests = []struct { key apacheutil.SliceKey expected string }{{ - key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, + key: apacheutil.SliceKey{RealName: "curl", Slice: "bins"}, expected: "curl_bins", }, { - key: apacheutil.SliceKey{Package: "curl", Kind: "bin", Slice: "bins"}, - expected: "bin/curl_bins", + key: apacheutil.SliceKey{RealName: "bin-curl", Slice: "bins"}, + expected: "bin-curl_bins", }, { - key: apacheutil.SliceKey{Package: "g++", Kind: "bin", Slice: "bins"}, - expected: "bin/g++_bins", + key: apacheutil.SliceKey{RealName: "bin-g++", Slice: "bins"}, + expected: "bin-g++_bins", }} func (s *S) TestSliceKeyString(c *C) { @@ -124,25 +115,25 @@ func (s *S) TestSliceKeyString(c *C) { } } -var sliceKeyPkgKeyTests = []struct { +var sliceKeyRealNameTests = []struct { key apacheutil.SliceKey expected string }{{ - key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, + key: apacheutil.SliceKey{RealName: "curl", Slice: "bins"}, expected: "curl", }, { - key: apacheutil.SliceKey{Package: "curl", Kind: "bin", Slice: "bins"}, - expected: "bin/curl", + key: apacheutil.SliceKey{RealName: "bin-curl", Slice: "bins"}, + expected: "bin-curl", }, { - key: apacheutil.SliceKey{Package: "curl", Kind: "bin"}, - expected: "bin/curl", + key: apacheutil.SliceKey{RealName: "bin-curl"}, + expected: "bin-curl", }, { - key: apacheutil.SliceKey{Package: "curl"}, + key: apacheutil.SliceKey{RealName: "curl"}, expected: "curl", }} -func (s *S) TestSliceKeyPkgKey(c *C) { - for _, test := range sliceKeyPkgKeyTests { - c.Assert(test.key.PkgKey(), Equals, test.expected) +func (s *S) TestSliceKeyRealName(c *C) { + for _, test := range sliceKeyRealNameTests { + c.Assert(test.key.RealName, Equals, test.expected) } } diff --git a/internal/manifestutil/manifestutil.go b/internal/manifestutil/manifestutil.go index 16b05402..edc3616b 100644 --- a/internal/manifestutil/manifestutil.go +++ b/internal/manifestutil/manifestutil.go @@ -134,7 +134,7 @@ func manifestAddReport(dbw *jsonwall.DBWriter, report *Report) error { func unixPerm(mode fs.FileMode) (perm uint32) { perm = uint32(mode.Perm()) if mode&fs.ModeSticky != 0 { - perm |= 01000 + perm |= 0o1000 } return perm } @@ -291,8 +291,8 @@ func Validate(mfest *manifest.Manifest) (err error) { if err != nil { return err } - if !pkgExist[sk.Package] { - return fmt.Errorf("slice %s refers to missing package %q", slice.Name, sk.Package) + if !pkgExist[sk.RealName] { + return fmt.Errorf("slice %s refers to missing package %q", slice.Name, sk.RealName) } sliceExist[slice.Name] = true return nil diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 8815f42b..119fba3e 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -16,15 +16,10 @@ import ( "github.com/canonical/chisel/internal/strdist" ) -// StoreKind identifies the backend type of a store. -type StoreKind string - -const StoreBin StoreKind = "bin" - // Store is the location from which binary packages are obtained via a store API. type Store struct { Name string - Kind StoreKind + Kind string Version string DefaultPrefix string } @@ -75,13 +70,13 @@ type Package struct { // Slice holds the details about a package slice. type Slice struct { - Package string - Kind string - Name string - Hint string - Essential map[SliceKey]EssentialInfo - Contents map[string]PathInfo - Scripts SliceScripts + Package string + DefaultPrefix string + Name string + Hint string + Essential map[SliceKey]EssentialInfo + Contents map[string]PathInfo + Scripts SliceScripts } type EssentialInfo struct { @@ -150,8 +145,8 @@ func ParseSliceKey(sliceKey string) (SliceKey, error) { return apacheutil.ParseSliceKey(sliceKey) } -// pkgKind returns the Kind value for a package based on its store reference. -func pkgKind(release *Release, pkg *Package) string { +// pkgDefaultPrefix returns the DefaultPrefix for a package based on its store reference. +func pkgDefaultPrefix(release *Release, pkg *Package) string { if pkg.Store == "" { return "" } @@ -159,24 +154,21 @@ func pkgKind(release *Release, pkg *Package) string { if store == nil { return "" } - return string(store.Kind) + return store.DefaultPrefix } -// pkgKey returns the qualified key for a package used as the +// realName returns the real name for a package used as the // Release.Packages map key. -func pkgKey(name, kind string) string { - if kind != "" { - return kind + "/" + name - } - return name +func realName(name, defaultPrefix string) string { + return defaultPrefix + name } func (s *Slice) String() string { - return SliceKey{Package: s.Package, Kind: s.Kind, Slice: s.Name}.String() + return SliceKey{RealName: s.RealName(), Slice: s.Name}.String() } -func (s *Slice) PkgKey() string { - return SliceKey{Package: s.Package, Kind: s.Kind}.PkgKey() +func (s *Slice) RealName() string { + return s.DefaultPrefix + s.Package } // Selection holds the required configuration to create a Build for a selection @@ -204,18 +196,18 @@ func (s *Selection) Prefers() (map[string]*Package, error) { if !hasPrefers { continue } - sPkgKey := pkgKey(slice.Package, slice.Kind) + sRealName := slice.RealName() old, ok := pathPreferredPkg[path] if !ok { - pathPreferredPkg[path] = s.Release.Packages[sPkgKey] + pathPreferredPkg[path] = s.Release.Packages[sRealName] continue } - oldKey := pkgKey(old.Name, pkgKind(s.Release, old)) - if oldKey == sPkgKey { + oldRealName := realName(old.Name, pkgDefaultPrefix(s.Release, old)) + if oldRealName == sRealName { // Skip if the package was already recorded. continue } - preferred, err := preferredPathPackage(path, oldKey, sPkgKey, prefers) + preferred, err := preferredPathPackage(path, oldRealName, sRealName, prefers) if err != nil { // Note: we have checked above that the path has prefers and // they are different packages so the error cannot be @@ -268,16 +260,16 @@ func (r *Release) validate() error { // cannot validate that they are the same without downloading the package. paths := make(map[string][]*Slice) for _, pkg := range r.Packages { - kind := pkgKind(r, pkg) + prefix := pkgDefaultPrefix(r, pkg) for _, new := range pkg.Slices { - keys = append(keys, SliceKey{Package: pkg.Name, Kind: kind, Slice: new.Name}) - newKey := pkgKey(new.Package, new.Kind) + keys = append(keys, SliceKey{RealName: realName(pkg.Name, prefix), Slice: new.Name}) + newRealName := new.RealName() for newPath, newInfo := range new.Contents { if oldSlices, ok := paths[newPath]; ok { for _, old := range oldSlices { - oldKey := pkgKey(old.Package, old.Kind) - if newKey != oldKey { - _, err := preferredPathPackage(newPath, newKey, oldKey, prefers) + oldRealName := old.RealName() + if newRealName != oldRealName { + _, err := preferredPathPackage(newPath, newRealName, oldRealName, prefers) if err == nil { continue } else if err != preferNone { @@ -286,8 +278,8 @@ func (r *Release) validate() error { } oldInfo := old.Contents[newPath] - if !newInfo.SameContent(&oldInfo) || (newInfo.Kind == CopyPath || newInfo.Kind == GlobPath) && newKey != oldKey { - if oldKey > newKey || oldKey == newKey && old.Name > new.Name { + if !newInfo.SameContent(&oldInfo) || (newInfo.Kind == CopyPath || newInfo.Kind == GlobPath) && newRealName != oldRealName { + if oldRealName > newRealName || oldRealName == newRealName && old.Name > new.Name { old, new = new, old } return fmt.Errorf("slices %s and %s conflict on %s", old, new, newPath) @@ -310,7 +302,7 @@ func (r *Release) validate() error { found := false for _, slice := range paths[skey.path] { - if pkgKey(slice.Package, slice.Kind) == skey.pkg { + if slice.RealName() == skey.pkg { found = true break } @@ -335,16 +327,16 @@ func (r *Release) validate() error { } for _, new := range newSlices { newInfo := new.Contents[newPath] - newKey := pkgKey(new.Package, new.Kind) - oldKey := pkgKey(old.Package, old.Kind) + newRealName := new.RealName() + oldRealName := old.RealName() if oldInfo.Kind == GlobPath && (newInfo.Kind == GlobPath || newInfo.Kind == CopyPath) { - if newKey == oldKey { + if newRealName == oldRealName { continue } } if strdist.GlobPath(newPath, oldPath) { - if (oldKey > newKey) || (oldKey == newKey && old.Name > new.Name) || - (oldKey == newKey && old.Name == new.Name && oldPath > newPath) { + if (oldRealName > newRealName) || (oldRealName == newRealName && old.Name > new.Name) || + (oldRealName == newRealName && old.Name == new.Name && oldPath > newPath) { old, new = new, old oldPath, newPath = newPath, oldPath } @@ -409,8 +401,8 @@ func (r *Release) validate() error { func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, error) { // Preprocess the list to improve error messages. for _, key := range keys { - if pkg, ok := pkgs[key.PkgKey()]; !ok { - return nil, fmt.Errorf("slices of package %q not found", key.Package) + if pkg, ok := pkgs[key.RealName]; !ok { + return nil, fmt.Errorf("slices of package %q not found", key.RealName) } else if _, ok := pkg.Slices[key.Slice]; !ok { return nil, fmt.Errorf("slice %s not found", key) } @@ -427,7 +419,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } seen[key] = true - pkg := pkgs[key.PkgKey()] + pkg := pkgs[key.RealName] slice := pkg.Slices[key.Slice] fqslice := slice.String() predecessors := successors[fqslice] @@ -436,7 +428,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } fqreq := req.String() - if reqpkg, ok := pkgs[req.PkgKey()]; !ok || reqpkg.Slices[req.Slice] == nil { + if reqpkg, ok := pkgs[req.RealName]; !ok || reqpkg.Slices[req.Slice] == nil { return nil, fmt.Errorf("%s requires %s, but slice is missing", fqslice, fqreq) } predecessors = append(predecessors, fqreq) @@ -514,20 +506,20 @@ func readSlices(release *Release, baseDir, dirName string) error { return err } - // Derive the package Kind from its store reference. - kind := pkgKind(release, pkg) + // Derive the package DefaultPrefix from its store reference. + prefix := pkgDefaultPrefix(release, pkg) - // Set Kind on all slices in the package. + // Set DefaultPrefix on all slices in the package. for _, slice := range pkg.Slices { - slice.Kind = kind + slice.DefaultPrefix = prefix } - // Use the qualified key for the Packages map. - pkgMapKey := pkgKey(pkg.Name, kind) - if existing, ok := release.Packages[pkgMapKey]; ok { + // Use the real name for the Packages map. + pkgRealName := realName(pkg.Name, prefix) + if existing, ok := release.Packages[pkgRealName]; ok { return fmt.Errorf("package %q slices defined more than once: %s and %s", pkgName, existing.Path, stripBase(baseDir, pkgPath)) } - release.Packages[pkgMapKey] = pkg + release.Packages[pkgRealName] = pkg } return nil } @@ -560,7 +552,7 @@ func Select(release *Release, slices []SliceKey, arch string) (*Selection, error } selection.Slices = make([]*Slice, len(sorted)) for i, key := range sorted { - selection.Slices[i] = release.Packages[key.PkgKey()].Slices[key.Slice] + selection.Slices[i] = release.Packages[key.RealName].Slices[key.Slice] } for _, new := range selection.Slices { diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index a3b48b87..e8538213 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -158,7 +158,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "myslice1"}: {}, + {RealName: "mypkg", Slice: "myslice1"}: {}, }, Contents: map[string]setup.PathInfo{ "/another/path": {Kind: "copy"}, @@ -421,7 +421,7 @@ var setupTests = []setupTest{{ myslice2: {essential: [mypkg1_myslice1]} `, }, - selslices: []setup.SliceKey{{Package: "mypkg1", Slice: "myslice1"}}, + selslices: []setup.SliceKey{{RealName: "mypkg1", Slice: "myslice1"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg1", @@ -444,7 +444,7 @@ var setupTests = []setupTest{{ myslice2: {essential: [mypkg1_myslice1]} `, }, - selslices: []setup.SliceKey{{Package: "mypkg2", Slice: "myslice2"}}, + selslices: []setup.SliceKey{{RealName: "mypkg2", Slice: "myslice2"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg1", @@ -453,7 +453,7 @@ var setupTests = []setupTest{{ Package: "mypkg2", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg1", Slice: "myslice1"}: {}, + {RealName: "mypkg1", Slice: "myslice1"}: {}, }, }}, }, @@ -483,7 +483,7 @@ var setupTests = []setupTest{{ /path3: {symlink: /link} `, }, - selslices: []setup.SliceKey{{Package: "mypkg1", Slice: "myslice1"}, {Package: "mypkg1", Slice: "myslice2"}, {Package: "mypkg2", Slice: "myslice1"}}, + selslices: []setup.SliceKey{{RealName: "mypkg1", Slice: "myslice1"}, {RealName: "mypkg1", Slice: "myslice2"}, {RealName: "mypkg2", Slice: "myslice1"}}, }, { summary: "Conflicting paths across slices", input: map[string]string{ @@ -1472,7 +1472,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "slice2"}: {}, + {RealName: "mypkg", Slice: "slice2"}: {}, }, }, "slice2": { @@ -1483,16 +1483,16 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice3", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "slice2"}: {}, - {Package: "mypkg", Slice: "slice1"}: {}, - {Package: "mypkg", Slice: "slice4"}: {}, + {RealName: "mypkg", Slice: "slice2"}: {}, + {RealName: "mypkg", Slice: "slice1"}: {}, + {RealName: "mypkg", Slice: "slice4"}: {}, }, }, "slice4": { Package: "mypkg", Name: "slice4", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "slice2"}: {}, + {RealName: "mypkg", Slice: "slice2"}: {}, }, }, }, @@ -1545,16 +1545,16 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "myotherpkg", Slice: "slice2"}: {}, - {Package: "mypkg", Slice: "slice2"}: {}, - {Package: "myotherpkg", Slice: "slice1"}: {}, + {RealName: "myotherpkg", Slice: "slice2"}: {}, + {RealName: "mypkg", Slice: "slice2"}: {}, + {RealName: "myotherpkg", Slice: "slice1"}: {}, }, }, "slice2": { Package: "mypkg", Name: "slice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "myotherpkg", Slice: "slice2"}: {}, + {RealName: "myotherpkg", Slice: "slice2"}: {}, }, }, }, @@ -1739,7 +1739,7 @@ var setupTests = []setupTest{{ EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), }, }, - selslices: []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}}, + selslices: []setup.SliceKey{{RealName: "mypkg", Slice: "myslice"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg", @@ -1792,7 +1792,7 @@ var setupTests = []setupTest{{ EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), }, }, - selslices: []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}}, + selslices: []setup.SliceKey{{RealName: "mypkg", Slice: "myslice"}}, selerror: `slice mypkg_myslice has invalid 'generate' for path /dir/\*\*: "foo"`, }, { summary: "Paths with generate: manifest must have trailing /**", @@ -2407,10 +2407,10 @@ var setupTests = []setupTest{{ }, { summary: "Path conflicts with 'prefer'", selslices: []setup.SliceKey{ - {Package: "mypkg1", Slice: "myslice1"}, - {Package: "mypkg1", Slice: "myslice2"}, - {Package: "mypkg2", Slice: "myslice1"}, - {Package: "mypkg3", Slice: "myslice1"}, + {RealName: "mypkg1", Slice: "myslice1"}, + {RealName: "mypkg1", Slice: "myslice2"}, + {RealName: "mypkg2", Slice: "myslice1"}, + {RealName: "mypkg3", Slice: "myslice1"}, }, input: map[string]string{ "slices/mydir/mypkg1.yaml": ` @@ -2514,9 +2514,9 @@ var setupTests = []setupTest{{ }, { summary: "Path conflicts with 'prefer' depends on selection", selslices: []setup.SliceKey{ - {Package: "mypkg1", Slice: "myslice1"}, - {Package: "mypkg1", Slice: "myslice2"}, - {Package: "mypkg2", Slice: "myslice1"}, + {RealName: "mypkg1", Slice: "myslice1"}, + {RealName: "mypkg1", Slice: "myslice2"}, + {RealName: "mypkg2", Slice: "myslice1"}, }, input: map[string]string{ "slices/mydir/mypkg1.yaml": ` @@ -3664,24 +3664,24 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "myslice2"}: {Arch: []string{"amd64"}}, - {Package: "mypkg", Slice: "myslice3"}: {Arch: []string{"amd64", "arm64"}}, - {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, - {Package: "mypkg", Slice: "myslice5"}: {Arch: nil}, + {RealName: "mypkg", Slice: "myslice2"}: {Arch: []string{"amd64"}}, + {RealName: "mypkg", Slice: "myslice3"}: {Arch: []string{"amd64", "arm64"}}, + {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {RealName: "mypkg", Slice: "myslice5"}: {Arch: nil}, }, }, "myslice2": { Package: "mypkg", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, "myslice3": { Package: "mypkg", Name: "myslice3", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, "myslice4": { @@ -3693,7 +3693,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice5", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, }, @@ -3941,13 +3941,13 @@ var setupTests = []setupTest{{ Stores: map[string]*setup.Store{ "bin": { Name: "bin", - Kind: setup.StoreBin, + Kind: "bin", Version: "26.10", DefaultPrefix: "bin-", }, }, Packages: map[string]*setup.Package{ - "bin/mypkg": { + "bin-mypkg": { Name: "mypkg", Path: "slices/bin/mypkg.yaml", Store: "bin", @@ -4009,32 +4009,6 @@ var setupTests = []setupTest{{ `, }, relerror: `slices/bin/mypkg.yaml: package refers to undefined store "no-such-store"`, -}, { - summary: "Store with invalid kind", - input: map[string]string{ - "chisel.yaml": ` - format: v3 - maintenance: - standard: 2025-01-01 - end-of-life: 2100-01-01 - archives: - ubuntu: - version: 26.10 - components: [main, universe] - suites: [stonking] - public-keys: [test-key] - public-keys: - test-key: - id: ` + testKey.ID + ` - armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` - stores: - mystore: - kind: unknown-kind - version: 26.10 - default-prefix: "pfx-" - `, - }, - relerror: `chisel.yaml: store "mystore" has invalid kind "unknown-kind"`, }, { summary: "Store missing version", input: map[string]string{ @@ -4144,7 +4118,7 @@ var setupTests = []setupTest{{ Stores: map[string]*setup.Store{ "bin": { Name: "bin", - Kind: setup.StoreBin, + Kind: "bin", Version: "26.10", DefaultPrefix: "bin-", }, @@ -4155,33 +4129,33 @@ var setupTests = []setupTest{{ Path: "slices/curl.yaml", Slices: map[string]*setup.Slice{ "libs": { - Package: "curl", - Kind: "", - Name: "libs", + Package: "curl", + DefaultPrefix: "", + Name: "libs", Contents: map[string]setup.PathInfo{ "/usr/lib/libcurl.so": {Kind: setup.CopyPath}, }, }, "bins": { - Package: "curl", - Kind: "", - Name: "bins", + Package: "curl", + DefaultPrefix: "", + Name: "bins", Contents: map[string]setup.PathInfo{ "/usr/bin/curl": {Kind: setup.CopyPath}, }, }, }, }, - "bin/curl": { + "bin-curl": { Name: "curl", Path: "slices/bin/curl.yaml", Store: "bin", DefaultTrack: "3.0", Slices: map[string]*setup.Slice{ "bins": { - Package: "curl", - Kind: "bin", - Name: "bins", + Package: "curl", + DefaultPrefix: "bin-", + Name: "bins", Contents: map[string]setup.PathInfo{ "/usr/bin/curl-bin": {Kind: setup.CopyPath}, }, @@ -4296,9 +4270,9 @@ func runParseReleaseTests(c *C, tests []setupTest) { dir := c.MkDir() for path, data := range test.input { fpath := filepath.Join(dir, path) - err := os.MkdirAll(filepath.Dir(fpath), 0755) + err := os.MkdirAll(filepath.Dir(fpath), 0o755) c.Assert(err, IsNil) - err = os.WriteFile(fpath, testutil.Reindent(data), 0644) + err = os.WriteFile(fpath, testutil.Reindent(data), 0o644) c.Assert(err, IsNil) } @@ -4393,16 +4367,16 @@ func (s *S) TestPackageMarshalYAML(c *C) { dir := c.MkDir() // Write chisel.yaml. fpath := filepath.Join(dir, "chisel.yaml") - err := os.WriteFile(fpath, testutil.Reindent(data), 0644) + err := os.WriteFile(fpath, testutil.Reindent(data), 0o644) c.Assert(err, IsNil) // Write the packages YAML. for _, pkg := range test.release.Packages { fpath = filepath.Join(dir, pkg.Path) - err = os.MkdirAll(filepath.Dir(fpath), 0755) + err = os.MkdirAll(filepath.Dir(fpath), 0o755) c.Assert(err, IsNil) pkgData, err := yaml.Marshal(pkg) c.Assert(err, IsNil) - err = os.WriteFile(fpath, testutil.Reindent(string(pkgData)), 0644) + err = os.WriteFile(fpath, testutil.Reindent(string(pkgData)), 0o644) c.Assert(err, IsNil) } @@ -4415,7 +4389,7 @@ func (s *S) TestPackageMarshalYAML(c *C) { } func (s *S) TestPackageYAMLFormat(c *C) { - var tests = []struct { + tests := []struct { summary string input map[string]string expected map[string]string @@ -4610,9 +4584,9 @@ func (s *S) TestPackageYAMLFormat(c *C) { dir := c.MkDir() for path, data := range test.input { fpath := filepath.Join(dir, path) - err := os.MkdirAll(filepath.Dir(fpath), 0755) + err := os.MkdirAll(filepath.Dir(fpath), 0o755) c.Assert(err, IsNil) - err = os.WriteFile(fpath, testutil.Reindent(data), 0644) + err = os.WriteFile(fpath, testutil.Reindent(data), 0o644) c.Assert(err, IsNil) } @@ -4698,7 +4672,7 @@ func (s *S) TestSelectEmptyArch(c *C) { release, err := setup.ReadRelease(dir) c.Assert(err, IsNil) - selslice := []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}} + selslice := []setup.SliceKey{{RealName: "mypkg", Slice: "myslice"}} selection, err := setup.Select(release, selslice, "") c.Assert(err, IsNil) diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index 36335b19..a08f4911 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -127,8 +127,10 @@ func (es yamlEssentialListMap) MarshalYAML() (any, error) { return es.Values, nil } -var _ yaml.Marshaler = yamlEssentialListMap{} -var _ yaml.Unmarshaler = (*yamlEssentialListMap)(nil) +var ( + _ yaml.Marshaler = yamlEssentialListMap{} + _ yaml.Unmarshaler = (*yamlEssentialListMap)(nil) +) type yamlPath struct { Dir bool `yaml:"make,omitempty"` @@ -450,10 +452,8 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { release.Stores = make(map[string]*Store, len(yamlVar.Stores)) } for storeName, details := range yamlVar.Stores { - switch StoreKind(details.Kind) { - case StoreBin: - default: - return nil, fmt.Errorf("%s: store %q has invalid kind %q", fileName, storeName, details.Kind) + if details.Kind == "" { + return nil, fmt.Errorf("%s: store %q missing kind field", fileName, storeName) } if details.Version == "" { return nil, fmt.Errorf("%s: store %q missing version field", fileName, storeName) @@ -463,7 +463,7 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { } release.Stores[storeName] = &Store{ Name: storeName, - Kind: StoreKind(details.Kind), + Kind: details.Kind, Version: details.Version, DefaultPrefix: details.DefaultPrefix, } @@ -496,7 +496,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != listEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{Package: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{RealName: pkgName, Slice: sliceName}) } } } else { @@ -508,10 +508,10 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.V3Essential != nil { - return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{RealName: pkgName, Slice: sliceName}) } if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{RealName: pkgName, Slice: sliceName}) } } } @@ -544,7 +544,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error return !unicode.IsPrint(r) }) if len(yamlSlice.Hint) > 40 || hintNotPrintable { - return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkgName, Slice: sliceName}, yamlSlice.Hint) + return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{RealName: pkgName, Slice: sliceName}, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, @@ -571,7 +571,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error if !path.IsAbs(contPath) || path.Clean(contPath) != comparePath { return nil, fmt.Errorf("slice %s_%s has invalid content path: %s", pkgName, sliceName, contPath) } - var kinds = make([]PathKind, 0, 3) + kinds := make([]PathKind, 0, 3) var info string var mode uint var mutable bool @@ -856,7 +856,7 @@ func parseEssentials(yamlPkg *yamlPackage, yamlSlice *yamlSlice, pkgPath string, if err != nil { return fmt.Errorf("package %q has invalid essential slice reference: %q", yamlPkg.Name, refName) } - if sliceKey.Package == slice.Package && sliceKey.Slice == slice.Name { + if sliceKey.RealName == slice.RealName() && sliceKey.Slice == slice.Name { // Do not add the slice to its own essentials list. return nil } @@ -878,7 +878,7 @@ func parseEssentials(yamlPkg *yamlPackage, yamlSlice *yamlSlice, pkgPath string, if err != nil { return fmt.Errorf("package %q has invalid essential slice reference: %q", yamlPkg.Name, refName) } - if sliceKey.Package == slice.Package && sliceKey.Slice == slice.Name { + if sliceKey.RealName == slice.RealName() && sliceKey.Slice == slice.Name { return fmt.Errorf("cannot add slice to itself as essential %s in %s", refName, pkgPath) } if _, ok := slice.Essential[sliceKey]; ok { diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 2a771169..f0ac9b6c 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -23,7 +23,7 @@ import ( "github.com/canonical/chisel/internal/setup" ) -const manifestMode fs.FileMode = 0644 +const manifestMode fs.FileMode = 0o644 type RunOptions struct { Selection *setup.Selection @@ -95,10 +95,10 @@ func Run(options *RunOptions) error { return err } - // Build a map from package map key to architecture. + // Build a map from package real name to architecture. pkgArch := make(map[string]string) - for pkgKey, a := range pkgArchive { - pkgArch[pkgKey] = a.Options().Arch + for realName, a := range pkgArchive { + pkgArch[realName] = a.Options().Arch } // TODO Handle packages coming from a store as well when we support them. @@ -110,13 +110,13 @@ func Run(options *RunOptions) error { // Build information to process the selection. extract := make(map[string]map[string][]deb.ExtractInfo) for _, slice := range options.Selection.Slices { - pkgKey := slice.PkgKey() - extractPackage := extract[pkgKey] + realName := slice.RealName() + extractPackage := extract[realName] if extractPackage == nil { extractPackage = make(map[string][]deb.ExtractInfo) - extract[pkgKey] = extractPackage + extract[realName] = extractPackage } - arch := pkgArch[pkgKey] + arch := pkgArch[realName] for targetPath, pathInfo := range slice.Contents { if targetPath == "" { continue @@ -157,16 +157,16 @@ func Run(options *RunOptions) error { packages := make(map[string]io.ReadSeekCloser) var pkgInfos []*archive.PackageInfo for _, slice := range options.Selection.Slices { - pkgKey := slice.PkgKey() - if packages[pkgKey] != nil { + realName := slice.RealName() + if packages[realName] != nil { continue } - reader, info, err := pkgArchive[pkgKey].Fetch(slice.Package) + reader, info, err := pkgArchive[realName].Fetch(slice.Package) if err != nil { return err } defer reader.Close() - packages[pkgKey] = reader + packages[realName] = reader pkgInfos = append(pkgInfos, info) } @@ -243,19 +243,19 @@ func Run(options *RunOptions) error { // Extract all packages, also using the selection order. for _, slice := range options.Selection.Slices { - pkgKey := slice.PkgKey() - reader := packages[pkgKey] + realName := slice.RealName() + reader := packages[realName] if reader == nil { continue } err := deb.Extract(reader, &deb.ExtractOptions{ Package: slice.Package, - Extract: extract[pkgKey], + Extract: extract[realName], TargetDir: targetDir, Create: create, }) reader.Close() - packages[pkgKey] = nil + packages[realName] = nil if err != nil { return err } @@ -279,7 +279,7 @@ func Run(options *RunOptions) error { // them to the appropriate slices. relPaths := map[string][]*setup.Slice{} for _, slice := range options.Selection.Slices { - arch := pkgArch[slice.PkgKey()] + arch := pkgArch[slice.RealName()] for relPath, pathInfo := range slice.Contents { if len(pathInfo.Arch) > 0 && !slices.Contains(pathInfo.Arch, arch) { continue @@ -361,7 +361,8 @@ func Run(options *RunOptions) error { } func generateManifests(targetDir string, selection *setup.Selection, - report *manifestutil.Report, pkgInfos []*archive.PackageInfo) error { + report *manifestutil.Report, pkgInfos []*archive.PackageInfo, +) error { manifestSlices := manifestutil.FindPaths(selection.Slices) if len(manifestSlices) == 0 { // Nothing to do. @@ -466,9 +467,9 @@ func createFile(targetDir, relPath string, pathInfo setup.PathInfo) (*fsutil.Ent targetMode := pathInfo.Mode if targetMode == 0 { if pathInfo.Kind == setup.DirPath { - targetMode = 0755 + targetMode = 0o755 } else { - targetMode = 0644 + targetMode = 0o644 } } @@ -518,11 +519,11 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel pkgArchive := make(map[string]archive.Archive) for _, s := range selection.Slices { - pkgKey := s.PkgKey() - if _, ok := pkgArchive[pkgKey]; ok { + realName := s.RealName() + if _, ok := pkgArchive[realName]; ok { continue } - pkg := selection.Release.Packages[pkgKey] + pkg := selection.Release.Packages[realName] if pkg.Store != "" { // Packages coming from a store are not fetched from an archive, // so we skip them here. @@ -549,7 +550,7 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel if chosen == nil { return nil, fmt.Errorf("cannot find package %q in archive(s)", pkg.Name) } - pkgArchive[pkgKey] = chosen + pkgArchive[realName] = chosen } return pkgArchive, nil } diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index 8935014f..c6cdc92d 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -22,9 +22,7 @@ import ( "github.com/canonical/chisel/public/manifest" ) -var ( - testKey = testutil.PGPKeys["key1"] -) +var testKey = testutil.PGPKeys["key1"] type slicerTest struct { summary string @@ -46,7 +44,7 @@ var packageEntries = map[string][]testutil.TarEntry{ {Header: tar.Header{Name: "./usr/"}}, {Header: tar.Header{Name: "./usr/lib/"}}, {Header: tar.Header{Name: "./usr/lib/x86_64-linux-gnu/"}}, - {Header: tar.Header{Name: "./usr/lib/x86_64-linux-gnu/libssl.so.3", Mode: 00755}}, + {Header: tar.Header{Name: "./usr/lib/x86_64-linux-gnu/libssl.so.3", Mode: 0o0755}}, {Header: tar.Header{Name: "./usr/share/"}}, {Header: tar.Header{Name: "./usr/share/doc/"}}, {Header: tar.Header{Name: "./usr/share/doc/copyright-symlink-libssl3/"}}, @@ -59,7 +57,7 @@ var packageEntries = map[string][]testutil.TarEntry{ {Header: tar.Header{Name: "./etc/ssl/openssl.cnf"}}, {Header: tar.Header{Name: "./usr/"}}, {Header: tar.Header{Name: "./usr/bin/"}}, - {Header: tar.Header{Name: "./usr/bin/openssl", Mode: 00755}}, + {Header: tar.Header{Name: "./usr/bin/openssl", Mode: 0o0755}}, {Header: tar.Header{Name: "./usr/share/"}}, {Header: tar.Header{Name: "./usr/share/doc/"}}, {Header: tar.Header{Name: "./usr/share/doc/copyright-symlink-openssl/"}}, @@ -69,16 +67,16 @@ var packageEntries = map[string][]testutil.TarEntry{ var testPackageCopyrightEntries = []testutil.TarEntry{ // Hardcoded copyright paths. - testutil.Dir(0755, "./usr/"), - testutil.Dir(0755, "./usr/share/"), - testutil.Dir(0755, "./usr/share/doc/"), - testutil.Dir(0755, "./usr/share/doc/test-package/"), - testutil.Reg(0644, "./usr/share/doc/test-package/copyright", "copyright"), + testutil.Dir(0o755, "./usr/"), + testutil.Dir(0o755, "./usr/share/"), + testutil.Dir(0o755, "./usr/share/doc/"), + testutil.Dir(0o755, "./usr/share/doc/test-package/"), + testutil.Reg(0o644, "./usr/share/doc/test-package/copyright", "copyright"), } var slicerTests = []slicerTest{{ summary: "Basic slicing", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -111,7 +109,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Glob extraction", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -133,7 +131,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new file under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -153,7 +151,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new nested file under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -174,7 +172,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new directory under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -194,7 +192,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new file using glob and preserve parent directory permissions", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -218,7 +216,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Conditional architecture", arch: "amd64", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -249,7 +247,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Copyright is not installed implicitly", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", // Add the copyright entries to the package. @@ -274,8 +272,9 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}, - {Package: "other-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + {RealName: "other-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.PackageData["test-package"], @@ -317,25 +316,26 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages, explicit path has preference over implicit parent", slices: []setup.SliceKey{ - {Package: "a-implicit-parent", Slice: "myslice"}, - {Package: "b-explicit-dir", Slice: "myslice"}, - {Package: "c-implicit-parent", Slice: "myslice"}}, + {RealName: "a-implicit-parent", Slice: "myslice"}, + {RealName: "b-explicit-dir", Slice: "myslice"}, + {RealName: "c-implicit-parent", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "a-implicit-parent", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./dir/"), - testutil.Reg(0644, "./dir/file-1", "random"), + testutil.Dir(0o755, "./dir/"), + testutil.Reg(0o644, "./dir/file-1", "random"), }), }, { Name: "b-explicit-dir", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(01777, "./dir/"), + testutil.Dir(0o1777, "./dir/"), }), }, { Name: "c-implicit-parent", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0766, "./dir/"), - testutil.Reg(0644, "./dir/file-2", "random"), + testutil.Dir(0o766, "./dir/"), + testutil.Reg(0o644, "./dir/file-2", "random"), }), }}, release: map[string]string{ @@ -376,8 +376,9 @@ var slicerTests = []slicerTest{{ }, { summary: "Valid same file in two slices in different packages", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}, - {Package: "other-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + {RealName: "other-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.PackageData["test-package"], @@ -409,7 +410,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: write a file", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -430,7 +431,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: read a file", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -456,7 +457,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: use 'until' to remove file after mutate", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -480,7 +481,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: use 'until' to remove wildcard after mutate", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -498,7 +499,7 @@ var slicerTests = []slicerTest{{ manifestPaths: map[string]string{}, }, { summary: "Script: 'until' does not remove non-empty directories", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -519,7 +520,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: writing same contents to existing file does not set the final hash in report", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -540,7 +541,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: cannot write non-mutable files", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -555,7 +556,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/text-file`, }, { summary: "Script: cannot write to unlisted file", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -569,7 +570,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/text-file`, }, { summary: "Script: cannot write to directory", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -584,7 +585,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/`, }, { summary: "Script: cannot read unlisted content", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice2"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice2"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -600,7 +601,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice2: cannot read file which is not selected: /dir/text-file`, }, { summary: "Script: can read globbed content", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice1"}, {Package: "test-package", Slice: "myslice2"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice1"}, {RealName: "test-package", Slice: "myslice2"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -615,7 +616,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Relative content root directory must not error", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -636,7 +637,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Can list parent directories of normal paths", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -655,7 +656,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot list unselected directory", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -670,7 +671,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot list directory which is not selected: /a/d/`, }, { summary: "Cannot list file path as a directory", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -685,7 +686,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: content is not a directory: /a/b/c`, }, { summary: "Can list parent directories of globs", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -699,7 +700,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot list directories not matched by glob", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -714,7 +715,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot list directory which is not selected: /other-dir/`, }, { summary: "Duplicate copyright symlink is ignored", - slices: []setup.SliceKey{{Package: "copyright-symlink-openssl", Slice: "bins"}}, + slices: []setup.SliceKey{{RealName: "copyright-symlink-openssl", Slice: "bins"}}, pkgs: []*testutil.TestPackage{{ Name: "copyright-symlink-openssl", Data: testutil.MustMakeDeb(packageEntries["copyright-symlink-openssl"]), @@ -746,7 +747,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Can list unclean directory paths", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -765,7 +766,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot read directories", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -780,14 +781,14 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: content is not a file: /x/y`, }, { summary: "Multiple archives with priority", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}, {Package: "other-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}, {RealName: "other-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", Version: "v1", Arch: "a1", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from foo"), + testutil.Reg(0o644, "./file", "from foo"), }), Archives: []string{"foo"}, }, { @@ -796,7 +797,7 @@ var slicerTests = []slicerTest{{ Version: "v2", Arch: "a2", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from bar"), + testutil.Reg(0o644, "./file", "from bar"), }), Archives: []string{"bar"}, }, { @@ -805,7 +806,7 @@ var slicerTests = []slicerTest{{ Version: "v3", Arch: "a3", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./other-file", "from bar"), + testutil.Reg(0o644, "./other-file", "from bar"), }), Archives: []string{"bar"}, }}, @@ -864,14 +865,14 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Pinned archive bypasses higher priority", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", Version: "v1", Arch: "a1", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from foo"), + testutil.Reg(0o644, "./file", "from foo"), }), Archives: []string{"foo"}, }, { @@ -880,7 +881,7 @@ var slicerTests = []slicerTest{{ Version: "v2", Arch: "a2", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from bar"), + testutil.Reg(0o644, "./file", "from bar"), }), Archives: []string{"bar"}, }}, @@ -932,11 +933,11 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Pinned archive does not have the package", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from foo"), + testutil.Reg(0o644, "./file", "from foo"), }), Archives: []string{"foo"}, }}, @@ -978,7 +979,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "No archives have the package", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{}, release: map[string]string{ "chisel.yaml": ` @@ -1015,11 +1016,11 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "Negative priority archives are ignored when not explicitly pinned in package", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from foo"), + testutil.Reg(0o644, "./file", "from foo"), }), Archives: []string{"foo"}, }}, @@ -1052,14 +1053,14 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "Negative priority archive explicitly pinned in package", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", Version: "v1", Arch: "a1", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Reg(0644, "./file", "from foo"), + testutil.Reg(0o644, "./file", "from foo"), }), Archives: []string{"foo"}, }}, @@ -1102,8 +1103,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Multiple slices of same package", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice1"}, - {Package: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1140,8 +1141,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Same glob in several entries with until:mutate and reading from script", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice1"}, - {Package: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1186,8 +1187,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping globs, until:mutate and reading from script", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice2"}, - {Package: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1232,8 +1233,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on entry and reading from script", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice1"}, - {Package: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1278,8 +1279,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on glob and reading from script", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice1"}, - {Package: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1307,8 +1308,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on both and reading from script", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice1"}, - {Package: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1331,8 +1332,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Content not created in packages with until:mutate on one and reading from script", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice1"}, - {Package: "test-package", Slice: "myslice2"}, + {RealName: "test-package", Slice: "myslice1"}, + {RealName: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1355,8 +1356,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages, both are recorded", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}, - {Package: "other-package", Slice: "myslice"}, + {RealName: "test-package", Slice: "myslice"}, + {RealName: "other-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1392,7 +1393,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Two packages, only one is selected and recorded", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}, + {RealName: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1426,7 +1427,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Relative paths are properly trimmed during extraction", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1436,12 +1437,12 @@ var slicerTests = []slicerTest{{ // relative path. Since TrimLeft takes in a cutset instead of a // prefix, the desired relative path was not produced. // See https://github.com/canonical/chisel/pull/145. - testutil.Dir(0755, "./foo-bar/"), + testutil.Dir(0o755, "./foo-bar/"), }), }}, hackopt: func(c *C, opts *slicer.RunOptions) { opts.TargetDir = filepath.Join(filepath.Clean(opts.TargetDir), "foo") - err := os.Mkdir(opts.TargetDir, 0755) + err := os.Mkdir(opts.TargetDir, 0o755) c.Assert(err, IsNil) }, release: map[string]string{ @@ -1457,7 +1458,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Producing a manifest is not mandatory", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, hackopt: func(c *C, opts *slicer.RunOptions) { // Remove the manifest slice that the tests add automatically. var index int @@ -1479,7 +1480,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "No valid archives defined due to invalid pro value", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, release: map[string]string{ "chisel.yaml": ` format: v1 @@ -1506,14 +1507,15 @@ var slicerTests = []slicerTest{{ }, { summary: "Valid hard link in two slices in the same package", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "slice1"}, - {Package: "test-package", Slice: "slice2"}}, + {RealName: "test-package", Slice: "slice1"}, + {RealName: "test-package", Slice: "slice2"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), - testutil.Hrd(0644, "./hardlink", "./file"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), + testutil.Hrd(0o644, "./hardlink", "./file"), }), }}, release: map[string]string{ @@ -1540,14 +1542,15 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link entries can be extracted without extracting the regular file", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), - testutil.Hrd(0644, "./hardlink1", "./file"), - testutil.Hrd(0644, "./hardlink2", "./file"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), + testutil.Hrd(0o644, "./hardlink1", "./file"), + testutil.Hrd(0o644, "./hardlink2", "./file"), }), }}, release: map[string]string{ @@ -1570,15 +1573,16 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link identifier for different groups", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file1", "text for file1"), - testutil.Reg(0644, "./file2", "text for file2"), - testutil.Hrd(0644, "./hardlink1", "./file1"), - testutil.Hrd(0644, "./hardlink2", "./file2"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file1", "text for file1"), + testutil.Reg(0o644, "./file2", "text for file2"), + testutil.Hrd(0o644, "./hardlink1", "./file1"), + testutil.Hrd(0o644, "./hardlink2", "./file2"), }), }}, release: map[string]string{ @@ -1605,13 +1609,14 @@ var slicerTests = []slicerTest{{ }, { summary: "Single hard link entry can be extracted without regular file and no hard links are created", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), - testutil.Hrd(0644, "./hardlink", "./file"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), + testutil.Hrd(0o644, "./hardlink", "./file"), }), }}, release: map[string]string{ @@ -1632,15 +1637,16 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link to symlink does not follow symlink", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), - testutil.Lnk(0644, "./symlink", "./file"), - testutil.Hrd(0644, "./hardlink", "./symlink"), + testutil.Dir(0o755, "./"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), + testutil.Lnk(0o644, "./symlink", "./file"), + testutil.Hrd(0o644, "./hardlink", "./symlink"), }), }}, release: map[string]string{ @@ -1664,22 +1670,22 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link identifiers are unique across packages", slices: []setup.SliceKey{ - {Package: "test-package1", Slice: "myslice"}, - {Package: "test-package2", Slice: "myslice"}, + {RealName: "test-package1", Slice: "myslice"}, + {RealName: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file1", "foo"), - testutil.Hrd(0644, "./hardlink1", "./file1"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file1", "foo"), + testutil.Hrd(0o644, "./hardlink1", "./file1"), }), }, { Name: "test-package2", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file2", "foo"), - testutil.Hrd(0644, "./hardlink2", "./file2"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file2", "foo"), + testutil.Hrd(0o644, "./hardlink2", "./file2"), }), }}, release: map[string]string{ @@ -1715,13 +1721,14 @@ var slicerTests = []slicerTest{{ }, { summary: "Mutations for hard links are forbidden", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), - testutil.Hrd(0644, "./hardlink", "./file"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), + testutil.Hrd(0o644, "./hardlink", "./file"), }), }}, release: map[string]string{ @@ -1740,13 +1747,14 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard links can be marked as mutable, but not mutated", slices: []setup.SliceKey{ - {Package: "test-package", Slice: "myslice"}}, + {RealName: "test-package", Slice: "myslice"}, + }, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), - testutil.Hrd(0644, "./hardlink", "./file"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), + testutil.Hrd(0o644, "./hardlink", "./file"), }), }}, release: map[string]string{ @@ -1769,12 +1777,12 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Hard links cannot escape the target directory", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Hrd(0644, "./hardlink", "/etc/group"), + testutil.Dir(0o755, "./"), + testutil.Hrd(0o644, "./hardlink", "/etc/group"), }), }}, release: map[string]string{ @@ -1789,12 +1797,12 @@ var slicerTests = []slicerTest{{ error: `cannot extract from package "test-package": invalid link target /etc/group`, }, { summary: "Cannot extract outside of target directory", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./../file", "hijacking system file"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./../file", "hijacking system file"), }), }}, release: map[string]string{ @@ -1810,25 +1818,25 @@ var slicerTests = []slicerTest{{ }, { summary: "Extract conflicting paths with prefer from proper package", slices: []setup.SliceKey{ - {Package: "test-package1", Slice: "myslice"}, - {Package: "test-package2", Slice: "myslice"}, + {RealName: "test-package1", Slice: "myslice"}, + {RealName: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "foo"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "foo"), }), }, { Name: "test-package2", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), - testutil.Reg(0644, "./file", "bar"), + testutil.Dir(0o755, "./"), + testutil.Reg(0o644, "./file", "bar"), }), }, { Name: "test-package3", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), + testutil.Dir(0o755, "./"), }), }}, release: map[string]string{ @@ -1871,24 +1879,24 @@ var slicerTests = []slicerTest{{ }, { summary: "Warning when implicit parent directories conflict", slices: []setup.SliceKey{ - {Package: "test-package1", Slice: "myslice"}, - {Package: "test-package2", Slice: "myslice"}, + {RealName: "test-package1", Slice: "myslice"}, + {RealName: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), + testutil.Dir(0o755, "./"), // Note that both implicit parents have different permissions. - testutil.Dir(0766, "./parent/"), - testutil.Reg(0644, "./parent/foo", "whatever"), + testutil.Dir(0o766, "./parent/"), + testutil.Reg(0o644, "./parent/foo", "whatever"), }), }, { Name: "test-package2", Data: testutil.MustMakeDeb([]testutil.TarEntry{ - testutil.Dir(0755, "./"), + testutil.Dir(0o755, "./"), // And here. - testutil.Dir(0755, "./parent/"), - testutil.Reg(0644, "./parent/bar", "whatever"), + testutil.Dir(0o755, "./parent/"), + testutil.Reg(0o644, "./parent/bar", "whatever"), }), }}, release: map[string]string{ @@ -1910,7 +1918,7 @@ var slicerTests = []slicerTest{{ logOutput: `(?s).*Warning: Path "/parent/" has diverging modes in different packages\. Please report\..*`, }, { summary: "Arch specific slice is not installed when it does not match requested arch", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, arch: "amd64", release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1929,7 +1937,7 @@ var slicerTests = []slicerTest{{ manifestPaths: map[string]string{}, }, { summary: "Arch specific slice is installed when it matches requested arch", - slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, arch: "arm64", release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1953,7 +1961,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Transitive essential", - slices: []setup.SliceKey{{Package: "test-package", Slice: "first"}}, + slices: []setup.SliceKey{{RealName: "test-package", Slice: "first"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -2049,9 +2057,9 @@ func runSlicerTests(s *S, c *C, tests []slicerTest) { releaseDir := c.MkDir() for path, data := range test.release { fpath := filepath.Join(releaseDir, path) - err := os.MkdirAll(filepath.Dir(fpath), 0755) + err := os.MkdirAll(filepath.Dir(fpath), 0o755) c.Assert(err, IsNil) - err = os.WriteFile(fpath, testutil.Reindent(data), 0644) + err = os.WriteFile(fpath, testutil.Reindent(data), 0o644) c.Assert(err, IsNil) } @@ -2059,7 +2067,7 @@ func runSlicerTests(s *S, c *C, tests []slicerTest) { c.Assert(err, IsNil) // Create a manifest slice and add it to the selection. - manifestPackage := test.slices[0].Package + manifestPackage := test.slices[0].RealName manifestPath := "/chisel-data/manifest.wall" release.Packages[manifestPackage].Slices["manifest"] = &setup.Slice{ Package: manifestPackage, @@ -2074,8 +2082,8 @@ func runSlicerTests(s *S, c *C, tests []slicerTest) { Scripts: setup.SliceScripts{}, } testSlices = append(testSlices, setup.SliceKey{ - Package: manifestPackage, - Slice: "manifest", + RealName: manifestPackage, + Slice: "manifest", }) selection, err := setup.Select(release, testSlices, test.arch) @@ -2229,9 +2237,9 @@ func readManifest(c *C, targetDir, manifestPath string) *manifest.Manifest { // in the manifest itself. s, err := os.Stat(path.Join(targetDir, manifestPath)) c.Assert(err, IsNil) - c.Assert(s.Mode(), Equals, fs.FileMode(0644)) + c.Assert(s.Mode(), Equals, fs.FileMode(0o644)) err = mfest.IteratePaths(manifestPath, func(p *manifest.Path) error { - c.Assert(p.Mode, Equals, fmt.Sprintf("%#o", fs.FileMode(0644))) + c.Assert(p.Mode, Equals, fmt.Sprintf("%#o", fs.FileMode(0o644))) return nil }) c.Assert(err, IsNil) From caf5fc493381dc6b1650b7db1e8c5df3268b3d8e Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 14:10:19 +0200 Subject: [PATCH 08/16] fix: more renaming/refactoring Signed-off-by: Paul Mars --- cmd/chisel/cmd_info.go | 10 +- internal/apacheutil/util.go | 8 +- internal/apacheutil/util_test.go | 42 +++---- internal/manifestutil/manifestutil.go | 4 +- internal/setup/setup.go | 16 +-- internal/setup/setup_test.go | 62 +++++----- internal/setup/yaml.go | 12 +- internal/slicer/slicer_test.go | 166 +++++++++++++------------- 8 files changed, 161 insertions(+), 159 deletions(-) diff --git a/cmd/chisel/cmd_info.go b/cmd/chisel/cmd_info.go index 4a08d969..a9fa826e 100644 --- a/cmd/chisel/cmd_info.go +++ b/cmd/chisel/cmd_info.go @@ -11,8 +11,9 @@ import ( "github.com/canonical/chisel/internal/setup" ) -var shortInfoHelp = "Show information about package slices" -var longInfoHelp = ` +var ( + shortInfoHelp = "Show information about package slices" + longInfoHelp = ` The info command shows detailed information about package slices. It accepts a whitespace-separated list of strings. The list can be @@ -23,6 +24,7 @@ the output is a list of YAML documents separated by a "---" line. Slice definitions are shown verbatim according to their definition in the selected release. For example, globs are not expanded. ` +) var infoDescs = map[string]string{ "release": "Chisel release name or directory (e.g. ubuntu-22.04)", @@ -83,7 +85,7 @@ func selectPackageSlices(release *setup.Release, queries []string) (packages []* allPkgSlices := make(map[string]bool) sliceExists := func(key setup.SliceKey) bool { - pkg, ok := release.Packages[key.RealName] + pkg, ok := release.Packages[key.Package] if !ok { return false } @@ -98,7 +100,7 @@ func selectPackageSlices(release *setup.Release, queries []string) (packages []* notFound = append(notFound, query) continue } - pkg, slice = key.RealName, key.Slice + pkg, slice = key.Package, key.Slice } else { if _, ok := release.Packages[query]; !ok { notFound = append(notFound, query) diff --git a/internal/apacheutil/util.go b/internal/apacheutil/util.go index 8beaf2be..ee98e55b 100644 --- a/internal/apacheutil/util.go +++ b/internal/apacheutil/util.go @@ -8,12 +8,12 @@ import ( ) type SliceKey struct { - RealName string - Slice string + Package string + Slice string } func (s SliceKey) String() string { - return s.RealName + "_" + s.Slice + return s.Package + "_" + s.Slice } // FnameExp matches the slice definition file basename. @@ -30,5 +30,5 @@ func ParseSliceKey(sliceKey string) (SliceKey, error) { if match == nil { return SliceKey{}, fmt.Errorf("invalid slice reference: %q", sliceKey) } - return SliceKey{RealName: match[1], Slice: match[2]}, nil + return SliceKey{Package: match[1], Slice: match[2]}, nil } diff --git a/internal/apacheutil/util_test.go b/internal/apacheutil/util_test.go index 4acab2cb..05f091c9 100644 --- a/internal/apacheutil/util_test.go +++ b/internal/apacheutil/util_test.go @@ -14,34 +14,34 @@ var sliceKeyTests = []struct { err string }{{ input: "foo_bar", - expected: apacheutil.SliceKey{RealName: "foo", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "foo", Slice: "bar"}, }, { input: "fo_bar", - expected: apacheutil.SliceKey{RealName: "fo", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "fo", Slice: "bar"}, }, { input: "1234_bar", - expected: apacheutil.SliceKey{RealName: "1234", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "1234", Slice: "bar"}, }, { input: "foo1.1-2-3_bar", - expected: apacheutil.SliceKey{RealName: "foo1.1-2-3", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "foo1.1-2-3", Slice: "bar"}, }, { input: "foo-pkg_dashed-slice-name", - expected: apacheutil.SliceKey{RealName: "foo-pkg", Slice: "dashed-slice-name"}, + expected: apacheutil.SliceKey{Package: "foo-pkg", Slice: "dashed-slice-name"}, }, { input: "foo+_bar", - expected: apacheutil.SliceKey{RealName: "foo+", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "foo+", Slice: "bar"}, }, { input: "foo_slice123", - expected: apacheutil.SliceKey{RealName: "foo", Slice: "slice123"}, + expected: apacheutil.SliceKey{Package: "foo", Slice: "slice123"}, }, { input: "g++_bins", - expected: apacheutil.SliceKey{RealName: "g++", Slice: "bins"}, + expected: apacheutil.SliceKey{Package: "g++", Slice: "bins"}, }, { input: "a+_bar", - expected: apacheutil.SliceKey{RealName: "a+", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "a+", Slice: "bar"}, }, { input: "a._bar", - expected: apacheutil.SliceKey{RealName: "a.", Slice: "bar"}, + expected: apacheutil.SliceKey{Package: "a.", Slice: "bar"}, }, { input: "foo_ba", err: `invalid slice reference: "foo_ba"`, @@ -99,13 +99,13 @@ var sliceKeyStringTests = []struct { key apacheutil.SliceKey expected string }{{ - key: apacheutil.SliceKey{RealName: "curl", Slice: "bins"}, + key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, expected: "curl_bins", }, { - key: apacheutil.SliceKey{RealName: "bin-curl", Slice: "bins"}, + key: apacheutil.SliceKey{Package: "bin-curl", Slice: "bins"}, expected: "bin-curl_bins", }, { - key: apacheutil.SliceKey{RealName: "bin-g++", Slice: "bins"}, + key: apacheutil.SliceKey{Package: "bin-g++", Slice: "bins"}, expected: "bin-g++_bins", }} @@ -115,25 +115,25 @@ func (s *S) TestSliceKeyString(c *C) { } } -var sliceKeyRealNameTests = []struct { +var sliceKeyPackageTests = []struct { key apacheutil.SliceKey expected string }{{ - key: apacheutil.SliceKey{RealName: "curl", Slice: "bins"}, + key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, expected: "curl", }, { - key: apacheutil.SliceKey{RealName: "bin-curl", Slice: "bins"}, + key: apacheutil.SliceKey{Package: "bin-curl", Slice: "bins"}, expected: "bin-curl", }, { - key: apacheutil.SliceKey{RealName: "bin-curl"}, + key: apacheutil.SliceKey{Package: "bin-curl"}, expected: "bin-curl", }, { - key: apacheutil.SliceKey{RealName: "curl"}, + key: apacheutil.SliceKey{Package: "curl"}, expected: "curl", }} -func (s *S) TestSliceKeyRealName(c *C) { - for _, test := range sliceKeyRealNameTests { - c.Assert(test.key.RealName, Equals, test.expected) +func (s *S) TestSliceKeyPackage(c *C) { + for _, test := range sliceKeyPackageTests { + c.Assert(test.key.Package, Equals, test.expected) } } diff --git a/internal/manifestutil/manifestutil.go b/internal/manifestutil/manifestutil.go index edc3616b..da9cc8b0 100644 --- a/internal/manifestutil/manifestutil.go +++ b/internal/manifestutil/manifestutil.go @@ -291,8 +291,8 @@ func Validate(mfest *manifest.Manifest) (err error) { if err != nil { return err } - if !pkgExist[sk.RealName] { - return fmt.Errorf("slice %s refers to missing package %q", slice.Name, sk.RealName) + if !pkgExist[sk.Package] { + return fmt.Errorf("slice %s refers to missing package %q", slice.Name, sk.Package) } sliceExist[slice.Name] = true return nil diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 119fba3e..73c6cc95 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -98,7 +98,7 @@ const ( GeneratePath PathKind = "generate" // TODO Maybe in the future, for binary support. - //Base64Path PathKind = "base64" + // Base64Path PathKind = "base64" ) type PathUntil string @@ -164,7 +164,7 @@ func realName(name, defaultPrefix string) string { } func (s *Slice) String() string { - return SliceKey{RealName: s.RealName(), Slice: s.Name}.String() + return SliceKey{Package: s.RealName(), Slice: s.Name}.String() } func (s *Slice) RealName() string { @@ -262,7 +262,7 @@ func (r *Release) validate() error { for _, pkg := range r.Packages { prefix := pkgDefaultPrefix(r, pkg) for _, new := range pkg.Slices { - keys = append(keys, SliceKey{RealName: realName(pkg.Name, prefix), Slice: new.Name}) + keys = append(keys, SliceKey{Package: realName(pkg.Name, prefix), Slice: new.Name}) newRealName := new.RealName() for newPath, newInfo := range new.Contents { if oldSlices, ok := paths[newPath]; ok { @@ -401,8 +401,8 @@ func (r *Release) validate() error { func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, error) { // Preprocess the list to improve error messages. for _, key := range keys { - if pkg, ok := pkgs[key.RealName]; !ok { - return nil, fmt.Errorf("slices of package %q not found", key.RealName) + if pkg, ok := pkgs[key.Package]; !ok { + return nil, fmt.Errorf("slices of package %q not found", key.Package) } else if _, ok := pkg.Slices[key.Slice]; !ok { return nil, fmt.Errorf("slice %s not found", key) } @@ -419,7 +419,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } seen[key] = true - pkg := pkgs[key.RealName] + pkg := pkgs[key.Package] slice := pkg.Slices[key.Slice] fqslice := slice.String() predecessors := successors[fqslice] @@ -428,7 +428,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, continue } fqreq := req.String() - if reqpkg, ok := pkgs[req.RealName]; !ok || reqpkg.Slices[req.Slice] == nil { + if reqpkg, ok := pkgs[req.Package]; !ok || reqpkg.Slices[req.Slice] == nil { return nil, fmt.Errorf("%s requires %s, but slice is missing", fqslice, fqreq) } predecessors = append(predecessors, fqreq) @@ -552,7 +552,7 @@ func Select(release *Release, slices []SliceKey, arch string) (*Selection, error } selection.Slices = make([]*Slice, len(sorted)) for i, key := range sorted { - selection.Slices[i] = release.Packages[key.RealName].Slices[key.Slice] + selection.Slices[i] = release.Packages[key.Package].Slices[key.Slice] } for _, new := range selection.Slices { diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index e8538213..7a5ee21d 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -158,7 +158,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "myslice1"}: {}, + {Package: "mypkg", Slice: "myslice1"}: {}, }, Contents: map[string]setup.PathInfo{ "/another/path": {Kind: "copy"}, @@ -421,7 +421,7 @@ var setupTests = []setupTest{{ myslice2: {essential: [mypkg1_myslice1]} `, }, - selslices: []setup.SliceKey{{RealName: "mypkg1", Slice: "myslice1"}}, + selslices: []setup.SliceKey{{Package: "mypkg1", Slice: "myslice1"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg1", @@ -444,7 +444,7 @@ var setupTests = []setupTest{{ myslice2: {essential: [mypkg1_myslice1]} `, }, - selslices: []setup.SliceKey{{RealName: "mypkg2", Slice: "myslice2"}}, + selslices: []setup.SliceKey{{Package: "mypkg2", Slice: "myslice2"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg1", @@ -453,7 +453,7 @@ var setupTests = []setupTest{{ Package: "mypkg2", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg1", Slice: "myslice1"}: {}, + {Package: "mypkg1", Slice: "myslice1"}: {}, }, }}, }, @@ -483,7 +483,7 @@ var setupTests = []setupTest{{ /path3: {symlink: /link} `, }, - selslices: []setup.SliceKey{{RealName: "mypkg1", Slice: "myslice1"}, {RealName: "mypkg1", Slice: "myslice2"}, {RealName: "mypkg2", Slice: "myslice1"}}, + selslices: []setup.SliceKey{{Package: "mypkg1", Slice: "myslice1"}, {Package: "mypkg1", Slice: "myslice2"}, {Package: "mypkg2", Slice: "myslice1"}}, }, { summary: "Conflicting paths across slices", input: map[string]string{ @@ -1472,7 +1472,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "slice2"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, }, }, "slice2": { @@ -1483,16 +1483,16 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice3", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "slice2"}: {}, - {RealName: "mypkg", Slice: "slice1"}: {}, - {RealName: "mypkg", Slice: "slice4"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, + {Package: "mypkg", Slice: "slice1"}: {}, + {Package: "mypkg", Slice: "slice4"}: {}, }, }, "slice4": { Package: "mypkg", Name: "slice4", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "slice2"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, }, }, }, @@ -1545,16 +1545,16 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "slice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "myotherpkg", Slice: "slice2"}: {}, - {RealName: "mypkg", Slice: "slice2"}: {}, - {RealName: "myotherpkg", Slice: "slice1"}: {}, + {Package: "myotherpkg", Slice: "slice2"}: {}, + {Package: "mypkg", Slice: "slice2"}: {}, + {Package: "myotherpkg", Slice: "slice1"}: {}, }, }, "slice2": { Package: "mypkg", Name: "slice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "myotherpkg", Slice: "slice2"}: {}, + {Package: "myotherpkg", Slice: "slice2"}: {}, }, }, }, @@ -1739,7 +1739,7 @@ var setupTests = []setupTest{{ EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), }, }, - selslices: []setup.SliceKey{{RealName: "mypkg", Slice: "myslice"}}, + selslices: []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}}, selection: &setup.Selection{ Slices: []*setup.Slice{{ Package: "mypkg", @@ -1792,7 +1792,7 @@ var setupTests = []setupTest{{ EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), }, }, - selslices: []setup.SliceKey{{RealName: "mypkg", Slice: "myslice"}}, + selslices: []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}}, selerror: `slice mypkg_myslice has invalid 'generate' for path /dir/\*\*: "foo"`, }, { summary: "Paths with generate: manifest must have trailing /**", @@ -2407,10 +2407,10 @@ var setupTests = []setupTest{{ }, { summary: "Path conflicts with 'prefer'", selslices: []setup.SliceKey{ - {RealName: "mypkg1", Slice: "myslice1"}, - {RealName: "mypkg1", Slice: "myslice2"}, - {RealName: "mypkg2", Slice: "myslice1"}, - {RealName: "mypkg3", Slice: "myslice1"}, + {Package: "mypkg1", Slice: "myslice1"}, + {Package: "mypkg1", Slice: "myslice2"}, + {Package: "mypkg2", Slice: "myslice1"}, + {Package: "mypkg3", Slice: "myslice1"}, }, input: map[string]string{ "slices/mydir/mypkg1.yaml": ` @@ -2514,9 +2514,9 @@ var setupTests = []setupTest{{ }, { summary: "Path conflicts with 'prefer' depends on selection", selslices: []setup.SliceKey{ - {RealName: "mypkg1", Slice: "myslice1"}, - {RealName: "mypkg1", Slice: "myslice2"}, - {RealName: "mypkg2", Slice: "myslice1"}, + {Package: "mypkg1", Slice: "myslice1"}, + {Package: "mypkg1", Slice: "myslice2"}, + {Package: "mypkg2", Slice: "myslice1"}, }, input: map[string]string{ "slices/mydir/mypkg1.yaml": ` @@ -3664,24 +3664,24 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice1", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "myslice2"}: {Arch: []string{"amd64"}}, - {RealName: "mypkg", Slice: "myslice3"}: {Arch: []string{"amd64", "arm64"}}, - {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, - {RealName: "mypkg", Slice: "myslice5"}: {Arch: nil}, + {Package: "mypkg", Slice: "myslice2"}: {Arch: []string{"amd64"}}, + {Package: "mypkg", Slice: "myslice3"}: {Arch: []string{"amd64", "arm64"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice5"}: {Arch: nil}, }, }, "myslice2": { Package: "mypkg", Name: "myslice2", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, "myslice3": { Package: "mypkg", Name: "myslice3", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, "myslice4": { @@ -3693,7 +3693,7 @@ var setupTests = []setupTest{{ Package: "mypkg", Name: "myslice5", Essential: map[setup.SliceKey]setup.EssentialInfo{ - {RealName: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, + {Package: "mypkg", Slice: "myslice4"}: {Arch: []string{"amd64", "i386"}}, }, }, }, @@ -4672,7 +4672,7 @@ func (s *S) TestSelectEmptyArch(c *C) { release, err := setup.ReadRelease(dir) c.Assert(err, IsNil) - selslice := []setup.SliceKey{{RealName: "mypkg", Slice: "myslice"}} + selslice := []setup.SliceKey{{Package: "mypkg", Slice: "myslice"}} selection, err := setup.Select(release, selslice, "") c.Assert(err, IsNil) diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index a08f4911..b1e2b6fe 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -496,7 +496,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != listEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{RealName: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{Package: pkgName, Slice: sliceName}) } } } else { @@ -508,10 +508,10 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.V3Essential != nil { - return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{RealName: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkgName, Slice: sliceName}) } if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{RealName: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkgName, Slice: sliceName}) } } } @@ -544,7 +544,7 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error return !unicode.IsPrint(r) }) if len(yamlSlice.Hint) > 40 || hintNotPrintable { - return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{RealName: pkgName, Slice: sliceName}, yamlSlice.Hint) + return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkgName, Slice: sliceName}, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, @@ -856,7 +856,7 @@ func parseEssentials(yamlPkg *yamlPackage, yamlSlice *yamlSlice, pkgPath string, if err != nil { return fmt.Errorf("package %q has invalid essential slice reference: %q", yamlPkg.Name, refName) } - if sliceKey.RealName == slice.RealName() && sliceKey.Slice == slice.Name { + if sliceKey.Package == slice.RealName() && sliceKey.Slice == slice.Name { // Do not add the slice to its own essentials list. return nil } @@ -878,7 +878,7 @@ func parseEssentials(yamlPkg *yamlPackage, yamlSlice *yamlSlice, pkgPath string, if err != nil { return fmt.Errorf("package %q has invalid essential slice reference: %q", yamlPkg.Name, refName) } - if sliceKey.RealName == slice.RealName() && sliceKey.Slice == slice.Name { + if sliceKey.Package == slice.RealName() && sliceKey.Slice == slice.Name { return fmt.Errorf("cannot add slice to itself as essential %s in %s", refName, pkgPath) } if _, ok := slice.Essential[sliceKey]; ok { diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index c6cdc92d..d11d8ca0 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -76,7 +76,7 @@ var testPackageCopyrightEntries = []testutil.TarEntry{ var slicerTests = []slicerTest{{ summary: "Basic slicing", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -109,7 +109,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Glob extraction", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -131,7 +131,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new file under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -151,7 +151,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new nested file under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -172,7 +172,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new directory under extracted directory and preserve parent directory permissions", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -192,7 +192,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Create new file using glob and preserve parent directory permissions", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -216,7 +216,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Conditional architecture", arch: "amd64", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -247,7 +247,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Copyright is not installed implicitly", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", // Add the copyright entries to the package. @@ -272,8 +272,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, - {RealName: "other-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, + {Package: "other-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -316,9 +316,9 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages, explicit path has preference over implicit parent", slices: []setup.SliceKey{ - {RealName: "a-implicit-parent", Slice: "myslice"}, - {RealName: "b-explicit-dir", Slice: "myslice"}, - {RealName: "c-implicit-parent", Slice: "myslice"}, + {Package: "a-implicit-parent", Slice: "myslice"}, + {Package: "b-explicit-dir", Slice: "myslice"}, + {Package: "c-implicit-parent", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "a-implicit-parent", @@ -376,8 +376,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Valid same file in two slices in different packages", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, - {RealName: "other-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, + {Package: "other-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -410,7 +410,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: write a file", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -431,7 +431,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: read a file", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -457,7 +457,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: use 'until' to remove file after mutate", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -481,7 +481,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: use 'until' to remove wildcard after mutate", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -499,7 +499,7 @@ var slicerTests = []slicerTest{{ manifestPaths: map[string]string{}, }, { summary: "Script: 'until' does not remove non-empty directories", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -520,7 +520,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: writing same contents to existing file does not set the final hash in report", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -541,7 +541,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Script: cannot write non-mutable files", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -556,7 +556,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/text-file`, }, { summary: "Script: cannot write to unlisted file", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -570,7 +570,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/text-file`, }, { summary: "Script: cannot write to directory", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -585,7 +585,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot write file which is not mutable: /dir/`, }, { summary: "Script: cannot read unlisted content", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice2"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice2"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -601,7 +601,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice2: cannot read file which is not selected: /dir/text-file`, }, { summary: "Script: can read globbed content", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice1"}, {RealName: "test-package", Slice: "myslice2"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice1"}, {Package: "test-package", Slice: "myslice2"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -616,7 +616,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Relative content root directory must not error", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -637,7 +637,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Can list parent directories of normal paths", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -656,7 +656,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot list unselected directory", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -671,7 +671,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot list directory which is not selected: /a/d/`, }, { summary: "Cannot list file path as a directory", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -686,7 +686,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: content is not a directory: /a/b/c`, }, { summary: "Can list parent directories of globs", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -700,7 +700,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot list directories not matched by glob", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -715,7 +715,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: cannot list directory which is not selected: /other-dir/`, }, { summary: "Duplicate copyright symlink is ignored", - slices: []setup.SliceKey{{RealName: "copyright-symlink-openssl", Slice: "bins"}}, + slices: []setup.SliceKey{{Package: "copyright-symlink-openssl", Slice: "bins"}}, pkgs: []*testutil.TestPackage{{ Name: "copyright-symlink-openssl", Data: testutil.MustMakeDeb(packageEntries["copyright-symlink-openssl"]), @@ -747,7 +747,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Can list unclean directory paths", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -766,7 +766,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Cannot read directories", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -781,7 +781,7 @@ var slicerTests = []slicerTest{{ error: `slice test-package_myslice: content is not a file: /x/y`, }, { summary: "Multiple archives with priority", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}, {RealName: "other-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}, {Package: "other-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", @@ -865,7 +865,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Pinned archive bypasses higher priority", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", @@ -933,7 +933,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Pinned archive does not have the package", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -979,7 +979,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "No archives have the package", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{}, release: map[string]string{ "chisel.yaml": ` @@ -1016,7 +1016,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "Negative priority archives are ignored when not explicitly pinned in package", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1053,7 +1053,7 @@ var slicerTests = []slicerTest{{ error: `cannot find package "test-package" in archive\(s\)`, }, { summary: "Negative priority archive explicitly pinned in package", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Hash: "h1", @@ -1103,8 +1103,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Multiple slices of same package", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice1"}, - {RealName: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1141,8 +1141,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Same glob in several entries with until:mutate and reading from script", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice1"}, - {RealName: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1187,8 +1187,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping globs, until:mutate and reading from script", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice2"}, - {RealName: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1233,8 +1233,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on entry and reading from script", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice1"}, - {RealName: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1279,8 +1279,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on glob and reading from script", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice1"}, - {RealName: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1308,8 +1308,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Overlapping glob and single entry, until:mutate on both and reading from script", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice1"}, - {RealName: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1332,8 +1332,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Content not created in packages with until:mutate on one and reading from script", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice1"}, - {RealName: "test-package", Slice: "myslice2"}, + {Package: "test-package", Slice: "myslice1"}, + {Package: "test-package", Slice: "myslice2"}, }, release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1356,8 +1356,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Install two packages, both are recorded", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, - {RealName: "other-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, + {Package: "other-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1393,7 +1393,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Two packages, only one is selected and recorded", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1427,7 +1427,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Relative paths are properly trimmed during extraction", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1458,7 +1458,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Producing a manifest is not mandatory", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, hackopt: func(c *C, opts *slicer.RunOptions) { // Remove the manifest slice that the tests add automatically. var index int @@ -1480,7 +1480,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "No valid archives defined due to invalid pro value", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, release: map[string]string{ "chisel.yaml": ` format: v1 @@ -1507,8 +1507,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Valid hard link in two slices in the same package", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "slice1"}, - {RealName: "test-package", Slice: "slice2"}, + {Package: "test-package", Slice: "slice1"}, + {Package: "test-package", Slice: "slice2"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1542,7 +1542,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link entries can be extracted without extracting the regular file", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1573,7 +1573,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link identifier for different groups", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1609,7 +1609,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Single hard link entry can be extracted without regular file and no hard links are created", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1637,7 +1637,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link to symlink does not follow symlink", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1670,8 +1670,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard link identifiers are unique across packages", slices: []setup.SliceKey{ - {RealName: "test-package1", Slice: "myslice"}, - {RealName: "test-package2", Slice: "myslice"}, + {Package: "test-package1", Slice: "myslice"}, + {Package: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", @@ -1721,7 +1721,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Mutations for hard links are forbidden", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1747,7 +1747,7 @@ var slicerTests = []slicerTest{{ }, { summary: "Hard links can be marked as mutable, but not mutated", slices: []setup.SliceKey{ - {RealName: "test-package", Slice: "myslice"}, + {Package: "test-package", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package", @@ -1777,7 +1777,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Hard links cannot escape the target directory", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1797,7 +1797,7 @@ var slicerTests = []slicerTest{{ error: `cannot extract from package "test-package": invalid link target /etc/group`, }, { summary: "Cannot extract outside of target directory", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, pkgs: []*testutil.TestPackage{{ Name: "test-package", Data: testutil.MustMakeDeb([]testutil.TarEntry{ @@ -1818,8 +1818,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Extract conflicting paths with prefer from proper package", slices: []setup.SliceKey{ - {RealName: "test-package1", Slice: "myslice"}, - {RealName: "test-package2", Slice: "myslice"}, + {Package: "test-package1", Slice: "myslice"}, + {Package: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", @@ -1879,8 +1879,8 @@ var slicerTests = []slicerTest{{ }, { summary: "Warning when implicit parent directories conflict", slices: []setup.SliceKey{ - {RealName: "test-package1", Slice: "myslice"}, - {RealName: "test-package2", Slice: "myslice"}, + {Package: "test-package1", Slice: "myslice"}, + {Package: "test-package2", Slice: "myslice"}, }, pkgs: []*testutil.TestPackage{{ Name: "test-package1", @@ -1918,7 +1918,7 @@ var slicerTests = []slicerTest{{ logOutput: `(?s).*Warning: Path "/parent/" has diverging modes in different packages\. Please report\..*`, }, { summary: "Arch specific slice is not installed when it does not match requested arch", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, arch: "amd64", release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1937,7 +1937,7 @@ var slicerTests = []slicerTest{{ manifestPaths: map[string]string{}, }, { summary: "Arch specific slice is installed when it matches requested arch", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "myslice"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "myslice"}}, arch: "arm64", release: map[string]string{ "slices/mydir/test-package.yaml": ` @@ -1961,7 +1961,7 @@ var slicerTests = []slicerTest{{ }, }, { summary: "Transitive essential", - slices: []setup.SliceKey{{RealName: "test-package", Slice: "first"}}, + slices: []setup.SliceKey{{Package: "test-package", Slice: "first"}}, release: map[string]string{ "slices/mydir/test-package.yaml": ` package: test-package @@ -2067,7 +2067,7 @@ func runSlicerTests(s *S, c *C, tests []slicerTest) { c.Assert(err, IsNil) // Create a manifest slice and add it to the selection. - manifestPackage := test.slices[0].RealName + manifestPackage := test.slices[0].Package manifestPath := "/chisel-data/manifest.wall" release.Packages[manifestPackage].Slices["manifest"] = &setup.Slice{ Package: manifestPackage, @@ -2082,8 +2082,8 @@ func runSlicerTests(s *S, c *C, tests []slicerTest) { Scripts: setup.SliceScripts{}, } testSlices = append(testSlices, setup.SliceKey{ - RealName: manifestPackage, - Slice: "manifest", + Package: manifestPackage, + Slice: "manifest", }) selection, err := setup.Select(release, testSlices, test.arch) From 36cfe36ca31d806507b9d839ec08ccbc04076fbe Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 14:15:23 +0200 Subject: [PATCH 09/16] fix: more renaming Signed-off-by: Paul Mars --- internal/setup/setup.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 73c6cc95..d1a30638 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -584,32 +584,32 @@ type preferKey struct { func (r *Release) prefers() (map[preferKey]string, error) { prefers := make(map[preferKey]string) - for mapKey, pkg := range r.Packages { + for realName, pkg := range r.Packages { for _, slice := range pkg.Slices { for path, info := range slice.Contents { if info.Prefer != "" { if _, ok := r.Packages[info.Prefer]; !ok { return nil, fmt.Errorf("slice %s path %s 'prefer' refers to undefined package %q", slice, path, info.Prefer) } - tkey := preferKey{preferTarget, path, mapKey} + tkey := preferKey{preferTarget, path, realName} skey := preferKey{preferSource, path, info.Prefer} if target, ok := prefers[tkey]; ok { if target != info.Prefer { pkg1, pkg2 := sortPair(target, info.Prefer) return nil, fmt.Errorf("package %q has conflicting prefers for %s: %s != %s", - mapKey, path, pkg1, pkg2) + realName, path, pkg1, pkg2) } } else if source, ok := prefers[skey]; ok { - if source != mapKey { - pkg1, pkg2 := sortPair(source, mapKey) + if source != realName { + pkg1, pkg2 := sortPair(source, realName) return nil, fmt.Errorf("packages %q and %q cannot both prefer %q for %s", pkg1, pkg2, info.Prefer, path) } } else { prefers[tkey] = info.Prefer - prefers[skey] = mapKey + prefers[skey] = realName // Sample package that requires this path to be in a prefer relationship. - prefers[preferKey{preferSource, path, ""}] = mapKey + prefers[preferKey{preferSource, path, ""}] = realName } } } From 10126aeae51762a89312fadcaab517ee7f2c418e Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 14:51:39 +0200 Subject: [PATCH 10/16] fix: improve name displayed Signed-off-by: Paul Mars --- internal/setup/setup.go | 11 ++------ internal/setup/yaml.go | 62 ++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/internal/setup/setup.go b/internal/setup/setup.go index d1a30638..0fa7086f 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -501,20 +501,13 @@ func readSlices(release *Release, baseDir, dirName string) error { return fmt.Errorf("cannot read slice definition file: %v", err) } - pkg, err := parsePackage(release.Format, pkgName, stripBase(baseDir, pkgPath), data) + pkg, err := parsePackage(release, pkgName, stripBase(baseDir, pkgPath), data) if err != nil { return err } - // Derive the package DefaultPrefix from its store reference. - prefix := pkgDefaultPrefix(release, pkg) - - // Set DefaultPrefix on all slices in the package. - for _, slice := range pkg.Slices { - slice.DefaultPrefix = prefix - } - // Use the real name for the Packages map. + prefix := pkgDefaultPrefix(release, pkg) pkgRealName := realName(pkg.Name, prefix) if existing, ok := release.Packages[pkgRealName]; ok { return fmt.Errorf("package %q slices defined more than once: %s and %s", pkgName, existing.Path, stripBase(baseDir, pkgPath)) diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index b1e2b6fe..edb24981 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -472,7 +472,7 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { return release, err } -func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error) { +func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Package, error) { pkg := Package{ Name: pkgName, Path: pkgPath, @@ -490,7 +490,30 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error return nil, fmt.Errorf("%s: filename and 'package' field (%q) disagree", pkgPath, yamlPkg.Name) } - if format == "v1" || format == "v2" { + if yamlPkg.Store != "" && yamlPkg.Archive != "" { + return nil, fmt.Errorf("cannot parse package %q: both 'store' and 'archive' fields are set", pkgName) + } + if yamlPkg.Store != "" { + if yamlPkg.DefaultTrack == "" { + return nil, fmt.Errorf("cannot parse package %q: 'default-track' is required when 'store' is set", pkgName) + } + if strings.Contains(yamlPkg.DefaultTrack, "/") { + return nil, fmt.Errorf("cannot parse package %q: 'default-track' must be a track name without /", pkgName) + } + pkg.Store = yamlPkg.Store + pkg.DefaultTrack = yamlPkg.DefaultTrack + } else { + if yamlPkg.DefaultTrack != "" { + return nil, fmt.Errorf("cannot parse package %q: 'store' is required when 'default-track' is set", pkgName) + } + } + pkg.Archive = yamlPkg.Archive + + // Derive the package DefaultPrefix from its store reference. + prefix := pkgDefaultPrefix(release, &pkg) + pkgRealName := realName(pkgName, prefix) + + if release.Format == "v1" || release.Format == "v2" { if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != listEssential { return nil, fmt.Errorf("cannot parse package %q: essential expects a list", pkgName) } @@ -501,39 +524,21 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error } } else { if yamlPkg.V3Essential != nil { - return nil, fmt.Errorf("cannot parse package %q: v3-essential is obsolete since format v3", pkgName) + return nil, fmt.Errorf("cannot parse package %q: v3-essential is obsolete since format v3", pkgRealName) } if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse package %q: essential expects a map", pkgName) + return nil, fmt.Errorf("cannot parse package %q: essential expects a map", pkgRealName) } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.V3Essential != nil { - return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkgRealName, Slice: sliceName}) } if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkgRealName, Slice: sliceName}) } } } - if yamlPkg.Store != "" && yamlPkg.Archive != "" { - return nil, fmt.Errorf("cannot parse package %q: both 'store' and 'archive' fields are set", pkgName) - } - if yamlPkg.Store != "" { - if yamlPkg.DefaultTrack == "" { - return nil, fmt.Errorf("cannot parse package %q: 'default-track' is required when 'store' is set", pkgName) - } - if strings.Contains(yamlPkg.DefaultTrack, "/") { - return nil, fmt.Errorf("cannot parse package %q: 'default-track' must be a track name without /", pkgName) - } - pkg.Store = yamlPkg.Store - pkg.DefaultTrack = yamlPkg.DefaultTrack - } else { - if yamlPkg.DefaultTrack != "" { - return nil, fmt.Errorf("cannot parse package %q: 'store' is required when 'default-track' is set", pkgName) - } - } - pkg.Archive = yamlPkg.Archive zeroPath := yamlPath{} for sliceName, yamlSlice := range yamlPkg.Slices { match := apacheutil.SnameExp.FindStringSubmatch(sliceName) @@ -544,12 +549,13 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error return !unicode.IsPrint(r) }) if len(yamlSlice.Hint) > 40 || hintNotPrintable { - return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkgName, Slice: sliceName}, yamlSlice.Hint) + return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkgRealName, Slice: sliceName}, yamlSlice.Hint) } slice := &Slice{ - Package: pkgName, - Name: sliceName, - Hint: yamlSlice.Hint, + Package: pkgName, + DefaultPrefix: prefix, + Name: sliceName, + Hint: yamlSlice.Hint, Scripts: SliceScripts{ Mutate: yamlSlice.Mutate, }, From dac4903cb3dd70e7d9ea0cd34d950d7f568af816 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 15:23:20 +0200 Subject: [PATCH 11/16] fix: refine naming Signed-off-by: Paul Mars --- internal/apacheutil/util.go | 6 +- internal/apacheutil/util_test.go | 43 ------- internal/setup/setup.go | 37 ++---- internal/setup/setup_test.go | 214 ++++++++++++++++++------------- internal/setup/yaml.go | 18 +-- internal/slicer/slicer.go | 10 +- 6 files changed, 156 insertions(+), 172 deletions(-) diff --git a/internal/apacheutil/util.go b/internal/apacheutil/util.go index ee98e55b..7e0f8e6d 100644 --- a/internal/apacheutil/util.go +++ b/internal/apacheutil/util.go @@ -12,9 +12,7 @@ type SliceKey struct { Slice string } -func (s SliceKey) String() string { - return s.Package + "_" + s.Slice -} +func (s SliceKey) String() string { return s.Package + "_" + s.Slice } // FnameExp matches the slice definition file basename. var FnameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})\.yaml$`) @@ -30,5 +28,5 @@ func ParseSliceKey(sliceKey string) (SliceKey, error) { if match == nil { return SliceKey{}, fmt.Errorf("invalid slice reference: %q", sliceKey) } - return SliceKey{Package: match[1], Slice: match[2]}, nil + return SliceKey{match[1], match[2]}, nil } diff --git a/internal/apacheutil/util_test.go b/internal/apacheutil/util_test.go index 05f091c9..6289473c 100644 --- a/internal/apacheutil/util_test.go +++ b/internal/apacheutil/util_test.go @@ -94,46 +94,3 @@ func (s *S) TestParseSliceKey(c *C) { c.Assert(key, DeepEquals, test.expected) } } - -var sliceKeyStringTests = []struct { - key apacheutil.SliceKey - expected string -}{{ - key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, - expected: "curl_bins", -}, { - key: apacheutil.SliceKey{Package: "bin-curl", Slice: "bins"}, - expected: "bin-curl_bins", -}, { - key: apacheutil.SliceKey{Package: "bin-g++", Slice: "bins"}, - expected: "bin-g++_bins", -}} - -func (s *S) TestSliceKeyString(c *C) { - for _, test := range sliceKeyStringTests { - c.Assert(test.key.String(), Equals, test.expected) - } -} - -var sliceKeyPackageTests = []struct { - key apacheutil.SliceKey - expected string -}{{ - key: apacheutil.SliceKey{Package: "curl", Slice: "bins"}, - expected: "curl", -}, { - key: apacheutil.SliceKey{Package: "bin-curl", Slice: "bins"}, - expected: "bin-curl", -}, { - key: apacheutil.SliceKey{Package: "bin-curl"}, - expected: "bin-curl", -}, { - key: apacheutil.SliceKey{Package: "curl"}, - expected: "curl", -}} - -func (s *S) TestSliceKeyPackage(c *C) { - for _, test := range sliceKeyPackageTests { - c.Assert(test.key.Package, Equals, test.expected) - } -} diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 0fa7086f..b4c7f23d 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -60,6 +60,7 @@ type Archive struct { // Package holds a collection of slices that represent parts of themselves. type Package struct { + RealName string Name string Path string Archive string @@ -157,17 +158,11 @@ func pkgDefaultPrefix(release *Release, pkg *Package) string { return store.DefaultPrefix } -// realName returns the real name for a package used as the -// Release.Packages map key. -func realName(name, defaultPrefix string) string { - return defaultPrefix + name -} - func (s *Slice) String() string { - return SliceKey{Package: s.RealName(), Slice: s.Name}.String() + return SliceKey{Package: s.RealPkgName(), Slice: s.Name}.String() } -func (s *Slice) RealName() string { +func (s *Slice) RealPkgName() string { return s.DefaultPrefix + s.Package } @@ -196,13 +191,13 @@ func (s *Selection) Prefers() (map[string]*Package, error) { if !hasPrefers { continue } - sRealName := slice.RealName() + sRealName := slice.RealPkgName() old, ok := pathPreferredPkg[path] if !ok { pathPreferredPkg[path] = s.Release.Packages[sRealName] continue } - oldRealName := realName(old.Name, pkgDefaultPrefix(s.Release, old)) + oldRealName := old.RealName if oldRealName == sRealName { // Skip if the package was already recorded. continue @@ -260,14 +255,13 @@ func (r *Release) validate() error { // cannot validate that they are the same without downloading the package. paths := make(map[string][]*Slice) for _, pkg := range r.Packages { - prefix := pkgDefaultPrefix(r, pkg) for _, new := range pkg.Slices { - keys = append(keys, SliceKey{Package: realName(pkg.Name, prefix), Slice: new.Name}) - newRealName := new.RealName() + keys = append(keys, SliceKey{Package: pkg.RealName, Slice: new.Name}) + newRealName := new.RealPkgName() for newPath, newInfo := range new.Contents { if oldSlices, ok := paths[newPath]; ok { for _, old := range oldSlices { - oldRealName := old.RealName() + oldRealName := old.RealPkgName() if newRealName != oldRealName { _, err := preferredPathPackage(newPath, newRealName, oldRealName, prefers) if err == nil { @@ -302,7 +296,7 @@ func (r *Release) validate() error { found := false for _, slice := range paths[skey.path] { - if slice.RealName() == skey.pkg { + if slice.RealPkgName() == skey.pkg { found = true break } @@ -327,8 +321,8 @@ func (r *Release) validate() error { } for _, new := range newSlices { newInfo := new.Contents[newPath] - newRealName := new.RealName() - oldRealName := old.RealName() + newRealName := new.RealPkgName() + oldRealName := old.RealPkgName() if oldInfo.Kind == GlobPath && (newInfo.Kind == GlobPath || newInfo.Kind == CopyPath) { if newRealName == oldRealName { continue @@ -506,13 +500,10 @@ func readSlices(release *Release, baseDir, dirName string) error { return err } - // Use the real name for the Packages map. - prefix := pkgDefaultPrefix(release, pkg) - pkgRealName := realName(pkg.Name, prefix) - if existing, ok := release.Packages[pkgRealName]; ok { - return fmt.Errorf("package %q slices defined more than once: %s and %s", pkgName, existing.Path, stripBase(baseDir, pkgPath)) + if existing, ok := release.Packages[pkg.RealName]; ok { + return fmt.Errorf("package %q slices defined more than once: %s and %s", pkg.RealName, existing.Path, stripBase(baseDir, pkgPath)) } - release.Packages[pkgRealName] = pkg + release.Packages[pkg.RealName] = pkg } return nil } diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 7a5ee21d..165fc1dc 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -92,9 +92,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -139,8 +140,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -204,8 +206,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -270,9 +273,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -327,9 +331,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -582,8 +587,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -800,8 +806,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -843,8 +850,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -887,8 +895,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -960,9 +969,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -1166,8 +1176,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -1241,9 +1252,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -1354,8 +1366,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "jq": { - Name: "jq", - Path: "slices/mydir/jq.yaml", + RealName: "jq", + Name: "jq", + Path: "slices/mydir/jq.yaml", Slices: map[string]*setup.Slice{ "bins": { Package: "jq", @@ -1465,8 +1478,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "slice1": { Package: "mypkg", @@ -1538,8 +1552,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "slice1": { Package: "mypkg", @@ -1560,8 +1575,9 @@ var setupTests = []setupTest{{ }, }, "myotherpkg": { - Name: "myotherpkg", - Path: "slices/mydir/myotherpkg.yaml", + RealName: "myotherpkg", + Name: "myotherpkg", + Path: "slices/mydir/myotherpkg.yaml", Slices: map[string]*setup.Slice{ "slice1": { Package: "myotherpkg", @@ -1721,8 +1737,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -1774,8 +1791,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -1869,8 +1887,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg", @@ -1882,8 +1901,9 @@ var setupTests = []setupTest{{ }, }, "mypkg2": { - Name: "mypkg2", - Path: "slices/mydir/mypkg2.yaml", + RealName: "mypkg2", + Name: "mypkg2", + Path: "slices/mydir/mypkg2.yaml", Slices: map[string]*setup.Slice{ "myslice": { Package: "mypkg2", @@ -2040,9 +2060,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -2166,9 +2187,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -2233,9 +2255,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -2328,9 +2351,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -2454,8 +2478,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg1": { - Name: "mypkg1", - Path: "slices/mydir/mypkg1.yaml", + RealName: "mypkg1", + Name: "mypkg1", + Path: "slices/mydir/mypkg1.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg1", @@ -2475,8 +2500,9 @@ var setupTests = []setupTest{{ }, }, "mypkg2": { - Name: "mypkg2", - Path: "slices/mydir/mypkg2.yaml", + RealName: "mypkg2", + Name: "mypkg2", + Path: "slices/mydir/mypkg2.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg2", @@ -2489,8 +2515,9 @@ var setupTests = []setupTest{{ }, }, "mypkg3": { - Name: "mypkg3", - Path: "slices/mydir/mypkg3.yaml", + RealName: "mypkg3", + Name: "mypkg3", + Path: "slices/mydir/mypkg3.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg3", @@ -2889,9 +2916,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -2939,9 +2967,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -3128,9 +3157,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -3250,9 +3280,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -3372,9 +3403,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -3494,9 +3526,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -3614,9 +3647,10 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", - Slices: map[string]*setup.Slice{}, + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, }, }, Maintenance: &setup.Maintenance{ @@ -3657,8 +3691,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "mypkg": { - Name: "mypkg", - Path: "slices/mydir/mypkg.yaml", + RealName: "mypkg", + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", Slices: map[string]*setup.Slice{ "myslice1": { Package: "mypkg", @@ -3948,6 +3983,7 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "bin-mypkg": { + RealName: "bin-mypkg", Name: "mypkg", Path: "slices/bin/mypkg.yaml", Store: "bin", @@ -4125,8 +4161,9 @@ var setupTests = []setupTest{{ }, Packages: map[string]*setup.Package{ "curl": { - Name: "curl", - Path: "slices/curl.yaml", + RealName: "curl", + Name: "curl", + Path: "slices/curl.yaml", Slices: map[string]*setup.Slice{ "libs": { Package: "curl", @@ -4147,6 +4184,7 @@ var setupTests = []setupTest{{ }, }, "bin-curl": { + RealName: "bin-curl", Name: "curl", Path: "slices/bin/curl.yaml", Store: "bin", diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index edb24981..31ead760 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -511,7 +511,7 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack // Derive the package DefaultPrefix from its store reference. prefix := pkgDefaultPrefix(release, &pkg) - pkgRealName := realName(pkgName, prefix) + pkg.RealName = prefix + pkgName if release.Format == "v1" || release.Format == "v2" { if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != listEssential { @@ -519,22 +519,22 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != listEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{Package: pkgName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{Package: pkg.RealName, Slice: sliceName}) } } } else { if yamlPkg.V3Essential != nil { - return nil, fmt.Errorf("cannot parse package %q: v3-essential is obsolete since format v3", pkgRealName) + return nil, fmt.Errorf("cannot parse package %q: v3-essential is obsolete since format v3", pkg.RealName) } if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse package %q: essential expects a map", pkgRealName) + return nil, fmt.Errorf("cannot parse package %q: essential expects a map", pkg.RealName) } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.V3Essential != nil { - return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkgRealName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{Package: pkg.RealName, Slice: sliceName}) } if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != mapEssential { - return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkgRealName, Slice: sliceName}) + return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{Package: pkg.RealName, Slice: sliceName}) } } } @@ -549,7 +549,7 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack return !unicode.IsPrint(r) }) if len(yamlSlice.Hint) > 40 || hintNotPrintable { - return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkgRealName, Slice: sliceName}, yamlSlice.Hint) + return nil, fmt.Errorf("slice %s has invalid hint %q (must be len <= 40, only contain letters, numbers, symbols and \" \")", SliceKey{Package: pkg.RealName, Slice: sliceName}, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, @@ -862,7 +862,7 @@ func parseEssentials(yamlPkg *yamlPackage, yamlSlice *yamlSlice, pkgPath string, if err != nil { return fmt.Errorf("package %q has invalid essential slice reference: %q", yamlPkg.Name, refName) } - if sliceKey.Package == slice.RealName() && sliceKey.Slice == slice.Name { + if sliceKey.Package == slice.RealPkgName() && sliceKey.Slice == slice.Name { // Do not add the slice to its own essentials list. return nil } @@ -884,7 +884,7 @@ func parseEssentials(yamlPkg *yamlPackage, yamlSlice *yamlSlice, pkgPath string, if err != nil { return fmt.Errorf("package %q has invalid essential slice reference: %q", yamlPkg.Name, refName) } - if sliceKey.Package == slice.RealName() && sliceKey.Slice == slice.Name { + if sliceKey.Package == slice.RealPkgName() && sliceKey.Slice == slice.Name { return fmt.Errorf("cannot add slice to itself as essential %s in %s", refName, pkgPath) } if _, ok := slice.Essential[sliceKey]; ok { diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index f0ac9b6c..887a577e 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -110,7 +110,7 @@ func Run(options *RunOptions) error { // Build information to process the selection. extract := make(map[string]map[string][]deb.ExtractInfo) for _, slice := range options.Selection.Slices { - realName := slice.RealName() + realName := slice.RealPkgName() extractPackage := extract[realName] if extractPackage == nil { extractPackage = make(map[string][]deb.ExtractInfo) @@ -157,7 +157,7 @@ func Run(options *RunOptions) error { packages := make(map[string]io.ReadSeekCloser) var pkgInfos []*archive.PackageInfo for _, slice := range options.Selection.Slices { - realName := slice.RealName() + realName := slice.RealPkgName() if packages[realName] != nil { continue } @@ -243,7 +243,7 @@ func Run(options *RunOptions) error { // Extract all packages, also using the selection order. for _, slice := range options.Selection.Slices { - realName := slice.RealName() + realName := slice.RealPkgName() reader := packages[realName] if reader == nil { continue @@ -279,7 +279,7 @@ func Run(options *RunOptions) error { // them to the appropriate slices. relPaths := map[string][]*setup.Slice{} for _, slice := range options.Selection.Slices { - arch := pkgArch[slice.RealName()] + arch := pkgArch[slice.RealPkgName()] for relPath, pathInfo := range slice.Contents { if len(pathInfo.Arch) > 0 && !slices.Contains(pathInfo.Arch, arch) { continue @@ -519,7 +519,7 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel pkgArchive := make(map[string]archive.Archive) for _, s := range selection.Slices { - realName := s.RealName() + realName := s.RealPkgName() if _, ok := pkgArchive[realName]; ok { continue } From dd7f8d8606615614339caaa6f5cd60839f7fef9d Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 15:28:44 +0200 Subject: [PATCH 12/16] fix: add missing check on format Signed-off-by: Paul Mars --- internal/setup/yaml.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index 31ead760..b0dd52e1 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -490,6 +490,9 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack return nil, fmt.Errorf("%s: filename and 'package' field (%q) disagree", pkgPath, yamlPkg.Name) } + if (yamlPkg.Store != "" || yamlPkg.DefaultTrack != "") && (release.Format == "v1" || release.Format == "v2") { + return nil, fmt.Errorf("cannot parse package %q: 'store' and 'default-track' are not supported in format %q", pkgName, release.Format) + } if yamlPkg.Store != "" && yamlPkg.Archive != "" { return nil, fmt.Errorf("cannot parse package %q: both 'store' and 'archive' fields are set", pkgName) } From 52747b2ca40f3c6266dad7e26bbc01ec8ed24c4c Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 15:44:13 +0200 Subject: [PATCH 13/16] fix: remove pkgDefaultPrefix Signed-off-by: Paul Mars --- internal/setup/setup.go | 12 ---- internal/setup/setup_test.go | 113 +++++++++++++++++++++++++++++++++-- internal/setup/yaml.go | 9 ++- 3 files changed, 116 insertions(+), 18 deletions(-) diff --git a/internal/setup/setup.go b/internal/setup/setup.go index b4c7f23d..dbc80ae4 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -146,18 +146,6 @@ func ParseSliceKey(sliceKey string) (SliceKey, error) { return apacheutil.ParseSliceKey(sliceKey) } -// pkgDefaultPrefix returns the DefaultPrefix for a package based on its store reference. -func pkgDefaultPrefix(release *Release, pkg *Package) string { - if pkg.Store == "" { - return "" - } - store := release.Stores[pkg.Store] - if store == nil { - return "" - } - return store.DefaultPrefix -} - func (s *Slice) String() string { return SliceKey{Package: s.RealPkgName(), Slice: s.Name}.String() } diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 165fc1dc..17586b2b 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -3999,6 +3999,27 @@ var setupTests = []setupTest{{ }, { summary: "Store and archive are mutually exclusive", input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, "slices/bin/mypkg.yaml": ` package: mypkg archive: ubuntu @@ -4008,8 +4029,29 @@ var setupTests = []setupTest{{ }, relerror: `cannot parse package "mypkg": both 'store' and 'archive' fields are set`, }, { - summary: "Store package missing default-track", + summary: "Store package missing default-track (v3)", input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, "slices/bin/mypkg.yaml": ` package: mypkg store: bin @@ -4017,8 +4059,29 @@ var setupTests = []setupTest{{ }, relerror: `cannot parse package "mypkg": 'default-track' is required when 'store' is set`, }, { - summary: "default-track without store", + summary: "default-track without store (v3)", input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, "slices/bin/mypkg.yaml": ` package: mypkg default-track: "3.0" @@ -4026,8 +4089,29 @@ var setupTests = []setupTest{{ }, relerror: `cannot parse package "mypkg": 'store' is required when 'default-track' is set`, }, { - summary: "default-track must not contain /", + summary: "default-track must not contain / (v3)", input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, "slices/bin/mypkg.yaml": ` package: mypkg store: bin @@ -4036,8 +4120,29 @@ var setupTests = []setupTest{{ }, relerror: `cannot parse package "mypkg": 'default-track' must be a track name without /`, }, { - summary: "Package store references undefined store", + summary: "Package store references undefined store (v3)", input: map[string]string{ + "chisel.yaml": ` + format: v3 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 26.10 + components: [main, universe] + suites: [stonking] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + stores: + bin: + kind: bin + version: 26.10 + default-prefix: "bin-" + `, "slices/bin/mypkg.yaml": ` package: mypkg store: no-such-store diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index b0dd52e1..1418e0b8 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -510,10 +510,14 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack return nil, fmt.Errorf("cannot parse package %q: 'store' is required when 'default-track' is set", pkgName) } } - pkg.Archive = yamlPkg.Archive // Derive the package DefaultPrefix from its store reference. - prefix := pkgDefaultPrefix(release, &pkg) + var prefix string + if pkg.Store != "" { + if store := release.Stores[pkg.Store]; store != nil { + prefix = store.DefaultPrefix + } + } pkg.RealName = prefix + pkgName if release.Format == "v1" || release.Format == "v2" { @@ -542,6 +546,7 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack } } + pkg.Archive = yamlPkg.Archive zeroPath := yamlPath{} for sliceName, yamlSlice := range yamlPkg.Slices { match := apacheutil.SnameExp.FindStringSubmatch(sliceName) From dc9f12067162b77a2c3d8f0261c9c654fd52575c Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 15:48:18 +0200 Subject: [PATCH 14/16] fix: consistent use of pkg.RealName Signed-off-by: Paul Mars --- internal/setup/yaml.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index 1418e0b8..f13232ee 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -522,7 +522,7 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack if release.Format == "v1" || release.Format == "v2" { if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != listEssential { - return nil, fmt.Errorf("cannot parse package %q: essential expects a list", pkgName) + return nil, fmt.Errorf("cannot parse package %q: essential expects a list", pkg.RealName) } for sliceName, yamlSlice := range yamlPkg.Slices { if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != listEssential { @@ -598,17 +598,17 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack zeroPathGenerate.Generate = yamlPath.Generate if !yamlPath.SameContent(&zeroPathGenerate) || yamlPath.Prefer != "" || yamlPath.Until != UntilNone { return nil, fmt.Errorf("slice %s_%s path %s has invalid generate options", - pkgName, sliceName, contPath) + pkg.RealName, sliceName, contPath) } if _, err := validateGeneratePath(contPath); err != nil { - return nil, fmt.Errorf("slice %s_%s has invalid generate path: %s", pkgName, sliceName, err) + return nil, fmt.Errorf("slice %s_%s has invalid generate path: %s", pkg.RealName, sliceName, err) } kinds = append(kinds, GeneratePath) } else if strings.ContainsAny(contPath, "*?") { if yamlPath != nil { if !yamlPath.SameContent(&zeroPath) || yamlPath.Prefer != "" { return nil, fmt.Errorf("slice %s_%s path %s has invalid wildcard options", - pkgName, sliceName, contPath) + pkg.RealName, sliceName, contPath) } } kinds = append(kinds, GlobPath) @@ -621,7 +621,7 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack if yamlPath.Dir { if !strings.HasSuffix(contPath, "/") { return nil, fmt.Errorf("slice %s_%s path %s must end in / for 'make' to be valid", - pkgName, sliceName, contPath) + pkg.RealName, sliceName, contPath) } kinds = append(kinds, DirPath) } @@ -644,17 +644,17 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack switch until { case UntilNone, UntilMutate: default: - return nil, fmt.Errorf("slice %s_%s has invalid 'until' for path %s: %q", pkgName, sliceName, contPath, until) + return nil, fmt.Errorf("slice %s_%s has invalid 'until' for path %s: %q", pkg.RealName, sliceName, contPath, until) } arch = yamlPath.Arch.List for _, s := range arch { if deb.ValidateArch(s) != nil { - return nil, fmt.Errorf("slice %s_%s has invalid 'arch' for path %s: %q", pkgName, sliceName, contPath, s) + return nil, fmt.Errorf("slice %s_%s has invalid 'arch' for path %s: %q", pkg.RealName, sliceName, contPath, s) } } } - if prefer == pkgName { - return nil, fmt.Errorf("slice %s_%s cannot 'prefer' its own package for path %s", pkgName, sliceName, contPath) + if prefer == pkg.RealName { + return nil, fmt.Errorf("slice %s_%s cannot 'prefer' its own package for path %s", pkg.RealName, sliceName, contPath) } if len(kinds) == 0 { kinds = append(kinds, CopyPath) @@ -664,10 +664,10 @@ func parsePackage(release *Release, pkgName, pkgPath string, data []byte) (*Pack for i, s := range kinds { list[i] = string(s) } - return nil, fmt.Errorf("conflict in slice %s_%s definition for path %s: %s", pkgName, sliceName, contPath, strings.Join(list, ", ")) + return nil, fmt.Errorf("conflict in slice %s_%s definition for path %s: %s", pkg.RealName, sliceName, contPath, strings.Join(list, ", ")) } if mutable && kinds[0] != TextPath && (kinds[0] != CopyPath || isDir) { - return nil, fmt.Errorf("slice %s_%s mutable is not a regular file: %s", pkgName, sliceName, contPath) + return nil, fmt.Errorf("slice %s_%s mutable is not a regular file: %s", pkg.RealName, sliceName, contPath) } slice.Contents[contPath] = PathInfo{ Kind: kinds[0], From 3b8a753abecb66ddc02590bc34e48c6dc7940897 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 15:58:11 +0200 Subject: [PATCH 15/16] fix: more name tweaking Signed-off-by: Paul Mars --- internal/slicer/slicer.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 887a577e..dc372862 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -243,19 +243,19 @@ func Run(options *RunOptions) error { // Extract all packages, also using the selection order. for _, slice := range options.Selection.Slices { - realName := slice.RealPkgName() - reader := packages[realName] + realPkgName := slice.RealPkgName() + reader := packages[realPkgName] if reader == nil { continue } err := deb.Extract(reader, &deb.ExtractOptions{ Package: slice.Package, - Extract: extract[realName], + Extract: extract[realPkgName], TargetDir: targetDir, Create: create, }) reader.Close() - packages[realName] = nil + packages[realPkgName] = nil if err != nil { return err } @@ -519,11 +519,11 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel pkgArchive := make(map[string]archive.Archive) for _, s := range selection.Slices { - realName := s.RealPkgName() - if _, ok := pkgArchive[realName]; ok { + realPkgName := s.RealPkgName() + if _, ok := pkgArchive[realPkgName]; ok { continue } - pkg := selection.Release.Packages[realName] + pkg := selection.Release.Packages[realPkgName] if pkg.Store != "" { // Packages coming from a store are not fetched from an archive, // so we skip them here. @@ -550,7 +550,7 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel if chosen == nil { return nil, fmt.Errorf("cannot find package %q in archive(s)", pkg.Name) } - pkgArchive[realName] = chosen + pkgArchive[realPkgName] = chosen } return pkgArchive, nil } From fdd0e4934e96eb154f9091609a4ad2dfb50b4433 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 2 Jun 2026 16:08:35 +0200 Subject: [PATCH 16/16] fix: correct involontary lint fixes Signed-off-by: Paul Mars --- cmd/chisel/cmd_info.go | 6 ++---- internal/manifestutil/manifestutil.go | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/chisel/cmd_info.go b/cmd/chisel/cmd_info.go index a9fa826e..fa5485c6 100644 --- a/cmd/chisel/cmd_info.go +++ b/cmd/chisel/cmd_info.go @@ -11,9 +11,8 @@ import ( "github.com/canonical/chisel/internal/setup" ) -var ( - shortInfoHelp = "Show information about package slices" - longInfoHelp = ` +var shortInfoHelp = "Show information about package slices" +var longInfoHelp = ` The info command shows detailed information about package slices. It accepts a whitespace-separated list of strings. The list can be @@ -24,7 +23,6 @@ the output is a list of YAML documents separated by a "---" line. Slice definitions are shown verbatim according to their definition in the selected release. For example, globs are not expanded. ` -) var infoDescs = map[string]string{ "release": "Chisel release name or directory (e.g. ubuntu-22.04)", diff --git a/internal/manifestutil/manifestutil.go b/internal/manifestutil/manifestutil.go index da9cc8b0..16b05402 100644 --- a/internal/manifestutil/manifestutil.go +++ b/internal/manifestutil/manifestutil.go @@ -134,7 +134,7 @@ func manifestAddReport(dbw *jsonwall.DBWriter, report *Report) error { func unixPerm(mode fs.FileMode) (perm uint32) { perm = uint32(mode.Perm()) if mode&fs.ModeSticky != 0 { - perm |= 0o1000 + perm |= 01000 } return perm }