feat(gerrit-integration): use gitiles archive for readTree if configured
If Gitiles is configured, leverage it to fetch an archive instead of cloning the repository. Co-Authored-By: Andy Ladjadj <andy.ladjadj@adevinta.com> Signed-off-by: Thomas Cardonne <thomas.cardonne@adevinta.com>
This commit is contained in:
@@ -172,6 +172,14 @@ export type BitbucketServerIntegrationConfig = {
|
||||
password?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
export function buildGerritGitilesArchiveUrl(
|
||||
config: GerritIntegrationConfig,
|
||||
project: string,
|
||||
branch: string,
|
||||
filePath: string,
|
||||
): string;
|
||||
|
||||
// @public
|
||||
export class DefaultGithubCredentialsProvider
|
||||
implements GithubCredentialsProvider
|
||||
|
||||
@@ -20,6 +20,7 @@ import fetch from 'cross-fetch';
|
||||
import { setupRequestMockHandlers } from '../helpers';
|
||||
import { GerritIntegrationConfig } from './config';
|
||||
import {
|
||||
buildGerritGitilesArchiveUrl,
|
||||
buildGerritGitilesUrl,
|
||||
getGerritBranchApiUrl,
|
||||
getGerritCloneRepoUrl,
|
||||
@@ -33,6 +34,41 @@ describe('gerrit core', () => {
|
||||
const worker = setupServer();
|
||||
setupRequestMockHandlers(worker);
|
||||
|
||||
describe('buildGerritGitilesArchiveUrl', () => {
|
||||
const config: GerritIntegrationConfig = {
|
||||
host: 'gerrit.com',
|
||||
gitilesBaseUrl: 'https://gerrit.com/gitiles',
|
||||
};
|
||||
it('can create an archive url for a branch', () => {
|
||||
expect(buildGerritGitilesArchiveUrl(config, 'repo', 'dev', '')).toEqual(
|
||||
'https://gerrit.com/gitiles/repo/+archive/refs/heads/dev.tar.gz',
|
||||
);
|
||||
|
||||
expect(buildGerritGitilesArchiveUrl(config, 'repo', 'dev', '/')).toEqual(
|
||||
'https://gerrit.com/gitiles/repo/+archive/refs/heads/dev.tar.gz',
|
||||
);
|
||||
});
|
||||
it('can create an archive url for a specific directory', () => {
|
||||
expect(
|
||||
buildGerritGitilesArchiveUrl(config, 'repo', 'dev', 'docs'),
|
||||
).toEqual(
|
||||
'https://gerrit.com/gitiles/repo/+archive/refs/heads/dev/docs.tar.gz',
|
||||
);
|
||||
});
|
||||
it('can create an authenticated url when auth is enabled', () => {
|
||||
const authConfig = {
|
||||
...config,
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
};
|
||||
expect(
|
||||
buildGerritGitilesArchiveUrl(authConfig, 'repo', 'dev', 'docs'),
|
||||
).toEqual(
|
||||
'https://gerrit.com/a/gitiles/repo/+archive/refs/heads/dev/docs.tar.gz',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildGerritGitilesUrl', () => {
|
||||
it('can create an url from arguments', () => {
|
||||
const config: GerritIntegrationConfig = {
|
||||
@@ -86,6 +122,25 @@ describe('gerrit core', () => {
|
||||
);
|
||||
expect(rootPath).toEqual('/');
|
||||
});
|
||||
it('can parse a valid authenticated gitiles url.', () => {
|
||||
const config: GerritIntegrationConfig = {
|
||||
host: 'gerrit.com',
|
||||
gitilesBaseUrl: 'https://gerrit.com/gitiles',
|
||||
};
|
||||
const { branch, filePath, project } = parseGerritGitilesUrl(
|
||||
config,
|
||||
'https://gerrit.com/a/gitiles/web/project/+/refs/heads/master/README.md',
|
||||
);
|
||||
expect(project).toEqual('web/project');
|
||||
expect(branch).toEqual('master');
|
||||
expect(filePath).toEqual('README.md');
|
||||
|
||||
const { filePath: rootPath } = parseGerritGitilesUrl(
|
||||
config,
|
||||
'https://gerrit.com/gitiles/web/project/+/refs/heads/master',
|
||||
);
|
||||
expect(rootPath).toEqual('/');
|
||||
});
|
||||
it('throws on incorrect gitiles urls.', () => {
|
||||
const config: GerritIntegrationConfig = {
|
||||
host: 'gerrit.com',
|
||||
|
||||
@@ -37,6 +37,7 @@ const GERRIT_BODY_PREFIX = ")]}'";
|
||||
*
|
||||
* Gitiles url:
|
||||
* https://g.com/optional_path/\{project\}/+/refs/heads/\{branch\}/\{filePath\}
|
||||
* https://g.com/a/optional_path/\{project\}/+/refs/heads/\{branch\}/\{filePath\}
|
||||
*
|
||||
*
|
||||
* @param url - An URL pointing to a file stored in git.
|
||||
@@ -47,7 +48,17 @@ export function parseGerritGitilesUrl(
|
||||
config: GerritIntegrationConfig,
|
||||
url: string,
|
||||
): { branch: string; filePath: string; project: string } {
|
||||
const urlPath = url.replace(config.gitilesBaseUrl!, '');
|
||||
const baseUrlParse = new URL(config.gitilesBaseUrl!);
|
||||
const urlParse = new URL(url);
|
||||
|
||||
// Remove the gerrit authentication prefix '/a/' from the url
|
||||
// In case of the gitilesBaseUrl is https://review.gerrit.com/plugins/gitiles
|
||||
// and the url provided is https://review.gerrit.com/a/plugins/gitiles/...
|
||||
// remove the prefix only if the pathname start with '/a/'
|
||||
const urlPath = urlParse.pathname
|
||||
.substring(urlParse.pathname.startsWith('/a/') ? 2 : 0)
|
||||
.replace(baseUrlParse.pathname, '');
|
||||
|
||||
const parts = urlPath.split('/').filter(p => !!p);
|
||||
|
||||
const projectEndIndex = parts.indexOf('+');
|
||||
@@ -91,6 +102,28 @@ export function buildGerritGitilesUrl(
|
||||
}/${project}/+/refs/heads/${branch}/${trimStart(filePath, '/')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Gerrit Gitiles archive url that targets a specific branch and path
|
||||
*
|
||||
* @param config - A Gerrit provider config.
|
||||
* @param project - The name of the git project
|
||||
* @param branch - The branch we will target.
|
||||
* @param filePath - The absolute file path.
|
||||
* @public
|
||||
*/
|
||||
export function buildGerritGitilesArchiveUrl(
|
||||
config: GerritIntegrationConfig,
|
||||
project: string,
|
||||
branch: string,
|
||||
filePath: string,
|
||||
): string {
|
||||
const archiveName =
|
||||
filePath === '/' || filePath === '' ? '.tar.gz' : `/${filePath}.tar.gz`;
|
||||
return `${getGitilesAuthenticationUrl(
|
||||
config,
|
||||
)}/${project}/+archive/refs/heads/${branch}${archiveName}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authentication prefix.
|
||||
*
|
||||
@@ -109,6 +142,27 @@ export function getAuthenticationPrefix(
|
||||
return config.password ? '/a/' : '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authentication gitiles url.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* To authenticate with a password the API url must be prefixed with "/a/".
|
||||
* If no password is set anonymous access (without the prefix) will
|
||||
* be used.
|
||||
*
|
||||
* @param config - A Gerrit provider config.
|
||||
* @public
|
||||
*/
|
||||
export function getGitilesAuthenticationUrl(
|
||||
config: GerritIntegrationConfig,
|
||||
): string {
|
||||
const parsedUrl = new URL(config.gitilesBaseUrl!);
|
||||
return `${parsedUrl.protocol}//${parsedUrl.host}${getAuthenticationPrefix(
|
||||
config,
|
||||
)}${parsedUrl.pathname.substring(1)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the url to get branch info from the Gerrit API.
|
||||
*
|
||||
|
||||
@@ -19,6 +19,7 @@ export {
|
||||
readGerritIntegrationConfigs,
|
||||
} from './config';
|
||||
export {
|
||||
buildGerritGitilesArchiveUrl,
|
||||
getGerritBranchApiUrl,
|
||||
getGerritCloneRepoUrl,
|
||||
getGerritFileContentsApiUrl,
|
||||
|
||||
Reference in New Issue
Block a user