chore: use alt url parser
Signed-off-by: Andrei Ivanovici <andrei.ivanovici@gmail.com>
This commit is contained in:
@@ -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');
|
||||
});
|
||||
});
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user