Skip to content

Commit 12f6c50

Browse files
author
Laurie T. Malau
committed
Adapt nested subgroups
1 parent ca9be09 commit 12f6c50

File tree

8 files changed

+100
-32
lines changed

8 files changed

+100
-32
lines changed

components/server/ee/src/workspace/workspace-factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { ResponseError } from 'vscode-jsonrpc';
1616
import { ErrorCodes } from '@gitpod/gitpod-protocol/lib/messaging/error';
1717
import { generateWorkspaceID } from '@gitpod/gitpod-protocol/lib/util/generate-workspace-id';
1818
import { HostContextProvider } from '../../../src/auth/host-context-provider';
19-
import { parseRepoUrl } from '../../../src/repohost';
19+
import { RepoURL } from '../../../src/repohost';
2020

2121
@injectable()
2222
export class WorkspaceFactoryEE extends WorkspaceFactory {
@@ -153,7 +153,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
153153
protected async storePrebuildInfo(ctx: TraceContext, project: Project, pws: PrebuiltWorkspace, ws: Workspace, user: User) {
154154
const span = TraceContext.startSpan("storePrebuildInfo", ctx);
155155
const { userId, teamId, name: projectName, id: projectId } = project;
156-
const parsedUrl = parseRepoUrl(project.cloneUrl);
156+
const parsedUrl = RepoURL.parseRepoUrl(project.cloneUrl);
157157
if (!parsedUrl) {
158158
return;
159159
}

components/server/src/bitbucket/bitbucket-repository-provider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import { Branch, CommitInfo, Repository, User } from "@gitpod/gitpod-protocol";
88
import { inject, injectable } from 'inversify';
9-
import { parseRepoUrl } from '../repohost/repo-url';
9+
import { RepoURL } from '../repohost/repo-url';
1010
import { RepositoryProvider } from '../repohost/repository-provider';
1111
import { BitbucketApiFactory } from './bitbucket-api-factory';
1212

@@ -19,7 +19,7 @@ export class BitbucketRepositoryProvider implements RepositoryProvider {
1919
const api = await this.apiFactory.create(user);
2020
const repo = (await api.repositories.get({ workspace: owner, repo_slug: name })).data;
2121
const cloneUrl = repo.links!.clone!.find((x: any) => x.name === "https")!.href!;
22-
const host = parseRepoUrl(cloneUrl)!.host;
22+
const host = RepoURL.parseRepoUrl(cloneUrl)!.host;
2323
const description = repo.description;
2424
const avatarUrl = repo.owner!.links!.avatar!.href;
2525
const webUrl = repo.links!.html!.href;

components/server/src/github/github-repository-provider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { injectable, inject } from 'inversify';
99
import { User, Repository } from "@gitpod/gitpod-protocol"
1010
import { GitHubGraphQlEndpoint, GitHubRestApi } from "./api";
1111
import { RepositoryProvider } from '../repohost/repository-provider';
12-
import { parseRepoUrl } from '../repohost/repo-url';
12+
import { RepoURL } from '../repohost/repo-url';
1313
import { Branch, CommitInfo } from '@gitpod/gitpod-protocol/src/protocol';
1414

1515
@injectable()
@@ -20,7 +20,7 @@ export class GithubRepositoryProvider implements RepositoryProvider {
2020
async getRepo(user: User, owner: string, repo: string): Promise<Repository> {
2121
const repository = await this.github.getRepository(user, { owner, repo });
2222
const cloneUrl = repository.clone_url;
23-
const host = parseRepoUrl(cloneUrl)!.host;
23+
const host = RepoURL.parseRepoUrl(cloneUrl)!.host;
2424
const description = repository.description;
2525
const avatarUrl = repository.owner.avatar_url;
2626
const webUrl = repository.html_url;

components/server/src/gitlab/gitlab-repository-provider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { injectable, inject } from 'inversify';
99
import { User, Repository, Branch, CommitInfo } from "@gitpod/gitpod-protocol"
1010
import { GitLabApi, GitLab } from "./api";
1111
import { RepositoryProvider } from '../repohost/repository-provider';
12-
import { parseRepoUrl } from '../repohost/repo-url';
12+
import { RepoURL } from '../repohost/repo-url';
1313

1414
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';
1515

@@ -26,7 +26,7 @@ export class GitlabRepositoryProvider implements RepositoryProvider {
2626
}
2727
const cloneUrl = response.http_url_to_repo;
2828
const description = response.default_branch;
29-
const host = parseRepoUrl(cloneUrl)!.host;
29+
const host = RepoURL.parseRepoUrl(cloneUrl)!.host;
3030
const avatarUrl = response.owner?.avatar_url || undefined;
3131
const webUrl = response.web_url;
3232
const defaultBranch = response.default_branch

components/server/src/projects/projects-service.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { DBWithTracing, ProjectDB, TeamDB, TracedWorkspaceDB, UserDB, WorkspaceD
99
import { Branch, CommitContext, PrebuildWithStatus, CreateProjectParams, FindPrebuildsParams, Project, ProjectConfig, User, WorkspaceConfig } from "@gitpod/gitpod-protocol";
1010
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
1111
import { HostContextProvider } from "../auth/host-context-provider";
12-
import { FileProvider, parseRepoUrl } from "../repohost";
12+
import { FileProvider, RepoURL } from "../repohost";
1313
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';
1414
import { ContextParser } from "../workspace/context-parser-service";
1515
import { ConfigInferrer } from "./config-inferrer";
@@ -46,13 +46,13 @@ export class ProjectsService {
4646
}
4747

4848
protected getRepositoryProvider(project: Project) {
49-
const parsedUrl = parseRepoUrl(project.cloneUrl);
49+
const parsedUrl = RepoURL.parseRepoUrl(project.cloneUrl);
5050
const repositoryProvider = parsedUrl && this.hostContextProvider.get(parsedUrl.host)?.services?.repositoryProvider;
5151
return repositoryProvider;
5252
}
5353

5454
async getBranchDetails(user: User, project: Project, branchName?: string): Promise<Project.BranchDetails[]> {
55-
const parsedUrl = parseRepoUrl(project.cloneUrl);
55+
const parsedUrl = RepoURL.parseRepoUrl(project.cloneUrl);
5656
if (!parsedUrl) {
5757
return [];
5858
}
@@ -109,7 +109,7 @@ export class ProjectsService {
109109

110110
protected async onDidCreateProject(project: Project) {
111111
let { userId, teamId, cloneUrl } = project;
112-
const parsedUrl = parseRepoUrl(project.cloneUrl);
112+
const parsedUrl = RepoURL.parseRepoUrl(project.cloneUrl);
113113
if ("gitlab.com" === parsedUrl?.host) {
114114
const repositoryService = this.hostContextProvider.get(parsedUrl?.host)?.services?.repositoryService;
115115
if (repositoryService) {
@@ -140,7 +140,7 @@ export class ProjectsService {
140140
if (!project) {
141141
return [];
142142
}
143-
const parsedUrl = parseRepoUrl(project.cloneUrl);
143+
const parsedUrl = RepoURL.parseRepoUrl(project.cloneUrl);
144144
if (!parsedUrl) {
145145
return [];
146146
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License-AGPL.txt in the project root for license information.
5+
*/
6+
7+
import * as chai from 'chai';
8+
import { suite, test } from 'mocha-typescript';
9+
import { RepoURL } from './repo-url';
10+
11+
const expect = chai.expect;
12+
13+
@suite
14+
export class RepoUrlTest {
15+
16+
@test public parseRepoUrl() {
17+
const testUrl = RepoURL.parseRepoUrl("https://gitlab.com/hello-group/my-cool-project.git")
18+
expect(testUrl).to.deep.equal({
19+
host: 'gitlab.com',
20+
owner: 'hello-group',
21+
repo: 'my-cool-project'
22+
});
23+
}
24+
25+
@test public parseSubgroupOneLevel() {
26+
const testUrl = RepoURL.parseRepoUrl("https://gitlab.com/hello-group/my-subgroup/my-cool-project.git")
27+
expect(testUrl).to.deep.equal({
28+
host: 'gitlab.com',
29+
owner: 'hello-group/my-subgroup',
30+
repo: 'my-cool-project'
31+
});
32+
}
33+
34+
@test public parseSubgroupTwoLevels() {
35+
const testUrl = RepoURL.parseRepoUrl("https://gitlab.com/hello-group/my-subgroup/my-sub-subgroup/my-cool-project.git")
36+
expect(testUrl).to.deep.equal({
37+
host: 'gitlab.com',
38+
owner: 'hello-group/my-subgroup/my-sub-subgroup',
39+
repo: 'my-cool-project'
40+
});
41+
}
42+
43+
@test public parseSubgroupThreeLevels() {
44+
const testUrl = RepoURL.parseRepoUrl(
45+
"https://gitlab.com/hello-group/my-subgroup/my-sub-subgroup/my-sub-sub-subgroup/my-cool-project.git")
46+
expect(testUrl).to.deep.equal({
47+
host: 'gitlab.com',
48+
owner: 'hello-group/my-subgroup/my-sub-subgroup/my-sub-sub-subgroup',
49+
repo: 'my-cool-project'
50+
});
51+
}
52+
53+
@test public parseSubgroupFourLevels() {
54+
const testUrl = RepoURL.parseRepoUrl(
55+
"https://gitlab.com/hello-group/my-subgroup/my-sub-subgroup/my-sub-sub-subgroup/my-sub-sub-sub-subgroup/my-cool-project.git")
56+
expect(testUrl).to.deep.equal({
57+
host: 'gitlab.com',
58+
owner: 'hello-group/my-subgroup/my-sub-subgroup/my-sub-sub-subgroup/my-sub-sub-sub-subgroup',
59+
repo: 'my-cool-project'
60+
});
61+
}
62+
63+
}
64+
65+
module.exports = new RepoUrlTest()

components/server/src/repohost/repo-url.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@
66

77

88
import * as url from 'url';
9-
10-
export function parseRepoUrl(repoUrl: string): { host: string, owner: string, repo: string} | undefined {
11-
const u = url.parse(repoUrl);
12-
const host = u.hostname || '';
13-
const path = u.pathname || '';
14-
const segments = path.split('/').filter(s => !!s); // e.g. [ 'gitpod-io', 'gitpod.git' ]
15-
if (segments.length === 2) {
16-
const owner = segments[0];
17-
const repo = segments[1].endsWith('.git') ? segments[1].slice(0, -4) : segments[1];
18-
return { host, owner, repo };
19-
}
20-
if (segments.length === 3) {
21-
const owner = `${segments[0]}/${segments[1]}`;
22-
const repo = segments[2].endsWith('.git') ? segments[2].slice(0, -4) : segments[1];
23-
return { host, owner, repo };
9+
export namespace RepoURL {
10+
export function parseRepoUrl(repoUrl: string): { host: string, owner: string, repo: string} | undefined {
11+
const u = url.parse(repoUrl);
12+
const host = u.hostname || '';
13+
const path = u.pathname || '';
14+
const segments = path.split('/').filter(s => !!s); // e.g. [ 'gitpod-io', 'gitpod.git' ]
15+
if (segments.length === 2) {
16+
const owner = segments[0];
17+
const repo = segments[1].endsWith('.git') ? segments[1].slice(0, -4) : segments[1];
18+
return { host, owner, repo };
19+
}
20+
if (segments.length > 2) {
21+
const endSegment = segments[segments.length - 1];
22+
const ownerSegments = segments.slice(0, segments.length-1);
23+
const owner = ownerSegments.join("/");
24+
const repo = endSegment.endsWith('.git') ? endSegment.slice(0, -4) : endSegment;
25+
return { host, owner, repo };
26+
}
27+
return undefined;
2428
}
25-
return undefined;
26-
}
29+
}

components/server/src/workspace/gitpod-server-impl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { HostContextProvider } from '../auth/host-context-provider';
3434
import { GuardedResource, ResourceAccessGuard, ResourceAccessOp } from '../auth/resource-access';
3535
import { Config } from '../config';
3636
import { NotFoundError, UnauthorizedError } from '../errors';
37-
import { parseRepoUrl } from '../repohost/repo-url';
37+
import { RepoURL } from '../repohost/repo-url';
3838
import { TermsProvider } from '../terms/terms-provider';
3939
import { TheiaPluginService } from '../theia-plugin/theia-plugin-service';
4040
import { AuthorizationService } from '../user/authorization-service';
@@ -970,7 +970,7 @@ export class GitpodServerImpl<Client extends GitpodClient, Server extends Gitpod
970970
return (await Promise.all(repositories
971971
.filter(repo => repo.url != undefined)
972972
.map(async whitelistedRepo => {
973-
const repoUrl = parseRepoUrl(whitelistedRepo.url!);
973+
const repoUrl = RepoURL.parseRepoUrl(whitelistedRepo.url!);
974974
if (!repoUrl) return undefined;
975975

976976
const { host, owner, repo } = repoUrl;

0 commit comments

Comments
 (0)