Skip to content

Commit 40ec727

Browse files
committed
spec: iterate subpackages by target
Expose target package selection as a package-level iterator so callers consume deterministic package metadata without materializing maps. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
1 parent 3489355 commit 40ec727

2 files changed

Lines changed: 58 additions & 26 deletions

File tree

subpackage.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dalec
33
import (
44
goerrors "errors"
55
"fmt"
6+
"iter"
67
"slices"
78
"unicode"
89

@@ -106,6 +107,13 @@ type SubPackage struct {
106107
Replaces PackageDependencyList `yaml:"replaces,omitempty" json:"replaces,omitempty"`
107108
}
108109

110+
// GetSubPackagesForTarget returns the supplemental packages defined for the
111+
// given target in map-key order. A missing target or a target without
112+
// supplemental packages yields no values.
113+
func GetSubPackagesForTarget(spec *Spec, target string) iter.Seq2[string, SubPackage] {
114+
return SortedMapIter(spec.Targets[target].Packages)
115+
}
116+
109117
// ResolvedName returns the package name that this SubPackage will produce.
110118
// If [SubPackage.Name] is set, it is returned as-is.
111119
// Otherwise, the name is "<parentName>-<mapKey>".
@@ -255,23 +263,11 @@ func validateSubPackageNames(specName, targetName string, packages map[string]Su
255263
return goerrors.Join(errs...)
256264
}
257265

258-
// GetSubPackages returns the supplemental packages defined for the given target.
259-
// Returns nil if the target does not exist or has no supplemental packages.
260-
func (s *Spec) GetSubPackages(targetKey string) map[string]SubPackage {
261-
t, ok := s.Targets[targetKey]
262-
if !ok {
263-
return nil
264-
}
265-
return t.Packages
266-
}
267-
268266
// GetAllPackageNames returns the resolved names of all packages (primary +
269267
// supplemental) for the given target. The primary package name is always first.
270268
func (s *Spec) GetAllPackageNames(targetKey string) []string {
271269
names := []string{s.Name}
272-
packages := s.GetSubPackages(targetKey)
273-
for _, key := range SortMapKeys(packages) {
274-
pkg := packages[key]
270+
for key, pkg := range GetSubPackagesForTarget(s, targetKey) {
275271
names = append(names, pkg.ResolvedName(s.Name, key))
276272
}
277273
return names

subpackage_test.go

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -487,34 +487,70 @@ targets:
487487
assert.Check(t, cmp.Equal(contribPkg.ResolvedName("foo", "contrib"), "foo-contrib-custom"))
488488
}
489489

490-
func TestGetSubPackages(t *testing.T) {
490+
func TestGetSubPackagesForTarget(t *testing.T) {
491491
t.Parallel()
492492

493493
spec := &Spec{
494494
Name: "foo",
495495
Targets: map[string]Target{
496496
"azlinux3": {
497497
Packages: map[string]SubPackage{
498-
"debug": {Description: "debug"},
498+
"debug": {
499+
Description: "debug",
500+
},
501+
"contrib": {
502+
Name: "custom-contrib",
503+
Description: "contrib",
504+
},
499505
},
500506
},
501507
"jammy": {},
508+
"other": {
509+
Packages: map[string]SubPackage{
510+
"other": {
511+
Description: "other",
512+
},
513+
},
514+
},
502515
},
503516
}
504517

505-
// Target with packages
506-
pkgs := spec.GetSubPackages("azlinux3")
507-
assert.Check(t, cmp.Equal(len(pkgs), 1))
508-
_, ok := pkgs["debug"]
509-
assert.Check(t, ok)
518+
t.Run("A target with subpackages yields only its packages in map-key order", func(t *testing.T) {
519+
t.Parallel()
510520

511-
// Target without packages
512-
pkgs = spec.GetSubPackages("jammy")
513-
assert.Check(t, cmp.Equal(len(pkgs), 0))
521+
var keys []string
522+
var packages []SubPackage
523+
for key, pkg := range GetSubPackagesForTarget(spec, "azlinux3") {
524+
keys = append(keys, key)
525+
packages = append(packages, pkg)
526+
}
514527

515-
// Non-existent target
516-
pkgs = spec.GetSubPackages("nonexistent")
517-
assert.Check(t, pkgs == nil)
528+
assert.DeepEqual(t, keys, []string{"contrib", "debug"})
529+
assert.Equal(t, packages[0].Name, "custom-contrib")
530+
assert.Equal(t, packages[1].Description, "debug")
531+
})
532+
533+
t.Run("A target without subpackages yields no values", func(t *testing.T) {
534+
t.Parallel()
535+
536+
var count int
537+
for range GetSubPackagesForTarget(spec, "jammy") {
538+
count++
539+
}
540+
541+
assert.Equal(t, count, 0)
542+
})
543+
544+
t.Run("A missing target yields no values", func(t *testing.T) {
545+
t.Parallel()
546+
547+
var count int
548+
for range GetSubPackagesForTarget(spec, "nonexistent") {
549+
count++
550+
}
551+
552+
assert.Equal(t, count, 0)
553+
})
518554
}
519555

520556
func TestGetAllPackageNames(t *testing.T) {

0 commit comments

Comments
 (0)