From 69ad77869c9e7bde425ded11a24fe6e394fb1965 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Fri, 5 Mar 2021 11:41:16 +0100 Subject: [PATCH] Make sure that changing the url type doesn't collide with repo or owner names Signed-off-by: Oliver Sand --- .../src/github/GitHubIntegration.test.ts | 28 ++++++++++++++++- .../src/github/GitHubIntegration.ts | 16 ++++++++-- .../src/gitlab/GitLabIntegration.test.ts | 31 ++++++++++++++++++- .../src/gitlab/GitLabIntegration.ts | 9 +++++- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/packages/integration/src/github/GitHubIntegration.test.ts b/packages/integration/src/github/GitHubIntegration.test.ts index 52822ca76f..3bb4b4d3fc 100644 --- a/packages/integration/src/github/GitHubIntegration.test.ts +++ b/packages/integration/src/github/GitHubIntegration.test.ts @@ -15,7 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { GitHubIntegration } from './GitHubIntegration'; +import { GitHubIntegration, replaceUrlType } from './GitHubIntegration'; describe('GitHubIntegration', () => { it('has a working factory', () => { @@ -80,3 +80,29 @@ describe('GitHubIntegration', () => { ).toBe('https://github.com/backstage/backstage/edit/master/README.md'); }); }); + +describe('replaceUrlType', () => { + it('should replace with expected type', () => { + expect( + replaceUrlType( + 'https://github.com/backstage/backstage/blob/master/README.md', + 'edit', + ), + ).toBe('https://github.com/backstage/backstage/edit/master/README.md'); + expect( + replaceUrlType( + 'https://github.com/webmodules/blob/blob/master/test', + 'tree', + ), + ).toBe('https://github.com/webmodules/blob/tree/master/test'); + expect( + replaceUrlType('https://github.com/blob/blob/blob/master/test', 'tree'), + ).toBe('https://github.com/blob/blob/tree/master/test'); + expect( + replaceUrlType( + 'https://github.com/backstage/backstage/edit/tree/README.md', + 'blob', + ), + ).toBe('https://github.com/backstage/backstage/blob/tree/README.md'); + }); +}); diff --git a/packages/integration/src/github/GitHubIntegration.ts b/packages/integration/src/github/GitHubIntegration.ts index 722b5a9f0a..34bebebd9e 100644 --- a/packages/integration/src/github/GitHubIntegration.ts +++ b/packages/integration/src/github/GitHubIntegration.ts @@ -50,10 +50,22 @@ export class GitHubIntegration implements ScmIntegration { // GitHub uses blob URLs for files and tree urls for directory listings. But // there is a redirect from tree to blob for files, so we can always return // tree urls here. - return defaultScmResolveUrl(options).replace('/blob/', '/tree/'); + return replaceUrlType(defaultScmResolveUrl(options), 'tree'); } resolveEditUrl(url: string): string { - return url.replace('/blob/', '/edit/'); + return replaceUrlType(url, 'edit'); } } + +export function replaceUrlType( + url: string, + type: 'blob' | 'tree' | 'edit', +): string { + return url.replace( + /\/\/([^/]+)\/([^/]+)\/([^/]+)\/(blob|tree|edit)\//, + (_, host, owner, repo) => { + return `//${host}/${owner}/${repo}/${type}/`; + }, + ); +} diff --git a/packages/integration/src/gitlab/GitLabIntegration.test.ts b/packages/integration/src/gitlab/GitLabIntegration.test.ts index 395957886b..5cc6d410e3 100644 --- a/packages/integration/src/gitlab/GitLabIntegration.test.ts +++ b/packages/integration/src/gitlab/GitLabIntegration.test.ts @@ -15,7 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { GitLabIntegration } from './GitLabIntegration'; +import { GitLabIntegration, replaceUrlType } from './GitLabIntegration'; describe('GitLabIntegration', () => { it('has a working factory', () => { @@ -54,3 +54,32 @@ describe('GitLabIntegration', () => { ).toBe('https://gitlab.com/my-org/my-project/-/edit/develop/README.md'); }); }); + +describe('replaceUrlType', () => { + it('should replace with expected type', () => { + expect( + replaceUrlType( + 'https://gitlab.com/my-org/my-project/-/blob/develop/README.md', + 'edit', + ), + ).toBe('https://gitlab.com/my-org/my-project/-/edit/develop/README.md'); + expect( + replaceUrlType( + 'https://gitlab.com/webmodules/blob/-/blob/develop/test', + 'tree', + ), + ).toBe('https://gitlab.com/webmodules/blob/-/tree/develop/test'); + expect( + replaceUrlType( + 'https://gitlab.com/blob/blob/-/blob/develop/test', + 'tree', + ), + ).toBe('https://gitlab.com/blob/blob/-/tree/develop/test'); + expect( + replaceUrlType( + 'https://gitlab.com/blob/blob/-/edit/develop/README.md', + 'tree', + ), + ).toBe('https://gitlab.com/blob/blob/-/tree/develop/README.md'); + }); +}); diff --git a/packages/integration/src/gitlab/GitLabIntegration.ts b/packages/integration/src/gitlab/GitLabIntegration.ts index 7e964d19ee..2fd9f54ffe 100644 --- a/packages/integration/src/gitlab/GitLabIntegration.ts +++ b/packages/integration/src/gitlab/GitLabIntegration.ts @@ -51,6 +51,13 @@ export class GitLabIntegration implements ScmIntegration { } resolveEditUrl(url: string): string { - return url.replace('/blob/', '/edit/'); + return replaceUrlType(url, 'edit'); } } + +export function replaceUrlType( + url: string, + type: 'blob' | 'tree' | 'edit', +): string { + return url.replace(/\/\-\/(blob|tree|edit)\//, `/-/${type}/`); +}