From 1da46b067241b988eae7ab0a7683bcc42e87a8ac Mon Sep 17 00:00:00 2001
From: eSamS <27200749+eSamS@users.noreply.github.com>
Date: Fri, 8 Apr 2022 10:16:46 +0200
Subject: [PATCH] fix(go): allow go modules in gitlab subgroups (#14831)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 .../go-get-gitlab-ee-subgroup.html            | 10 ++++
 lib/modules/datasource/go/base.spec.ts        | 54 +++++++++++++++++++
 lib/modules/datasource/go/base.ts             |  6 +--
 lib/util/url.ts                               |  4 ++
 4 files changed, 70 insertions(+), 4 deletions(-)
 create mode 100644 lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-subgroup.html

diff --git a/lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-subgroup.html b/lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-subgroup.html
new file mode 100644
index 0000000000..c2e75fbe67
--- /dev/null
+++ b/lib/modules/datasource/go/__fixtures__/go-get-gitlab-ee-subgroup.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+	<meta name="go-import" content="my.custom.domain/golang/subgroup/myrepo git https://my.custom.domain/golang/subgroup/myrepo.git" />
+	<meta name="go-source"
+		content="my.custom.domain/golang/subgroup/myrepo https://my.custom.domain/golang/subgroup/myrepo https://my.custom.domain/golang/subgroup/myrepo/-/tree/master{/dir} https://my.custom.domain/golang/subgroup/myrepo/-/blob/master{/dir}/{file}#L{line}" />
+</head>
+
+<body>go get https://my.custom.domain/golang/subgroup/myrepo</body>
+
+</html>
diff --git a/lib/modules/datasource/go/base.spec.ts b/lib/modules/datasource/go/base.spec.ts
index 3acf75baa9..80e6da2966 100644
--- a/lib/modules/datasource/go/base.spec.ts
+++ b/lib/modules/datasource/go/base.spec.ts
@@ -201,6 +201,60 @@ describe('modules/datasource/go/base', () => {
         });
       });
 
+      it('supports GitLab EE deps in subgroup', async () => {
+        hostRules.find.mockReturnValue({ token: 'some-token' });
+        httpMock
+          .scope('https://my.custom.domain')
+          .get('/golang/subgroup/myrepo?go-get=1')
+          .reply(200, loadFixture('go-get-gitlab-ee-subgroup.html'));
+
+        const res = await BaseGoDatasource.getDatasource(
+          'my.custom.domain/golang/subgroup/myrepo'
+        );
+
+        expect(res).toEqual({
+          datasource: GitlabTagsDatasource.id,
+          packageName: 'golang/subgroup/myrepo',
+          registryUrl: 'https://my.custom.domain',
+        });
+      });
+
+      it('supports GitLab EE deps in subgroup with version', async () => {
+        hostRules.find.mockReturnValue({ token: 'some-token' });
+        httpMock
+          .scope('https://my.custom.domain')
+          .get('/golang/subgroup/myrepo/v2?go-get=1')
+          .reply(200, loadFixture('go-get-gitlab-ee-subgroup.html'));
+
+        const res = await BaseGoDatasource.getDatasource(
+          'my.custom.domain/golang/subgroup/myrepo/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
+          .scope('https://my.custom.domain')
+          .get('/golang/subgroup/myrepo/monorepo?go-get=1')
+          .reply(200, loadFixture('go-get-gitlab-ee-subgroup.html'));
+
+        const res = await BaseGoDatasource.getDatasource(
+          'my.custom.domain/golang/subgroup/myrepo/monorepo'
+        );
+
+        expect(res).toEqual({
+          datasource: GitlabTagsDatasource.id,
+          packageName: 'golang/subgroup/myrepo',
+          registryUrl: 'https://my.custom.domain',
+        });
+      });
+
       it('handles fyne.io', async () => {
         const meta =
           '<meta name="go-import" content="fyne.io/fyne git https://github.com/fyne-io/fyne">';
diff --git a/lib/modules/datasource/go/base.ts b/lib/modules/datasource/go/base.ts
index d6f562019f..d32e9513ab 100644
--- a/lib/modules/datasource/go/base.ts
+++ b/lib/modules/datasource/go/base.ts
@@ -4,7 +4,7 @@ import { logger } from '../../../logger';
 import * as hostRules from '../../../util/host-rules';
 import { Http } from '../../../util/http';
 import { regEx } from '../../../util/regex';
-import { trimTrailingSlash } from '../../../util/url';
+import { trimLeadingSlash, trimTrailingSlash } from '../../../util/url';
 import { BitBucketTagsDatasource } from '../bitbucket-tags';
 import { GithubTagsDatasource } from '../github-tags';
 import { GitlabTagsDatasource } from '../gitlab-tags';
@@ -123,9 +123,7 @@ export class BaseGoDatasource {
         // get server base url from import url
         const parsedUrl = URL.parse(goSourceUrl);
 
-        // split the go module from the URL: host/go/module -> go/module
-        const split = goModule.split('/');
-        const packageName = split[1] + '/' + split[2];
+        const packageName = trimLeadingSlash(parsedUrl.pathname);
 
         const registryUrl = `${parsedUrl.protocol}//${parsedUrl.host}`;
 
diff --git a/lib/util/url.ts b/lib/util/url.ts
index 3c3ec98f39..176769a604 100644
--- a/lib/util/url.ts
+++ b/lib/util/url.ts
@@ -26,6 +26,10 @@ export function trimTrailingSlash(url: string): string {
   return url.replace(regEx(/\/+$/), '');
 }
 
+export function trimLeadingSlash(path: string): string {
+  return path.replace(/^\//, '');
+}
+
 export function resolveBaseUrl(baseUrl: string, input: string | URL): string {
   const inputString = input.toString();
 
-- 
GitLab