diff --git a/cmd/api/cmd_test.go b/cmd/api/cmd_test.go index e42d23e..145894a 100644 --- a/cmd/api/cmd_test.go +++ b/cmd/api/cmd_test.go @@ -189,6 +189,30 @@ func TestAPISpecCmd_Good_ContactFlagsPopulateSpecInfo(t *testing.T) { } } +func TestSpecGroupsIter_Good_DeduplicatesExtraBridge(t *testing.T) { + snapshot := api.RegisteredSpecGroups() + api.ResetSpecGroups() + t.Cleanup(func() { + api.ResetSpecGroups() + api.RegisterSpecGroups(snapshot...) + }) + + group := specCmdStubGroup{} + api.RegisterSpecGroups(group) + + var groups []api.RouteGroup + for g := range specGroupsIter(group) { + groups = append(groups, g) + } + + if len(groups) != 1 { + t.Fatalf("expected duplicate extra group to be skipped, got %d groups", len(groups)) + } + if groups[0].Name() != group.Name() || groups[0].BasePath() != group.BasePath() { + t.Fatalf("expected original group to be preserved, got %s at %s", groups[0].Name(), groups[0].BasePath()) + } +} + func TestAPISpecCmd_Good_TermsOfServiceFlagPopulatesSpecInfo(t *testing.T) { root := &cli.Command{Use: "root"} AddAPICommands(root) diff --git a/cmd/api/spec_groups_iter.go b/cmd/api/spec_groups_iter.go index ce910e5..5c5a87a 100644 --- a/cmd/api/spec_groups_iter.go +++ b/cmd/api/spec_groups_iter.go @@ -13,15 +13,29 @@ import ( // existing ordering guarantees. func specGroupsIter(extra goapi.RouteGroup) iter.Seq[goapi.RouteGroup] { return func(yield func(goapi.RouteGroup) bool) { + seen := map[string]struct{}{} for group := range goapi.RegisteredSpecGroupsIter() { + key := specGroupIterKey(group) + seen[key] = struct{}{} if !yield(group) { return } } if extra != nil { + if _, ok := seen[specGroupIterKey(extra)]; ok { + return + } if !yield(extra) { return } } } } + +func specGroupIterKey(group goapi.RouteGroup) string { + if group == nil { + return "" + } + + return group.Name() + "\x00" + group.BasePath() +}