diff --git a/lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-private-subgroup.html b/lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-private-subgroup.html new file mode 100644 index 00000000000000..661497b59cd226 --- /dev/null +++ b/lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-private-subgroup.html @@ -0,0 +1,10 @@ + + + + + + +go get https://my.custom.domain/golang/subgroup + + diff --git a/lib/modules/datasource/go/base.spec.ts b/lib/modules/datasource/go/base.spec.ts index 26ef02a98dc052..c2d2c0c468ff2c 100644 --- a/lib/modules/datasource/go/base.spec.ts +++ b/lib/modules/datasource/go/base.spec.ts @@ -148,6 +148,23 @@ describe('modules/datasource/go/base', () => { }); }); + it('does not fail for names containing .git', async () => { + httpMock + .scope('https://gitlab.com') + .get('/group/subgroup/my.git.module?go-get=1') + .reply(200, Fixtures.get('go-get-gitlab.html')); + + const res = await BaseGoDatasource.getDatasource( + 'gitlab.com/group/subgroup/my.git.module' + ); + + expect(res).toEqual({ + datasource: GitlabTagsDatasource.id, + packageName: 'group/subgroup/my.git.module', + registryUrl: 'https://gitlab.com', + }); + }); + it('supports GitLab with URL mismatch', async () => { const mismatchingResponse = Fixtures.get('go-get-github.html').replace( 'https://github.com/golang/text/', @@ -238,6 +255,24 @@ describe('modules/datasource/go/base', () => { }); }); + it('supports GitLab EE deps in private subgroup with vcs indicator', async () => { + hostRules.find.mockReturnValue({ token: 'some-token' }); + httpMock + .scope('https://my.custom.domain') + .get('/golang/subgroup/myrepo.git/v2?go-get=1') + .reply(200, Fixtures.get('go-get-gitlab-ee-private-subgroup.html')); + + const res = await BaseGoDatasource.getDatasource( + 'my.custom.domain/golang/subgroup/myrepo.git/v2' + ); + + expect(res).toEqual({ + datasource: GitlabTagsDatasource.id, + packageName: 'golang/subgroup/myrepo', + registryUrl: 'https://my.custom.domain', + }); + }); + it('supports GitLab EE monorepo deps in subgroup', async () => { hostRules.find.mockReturnValue({ token: 'some-token' }); httpMock diff --git a/lib/modules/datasource/go/base.ts b/lib/modules/datasource/go/base.ts index b6bbc1a3dc04cc..8c75bb0709d95c 100644 --- a/lib/modules/datasource/go/base.ts +++ b/lib/modules/datasource/go/base.ts @@ -20,6 +20,9 @@ export class BaseGoDatasource { private static readonly gitlabRegExp = regEx( /^(?gitlab\.[^/]*)\/(?.+?)(?:\/v\d+)?[/]?$/ ); + private static readonly gitVcsRegexp = regEx( + /^(?:[^/]+)\/(?.*)\.git(?:$|\/)/ + ); private static readonly id = 'go'; private static readonly http = new Http(BaseGoDatasource.id); @@ -112,14 +115,12 @@ export class BaseGoDatasource { BaseGoDatasource.gitlabRegExp.exec(goModule)?.groups?.regExpPath; if (gitlabUrl && gitlabUrlName) { if (gitlabModuleName?.startsWith(gitlabUrlName)) { - if (gitlabModuleName.includes('.git')) { + const vcsIndicatedModule = BaseGoDatasource.gitVcsRegexp.exec(goModule); + if (vcsIndicatedModule?.groups?.module) { return { datasource: GitlabTagsDatasource.id, registryUrl: gitlabUrl, - packageName: gitlabModuleName.substring( - 0, - gitlabModuleName.indexOf('.git') - ), + packageName: vcsIndicatedModule.groups?.module, }; } return { @@ -149,6 +150,16 @@ export class BaseGoDatasource { const registryUrl = `${parsedUrl.protocol}//${parsedUrl.host}`; + // a .git path indicates a concrete git repository, which can be different from metadata returned by gitlab + const vcsIndicatedModule = BaseGoDatasource.gitVcsRegexp.exec(goModule); + if (vcsIndicatedModule?.groups?.module) { + return { + datasource: GitlabTagsDatasource.id, + registryUrl, + packageName: vcsIndicatedModule.groups?.module, + }; + } + return { datasource: GitlabTagsDatasource.id, registryUrl,