Skip to content

Commit d29be10

Browse files
authored
fix: trim trailing slashes from the base-path (#1396)
<!-- markdownlint-disable MD041 --> #### What this PR does / why we need it Avoids things like this: ```yaml Component: bob.poc.sap.com/root ... Repository Spec: Base URL: mcp-blueprints.common.repositories.cloud.sap/ocm/ ... ``` ending up like this: ``` Message: failed to list versions: failed to get store for reference: invalid reference: invalid repository "ocm//component-descriptors/bob.poc.sap.com/root" ``` Because, basically oras has `parts := strings.SplitN(artifact, "/", 2)` in it's parser which resulted in the repository section being cut as `ocm//...` for the full reference of `mcp-blueprints.common.repositories.cloud.sap/ocm//component-descriptors/bob.poc.sap.com/root`. #### Which issue(s) this PR fixes <!-- Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`. --> Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
1 parent 413b01a commit d29be10

2 files changed

Lines changed: 84 additions & 61 deletions

File tree

bindings/go/oci/repository/repository.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ func buildResolver(client remote.Client, repository *ocirepospecv1.Repository) (
9898
return nil, fmt.Errorf("a base url is required")
9999
}
100100

101-
purl, err := runtime.ParseURLAndAllowNoScheme(repository.BaseUrl)
101+
baseURL := strings.TrimSuffix(repository.BaseUrl, "/")
102+
purl, err := runtime.ParseURLAndAllowNoScheme(baseURL)
102103
if err != nil {
103104
return nil, fmt.Errorf("could not parse OCI repository URL %q: %w", repository.BaseUrl, err)
104105
}
105106

106107
// Extract SubPath from BaseUrl if not explicitly set
107-
baseURL := repository.BaseUrl
108108
subPath := repository.SubPath
109109
if subPath == "" && purl.Path != "" && purl.Path != "/" {
110110
// Use path as SubPath and Host as BaseURL.

bindings/go/oci/repository/repository_test.go

Lines changed: 82 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -141,87 +141,107 @@ func TestNewFromOCIRepoV1(t *testing.T) {
141141

142142
func TestBuildResolver_SubPathExtraction(t *testing.T) {
143143
tests := []struct {
144-
name string
145-
baseURL string
146-
subPath string
147-
expectedBasePath string
148-
expectedCVRef string
144+
name string
145+
baseURL string
146+
subPath string
147+
expectedBasePath string
148+
expectedCVRef string
149+
expectedReference string // make sure that the reference parser from ORAS isn't breaking.
149150
}{
150151
{
151-
name: "https with single path segment",
152-
baseURL: "https://registry.example.com/my-org",
153-
subPath: "",
154-
expectedBasePath: "registry.example.com/my-org/component-descriptors",
155-
expectedCVRef: "registry.example.com/my-org/component-descriptors/test-component:1.0.0",
152+
name: "https with single path segment",
153+
baseURL: "https://registry.example.com/my-org",
154+
subPath: "",
155+
expectedBasePath: "registry.example.com/my-org/component-descriptors",
156+
expectedCVRef: "registry.example.com/my-org/component-descriptors/test-component:1.0.0",
157+
expectedReference: "registry.example.com/my-org/component-descriptors/test-component:1.0.0",
156158
},
157159
{
158-
name: "https with multiple path segments",
159-
baseURL: "https://registry.example.com/my-org/components",
160-
subPath: "",
161-
expectedBasePath: "registry.example.com/my-org/components/component-descriptors",
162-
expectedCVRef: "registry.example.com/my-org/components/component-descriptors/test-component:1.0.0",
160+
name: "segmented url",
161+
baseURL: "host/ocm/",
162+
subPath: "",
163+
expectedBasePath: "host/ocm/component-descriptors",
164+
expectedCVRef: "host/ocm/component-descriptors/test-component:1.0.0",
165+
expectedReference: "host/ocm/component-descriptors/test-component:1.0.0",
163166
},
164167
{
165-
name: "http with path",
166-
baseURL: "http://localhost:5000/test/path",
167-
subPath: "",
168-
expectedBasePath: "localhost:5000/test/path/component-descriptors",
169-
expectedCVRef: "localhost:5000/test/path/component-descriptors/test-component:1.0.0",
168+
name: "https with multiple path segments",
169+
baseURL: "https://registry.example.com/my-org/components",
170+
subPath: "",
171+
expectedBasePath: "registry.example.com/my-org/components/component-descriptors",
172+
expectedCVRef: "registry.example.com/my-org/components/component-descriptors/test-component:1.0.0",
173+
expectedReference: "registry.example.com/my-org/components/component-descriptors/test-component:1.0.0",
170174
},
171175
{
172-
name: "no scheme with path",
173-
baseURL: "registry.example.com/org/repo",
174-
subPath: "",
175-
expectedBasePath: "registry.example.com/org/repo/component-descriptors",
176-
expectedCVRef: "registry.example.com/org/repo/component-descriptors/test-component:1.0.0",
176+
name: "http with path",
177+
baseURL: "http://localhost:5000/test/path",
178+
subPath: "",
179+
expectedBasePath: "localhost:5000/test/path/component-descriptors",
180+
expectedCVRef: "localhost:5000/test/path/component-descriptors/test-component:1.0.0",
181+
expectedReference: "localhost:5000/test/path/component-descriptors/test-component:1.0.0",
177182
},
178183
{
179-
name: "explicit subPath with path in baseURL",
180-
baseURL: "https://registry.example.com/extra",
181-
subPath: "explicit/path",
182-
expectedBasePath: "registry.example.com/extra/explicit/path/component-descriptors",
183-
expectedCVRef: "registry.example.com/extra/explicit/path/component-descriptors/test-component:1.0.0",
184+
name: "no scheme with path",
185+
baseURL: "registry.example.com/org/repo",
186+
subPath: "",
187+
expectedBasePath: "registry.example.com/org/repo/component-descriptors",
188+
expectedCVRef: "registry.example.com/org/repo/component-descriptors/test-component:1.0.0",
189+
expectedReference: "registry.example.com/org/repo/component-descriptors/test-component:1.0.0",
184190
},
185191
{
186-
name: "baseURL without path",
187-
baseURL: "https://registry.example.com",
188-
subPath: "",
189-
expectedBasePath: "registry.example.com/component-descriptors",
190-
expectedCVRef: "registry.example.com/component-descriptors/test-component:1.0.0",
192+
name: "explicit subPath with path in baseURL",
193+
baseURL: "https://registry.example.com/extra",
194+
subPath: "explicit/path",
195+
expectedBasePath: "registry.example.com/extra/explicit/path/component-descriptors",
196+
expectedCVRef: "registry.example.com/extra/explicit/path/component-descriptors/test-component:1.0.0",
197+
expectedReference: "registry.example.com/extra/explicit/path/component-descriptors/test-component:1.0.0",
191198
},
192199
{
193-
name: "baseURL with port and path",
194-
baseURL: "https://registry.example.com:8080/my-org",
195-
subPath: "",
196-
expectedBasePath: "registry.example.com:8080/my-org/component-descriptors",
197-
expectedCVRef: "registry.example.com:8080/my-org/component-descriptors/test-component:1.0.0",
200+
name: "baseURL without path",
201+
baseURL: "https://registry.example.com",
202+
subPath: "",
203+
expectedBasePath: "registry.example.com/component-descriptors",
204+
expectedCVRef: "registry.example.com/component-descriptors/test-component:1.0.0",
205+
expectedReference: "registry.example.com/component-descriptors/test-component:1.0.0",
198206
},
199207
{
200-
name: "ghcr.io style URL",
201-
baseURL: "ghcr.io/my-org/my-repo",
202-
subPath: "",
203-
expectedBasePath: "ghcr.io/my-org/my-repo/component-descriptors",
204-
expectedCVRef: "ghcr.io/my-org/my-repo/component-descriptors/test-component:1.0.0",
208+
name: "baseURL with port and path",
209+
baseURL: "https://registry.example.com:8080/my-org",
210+
subPath: "",
211+
expectedBasePath: "registry.example.com:8080/my-org/component-descriptors",
212+
expectedCVRef: "registry.example.com:8080/my-org/component-descriptors/test-component:1.0.0",
213+
expectedReference: "registry.example.com:8080/my-org/component-descriptors/test-component:1.0.0",
205214
},
206215
{
207-
name: "explicit baseURL and subPath",
208-
baseURL: "https://registry.example.com",
209-
subPath: "my-org/my-repo",
210-
expectedBasePath: "registry.example.com/my-org/my-repo/component-descriptors",
211-
expectedCVRef: "registry.example.com/my-org/my-repo/component-descriptors/test-component:1.0.0",
216+
name: "ghcr.io style URL",
217+
baseURL: "ghcr.io/my-org/my-repo",
218+
subPath: "",
219+
expectedBasePath: "ghcr.io/my-org/my-repo/component-descriptors",
220+
expectedCVRef: "ghcr.io/my-org/my-repo/component-descriptors/test-component:1.0.0",
221+
expectedReference: "ghcr.io/my-org/my-repo/component-descriptors/test-component:1.0.0",
212222
},
213223
{
214-
name: "concrete example for platform-mesh",
215-
baseURL: "ghcr.io/platform-mesh",
216-
subPath: "",
217-
expectedBasePath: "ghcr.io/platform-mesh/component-descriptors",
218-
expectedCVRef: "ghcr.io/platform-mesh/component-descriptors/test-component:1.0.0",
224+
name: "explicit baseURL and subPath",
225+
baseURL: "https://registry.example.com",
226+
subPath: "my-org/my-repo",
227+
expectedBasePath: "registry.example.com/my-org/my-repo/component-descriptors",
228+
expectedCVRef: "registry.example.com/my-org/my-repo/component-descriptors/test-component:1.0.0",
229+
expectedReference: "registry.example.com/my-org/my-repo/component-descriptors/test-component:1.0.0",
219230
},
220231
{
221-
name: "avoid duplicates",
222-
baseURL: "https://registry.example.com/my-org/components",
223-
expectedBasePath: "registry.example.com/my-org/components/component-descriptors",
224-
expectedCVRef: "registry.example.com/my-org/components/component-descriptors/test-component:1.0.0",
232+
name: "concrete example for platform-mesh",
233+
baseURL: "ghcr.io/platform-mesh",
234+
subPath: "",
235+
expectedBasePath: "ghcr.io/platform-mesh/component-descriptors",
236+
expectedCVRef: "ghcr.io/platform-mesh/component-descriptors/test-component:1.0.0",
237+
expectedReference: "ghcr.io/platform-mesh/component-descriptors/test-component:1.0.0",
238+
},
239+
{
240+
name: "avoid duplicates",
241+
baseURL: "https://registry.example.com/my-org/components",
242+
expectedBasePath: "registry.example.com/my-org/components/component-descriptors",
243+
expectedCVRef: "registry.example.com/my-org/components/component-descriptors/test-component:1.0.0",
244+
expectedReference: "registry.example.com/my-org/components/component-descriptors/test-component:1.0.0",
225245
},
226246
}
227247

@@ -238,6 +258,9 @@ func TestBuildResolver_SubPathExtraction(t *testing.T) {
238258

239259
assert.Equal(t, tt.expectedBasePath, resolver.BasePath())
240260
assert.Equal(t, tt.expectedCVRef, resolver.ComponentVersionReference(t.Context(), "test-component", "1.0.0"))
261+
stringer, err := resolver.Reference(resolver.ComponentVersionReference(t.Context(), "test-component", "1.0.0"))
262+
require.NoError(t, err)
263+
assert.Equal(t, tt.expectedReference, stringer.String())
241264
})
242265
}
243266
}

0 commit comments

Comments
 (0)