chore: use alt url parser

Signed-off-by: Andrei Ivanovici <andrei.ivanovici@gmail.com>
This commit is contained in:
Andrei Ivanovici
2024-05-10 15:38:48 +03:00
parent 9a22ffef8a
commit 4fefb2a393
5 changed files with 107 additions and 30 deletions
+12 -14
View File
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AzureIntegration } from '@backstage/integration';
import { ScmAuthApi } from '@backstage/integration-react';
import { ConfigApi } from '@backstage/core-plugin-api';
import { getBranchName, getCatalogFilename } from '../components/helpers';
import { createAzurePullRequest } from './AzureRepoApiClient';
import parseGitUrl from 'git-url-parse';
import { parseRepoUrl } from './util';
export interface AzureRepoParts {
tenantUrl: string;
@@ -26,17 +25,19 @@ export interface AzureRepoParts {
project: string;
}
export function parseAzureUrl(
repoUrl: string,
integration: AzureIntegration,
): AzureRepoParts {
const { organization, owner, name } = parseGitUrl(repoUrl);
const tenantUrl = `https://${integration.config.host}/${organization}`;
return { tenantUrl, repoName: name, project: owner };
export function parseAzureUrl(repoUrl: string): AzureRepoParts {
const { org, repo, project, host } = parseRepoUrl(repoUrl);
if (!org || !repo || !project) {
throw new Error(
'Invalid AzureDevops Repository. Please use a valid repository url and try again ',
);
}
const tenantUrl = `https://${host}/${org}`;
return { tenantUrl, repoName: repo, project: project };
}
export async function submitAzurePrToRepo(
integration: AzureIntegration,
options: {
title: string;
body: string;
@@ -57,10 +58,7 @@ export async function submitAzurePrToRepo(
repoWrite: true,
},
});
const { tenantUrl, repoName, project } = parseAzureUrl(
repositoryUrl,
integration,
);
const { tenantUrl, repoName, project } = parseAzureUrl(repositoryUrl);
const result = await createAzurePullRequest({
token,
fileContent,
@@ -21,7 +21,6 @@ import {
IdentityApi,
} from '@backstage/core-plugin-api';
import {
AzureIntegration,
GithubIntegration,
ScmIntegrationRegistry,
} from '@backstage/integration';
@@ -208,7 +207,6 @@ the component will become available.\n\nFor more information, read an \
}
case 'azure': {
return submitAzurePrToRepo(
provider as AzureIntegration,
{
repositoryUrl,
fileContent,
@@ -0,0 +1,51 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { parseRepoUrl } from './util';
describe('parseRepoUrl', () => {
it('parses Azure DevOps Cloud url', async () => {
const result = parseRepoUrl(
'https://dev.azure.com/organization/project/_git/repository?path=%2Fcatalog-info.yaml',
);
expect(result.host).toEqual('dev.azure.com');
expect(result.org).toEqual('organization');
expect(result.project).toEqual('project');
expect(result.repo).toEqual('repository');
});
it('parses Azure DevOps Server url', async () => {
const result = parseRepoUrl(
'https://server.com/organization/project/_git/repository?path=%2Fcatalog-info.yaml',
);
expect(result.host).toEqual('server.com');
expect(result.org).toEqual('organization');
expect(result.project).toEqual('project');
expect(result.repo).toEqual('repository');
});
it('parses TFS subpath Url', async () => {
const result = parseRepoUrl(
'https://server.com/tfs/organization/project/_git/repository?path=%2Fcatalog-info.yaml',
);
expect(result.host).toEqual('server.com/tfs');
expect(result.org).toEqual('organization');
expect(result.project).toEqual('project');
expect(result.repo).toEqual('repository');
});
});
+40
View File
@@ -0,0 +1,40 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export function parseRepoUrl(sourceUrl: string) {
const url = new URL(sourceUrl);
let host = url.host;
let org;
let project;
let repo;
const parts = url.pathname.split('/').map(part => decodeURIComponent(part));
if (parts[2] === '_git') {
org = parts[1];
project = repo = parts[3];
} else if (parts[3] === '_git') {
org = parts[1];
project = parts[2];
repo = parts[4];
} else if (parts[4] === '_git') {
host = `${host}/${parts[1]}`;
org = parts[2];
project = parts[3];
repo = parts[5];
}
return { host, org, project, repo };
}
@@ -29,8 +29,7 @@ import { useCatalogFilename } from '../../hooks';
*/
export interface ImportInfoCardProps {
exampleLocationUrl?: string;
exampleGitRepositoryUrl?: string;
exampleAzureRepositoryUrl?: string;
exampleRepositoryUrl?: string;
}
/**
@@ -41,8 +40,7 @@ export interface ImportInfoCardProps {
export const ImportInfoCard = (props: ImportInfoCardProps) => {
const {
exampleLocationUrl = 'https://github.com/backstage/backstage/blob/master/catalog-info.yaml',
exampleGitRepositoryUrl = 'https://github.com/backstage/backstage',
exampleAzureRepositoryUrl = 'https://dev.azure.com/org-name/project-name/_git/repo-name,
exampleRepositoryUrl = 'https://github.com/backstage/backstage',
} = props;
const configApi = useApi(configApiRef);
@@ -79,18 +77,10 @@ export const ImportInfoCard = (props: ImportInfoCardProps) => {
<>
<Typography component="h4" variant="h6">
Link to a repository{' '}
<Chip
label="GitHub and Azure DevOps"
variant="outlined"
size="small"
/>
</Typography>
<Typography variant="subtitle2" color="textSecondary" paragraph>
GitHub Example: <code>{exampleGitRepositoryUrl}</code>
<Chip label="GitHub only" variant="outlined" size="small" />
</Typography>
<Typography variant="subtitle2" color="textSecondary" paragraph>
Azure Example: <code>{exampleAzureRepositoryUrl}</code>
Example: <code>{exampleRepositoryUrl}</code>
</Typography>
<Typography variant="body2" paragraph>
The wizard discovers all <code>{catalogFilename}</code> files in the