diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 10953ada..f8e86f94 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -153,6 +153,9 @@ func (s *Slice) String() string { return s.Package + "_" + s.Name } type Selection struct { Release *Release Slices []*Slice + // Arch is the architecture the selection was made for. Paths listed for + // other architectures do not take part in it. + Arch string } // Prefers uses the prefer relationships and returns a map from each path to @@ -166,7 +169,10 @@ func (s *Selection) Prefers() (map[string]*Package, error) { pathPreferredPkg := make(map[string]*Package) for _, slice := range s.Slices { - for path := range slice.Contents { + for path, info := range slice.Contents { + if len(info.Arch) > 0 && s.Arch != "" && !slices.Contains(info.Arch, s.Arch) { + continue + } _, hasPrefers := prefers[preferKey{preferSource, path, ""}] if !hasPrefers { continue @@ -482,6 +488,7 @@ func Select(release *Release, slices []SliceKey, arch string) (*Selection, error selection := &Selection{ Release: release, + Arch: arch, } sorted, err := order(release.Packages, slices, arch) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index ec61490b..4b742fba 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -428,6 +428,7 @@ var setupTests = []setupTest{{ }, selslices: []setup.SliceKey{{"mypkg1", "myslice1"}}, selection: &setup.Selection{ + Arch: "amd64", Slices: []*setup.Slice{{ Package: "mypkg1", Name: "myslice1", @@ -451,6 +452,7 @@ var setupTests = []setupTest{{ }, selslices: []setup.SliceKey{{"mypkg2", "myslice2"}}, selection: &setup.Selection{ + Arch: "amd64", Slices: []*setup.Slice{{ Package: "mypkg1", Name: "myslice1", @@ -1891,6 +1893,7 @@ var setupTests = []setupTest{{ }, selslices: []setup.SliceKey{{"mypkg", "myslice"}}, selection: &setup.Selection{ + Arch: "amd64", Slices: []*setup.Slice{{ Package: "mypkg", Name: "myslice", @@ -2729,6 +2732,31 @@ var setupTests = []setupTest{{ "/path": "mypkg2", "/link": "mypkg1", }, +}, { + summary: "Path 'prefer' ignores packages listing the path for another arch", + selslices: []setup.SliceKey{ + {"mypkg1", "myslice1"}, + {"mypkg2", "myslice1"}, + }, + input: map[string]string{ + "slices/mydir/mypkg1.yaml": ` + package: mypkg1 + slices: + myslice1: + contents: + /path: {arch: arm64} + `, + "slices/mydir/mypkg2.yaml": ` + package: mypkg2 + slices: + myslice1: + contents: + /path: {prefer: mypkg1} + `, + }, + prefers: map[string]string{ + "/path": "mypkg2", + }, }, { summary: "Cannot specify same package in 'prefer'", input: map[string]string{ diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index d6ef9ca0..abb3a926 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -1868,6 +1868,50 @@ var slicerTests = []slicerTest{{ "/link": "symlink /file1 {test-package1_myslice}", "/text": "file 0644 2c26b46b {test-package1_myslice}", }, +}, { + summary: "Preferred package lists the path only for another arch", + arch: "i386", + slices: []setup.SliceKey{ + {"test-package1", "myslice"}, + {"test-package2", "myslice"}, + }, + pkgs: []*testutil.TestPackage{{ + Name: "test-package1", + Data: testutil.MustMakeDeb([]testutil.TarEntry{ + testutil.Dir(0755, "./"), + testutil.Reg(0644, "./file", "foo"), + }), + }, { + Name: "test-package2", + Data: testutil.MustMakeDeb([]testutil.TarEntry{ + testutil.Dir(0755, "./"), + testutil.Reg(0644, "./file", "bar"), + }), + }}, + release: map[string]string{ + "slices/mydir/test-package1.yaml": ` + package: test-package1 + slices: + myslice: + contents: + /file: {arch: amd64} + `, + "slices/mydir/test-package2.yaml": ` + package: test-package2 + slices: + myslice: + contents: + /file: {prefer: test-package1} + `, + }, + // test-package1 does not list /file for i386, so test-package2 is the + // only package providing it and must extract it. + filesystem: map[string]string{ + "/file": "file 0644 fcde2b2e", + }, + manifestPaths: map[string]string{ + "/file": "file 0644 fcde2b2e {test-package2_myslice}", + }, }, { summary: "Warning when implicit parent directories conflict", slices: []setup.SliceKey{