Skip to content

Commit 7a789fe

Browse files
authored
opm validate: fail on duplicate packages, channels, and bundles (#824)
Signed-off-by: Joe Lanford <[email protected]>
1 parent 29cd8e3 commit 7a789fe

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

alpha/declcfg/declcfg_to_model.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
1818
return nil, fmt.Errorf("config contains package with no name")
1919
}
2020

21+
if _, ok := mpkgs[p.Name]; ok {
22+
return nil, fmt.Errorf("duplicate package %q", p.Name)
23+
}
24+
2125
mpkg := &model.Package{
2226
Name: p.Name,
2327
Description: p.Description,
@@ -44,6 +48,10 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
4448
return nil, fmt.Errorf("package %q contains channel with no name", c.Package)
4549
}
4650

51+
if _, ok := mpkg.Channels[c.Name]; ok {
52+
return nil, fmt.Errorf("package %q has duplicate channel %q", c.Package, c.Name)
53+
}
54+
4755
mch := &model.Channel{
4856
Package: mpkg,
4957
Name: c.Name,
@@ -75,6 +83,10 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
7583
}
7684
}
7785

86+
// packageBundles tracks the set of bundle names for each package
87+
// and is used to detect duplicate bundles.
88+
packageBundles := map[string]sets.String{}
89+
7890
for _, b := range cfg.Bundles {
7991
if b.Package == "" {
8092
return nil, fmt.Errorf("package name must be set for bundle %q", b.Name)
@@ -84,6 +96,16 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
8496
return nil, fmt.Errorf("unknown package %q for bundle %q", b.Package, b.Name)
8597
}
8698

99+
bundles, ok := packageBundles[b.Package]
100+
if !ok {
101+
bundles = sets.NewString()
102+
}
103+
if bundles.Has(b.Name) {
104+
return nil, fmt.Errorf("package %q has duplicate bundle %q", b.Package, b.Name)
105+
}
106+
bundles.Insert(b.Name)
107+
packageBundles[b.Package] = bundles
108+
87109
props, err := property.Parse(b.Properties)
88110
if err != nil {
89111
return nil, fmt.Errorf("parse properties for bundle %q: %v", b.Name, err)

alpha/declcfg/declcfg_to_model_test.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,42 @@ func TestConvertToModel(t *testing.T) {
203203
Bundles: []Bundle{newTestBundle("foo", "0.1.0")},
204204
},
205205
},
206+
{
207+
name: "Error/DuplicatePackage",
208+
assertion: hasError(`duplicate package "foo"`),
209+
cfg: DeclarativeConfig{
210+
Packages: []Package{
211+
newTestPackage("foo", "alpha", svgSmallCircle),
212+
newTestPackage("foo", "alpha", svgSmallCircle),
213+
},
214+
Channels: []Channel{newTestChannel("foo", "alpha", ChannelEntry{Name: "foo.v0.1.0"})},
215+
Bundles: []Bundle{newTestBundle("foo", "0.1.0")},
216+
},
217+
},
218+
{
219+
name: "Error/DuplicateChannel",
220+
assertion: hasError(`package "foo" has duplicate channel "alpha"`),
221+
cfg: DeclarativeConfig{
222+
Packages: []Package{newTestPackage("foo", "alpha", svgSmallCircle)},
223+
Channels: []Channel{
224+
newTestChannel("foo", "alpha", ChannelEntry{Name: "foo.v0.1.0"}),
225+
newTestChannel("foo", "alpha", ChannelEntry{Name: "foo.v0.1.0"}),
226+
},
227+
Bundles: []Bundle{newTestBundle("foo", "0.1.0")},
228+
},
229+
},
230+
{
231+
name: "Error/DuplicateBundle",
232+
assertion: hasError(`package "foo" has duplicate bundle "foo.v0.1.0"`),
233+
cfg: DeclarativeConfig{
234+
Packages: []Package{newTestPackage("foo", "alpha", svgSmallCircle)},
235+
Channels: []Channel{newTestChannel("foo", "alpha", ChannelEntry{Name: "foo.v0.1.0"})},
236+
Bundles: []Bundle{
237+
newTestBundle("foo", "0.1.0"),
238+
newTestBundle("foo", "0.1.0"),
239+
},
240+
},
241+
},
206242
{
207243
name: "Success/ValidModel",
208244
assertion: require.NoError,
@@ -242,7 +278,7 @@ func hasError(expectedError string) require.ErrorAssertionFunc {
242278
if stdt, ok := t.(*testing.T); ok {
243279
stdt.Helper()
244280
}
245-
if actualError.Error() == expectedError {
281+
if actualError != nil && actualError.Error() == expectedError {
246282
return
247283
}
248284
t.Errorf("expected error to be `%s`, got `%s`", expectedError, actualError)

0 commit comments

Comments
 (0)