Skip to content

Commit

Permalink
Get default branch name from git
Browse files Browse the repository at this point in the history
  • Loading branch information
kvart714 committed Mar 29, 2021
1 parent 7d22992 commit 6ba265e
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const EXTENSION = {
export const CONFIGURATION = {
section: EXTENSION.id,
linkType: 'linkType',
defaultBranch: 'defaultBranch',
customBranch: 'customBranch',
showCopy: 'showCopy',
showOpen: 'showOpen'
};
Expand Down
14 changes: 10 additions & 4 deletions src/link-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ export class LinkHandler {
data = {
base: address.http,
repository: this.getRepositoryPath(remote, address),
ref: await this.getRef(type, repository.root),
commit: await this.getRef('commit', repository.root),
ref: await this.getRef(type, repository.root, repository.remoteName),
commit: await this.getRef('commit', repository.root, repository.remoteName),
file: await this.getRelativePath(repository.root, file.filePath),
type: type === 'commit' ? 'commit' : 'branch',
...file.selection
Expand Down Expand Up @@ -211,18 +211,24 @@ export class LinkHandler {
*
* @param type The type of ref to get.
* @param repositoryRoot The path to the root of the repository.
* @param remoteName The name of default remote.
* @returns The ref to use.
*/
private async getRef(type: LinkType, repositoryRoot: string): Promise<string> {
private async getRef(type: LinkType, repositoryRoot: string, remoteName: string): Promise<string> {
const remoteBranch = new RegExp(`^${remoteName}/`);

switch (type) {
case 'branch':
return (await git(repositoryRoot, ...this.definition.branch, 'HEAD')).trim();

case 'commit':
return (await git(repositoryRoot, 'rev-parse', 'HEAD')).trim();

case 'defaultBranch':
return (await git(repositoryRoot, ...this.definition.branch, remoteName)).replace(remoteBranch, '').trim()

default:
return this.settings.getDefaultBranch();
return this.settings.getCustomBranch();
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/repository-finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,14 @@ export class RepositoryFinder {
* @returns The `Repository` object.
*/
private async createRepository(root: string): Promise<Repository> {
let remote: string | undefined;

log("Finding remote URL for '%s'...", root);

remote = await this.findRemote(root);
let remote = await this.findRemote(root);

log("Remote URL is '%s'.", remote ?? '');

return { root, remote };
return { root, remoteName: remote?.name, remote: remote?.url };
}

/**
Expand Down Expand Up @@ -225,7 +224,7 @@ export class RepositoryFinder {
* @param root The root of the repository.
* @returns The URL of the "origin" remote if it exists, otherwise the first remote alphabetically, or `undefined` if there are no remotes.
*/
private async findRemote(root: string): Promise<string | undefined> {
private async findRemote(root: string): Promise<Remote | undefined> {
let data: string;
let remotes: Remote[];
let remote: Remote;
Expand All @@ -249,7 +248,7 @@ export class RepositoryFinder {
remote = remotes.sort((x, y) => x.name.localeCompare(y.name))[0];
}

return remote?.url;
return remote;
}

/**
Expand Down
11 changes: 7 additions & 4 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,21 @@ export class Settings {
case 'defaultBranch':
return 'defaultBranch';

case 'customBranch':
return 'customBranch';

default:
return 'commit';
}
}

/**
* Gets the name of the branch to use when producing a link for the default branch.
* Gets the name of the branch to use when producing a link for the custom branch.
*
* @returns The name of the default branch.
* @returns The name of the custom branch.
*/
public getDefaultBranch(): string {
return this.getConfiguration().get<string>(CONFIGURATION.defaultBranch) ?? 'master';
public getCustomBranch(): string {
return this.getConfiguration().get<string>(CONFIGURATION.customBranch) ?? 'master';
}

/**
Expand Down
12 changes: 11 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { StaticServer } from './schema';
/**
* The type of link to generate.
*/
export type LinkType = 'commit' | 'branch' | 'defaultBranch';
export type LinkType = 'commit' | 'branch' | 'defaultBranch' | 'customBranch';

/**
* Information about a Git repository.
Expand All @@ -18,6 +18,11 @@ export interface Repository {
* The URL to the default remote, or `undefined` if the repository has no remotes.
*/
readonly remote: string | undefined;

/**
* The name of the default remote.
*/
readonly remoteName: string | undefined;
}

/**
Expand All @@ -28,6 +33,11 @@ export type RepositoryWithRemote = Omit<Repository, 'remote'> & {
* The URL of the default remote.
*/
readonly remote: string;

/**
* The name of the default remote.
*/
readonly remoteName: string;
};

/**
Expand Down
6 changes: 3 additions & 3 deletions test/commands/get-link-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('GetLinkCommand', () => {

file = Uri.file('/foo/bar');
folder = Uri.file('/foo');
repository = { root: folder.toString(), remote: 'http://example.com' };
repository = { root: folder.toString(), remote: 'http://example.com', remoteName: 'origin' };

showErrorMessage = sinon
.stub(window, 'showErrorMessage')
Expand Down Expand Up @@ -98,7 +98,7 @@ describe('GetLinkCommand', () => {
});

it('should show an error if the repository does not have a remote.', async () => {
repository = { root: folder.toString(), remote: undefined };
repository = { root: folder.toString(), remote: undefined, remoteName: undefined };

command = createCommand({ linkType: 'commit', includeSelection: true, action: 'copy' });
await command.execute(file);
Expand Down Expand Up @@ -271,6 +271,6 @@ describe('GetLinkCommand', () => {
}

function getLinkTypes(): (LinkType | undefined)[] {
return ['commit', 'branch', 'defaultBranch', undefined];
return ['commit', 'branch', 'defaultBranch', 'customBranch', undefined];
}
});
2 changes: 1 addition & 1 deletion test/commands/go-to-file-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ describe('GoToFileLinkCommand', () => {
}

if (folder.repository) {
currentRepository = { root: path, remote: folder.repository };
currentRepository = { root: path, remote: folder.repository, remoteName: 'origin' };

if (currentWorkspace) {
let workspaceRepositories: Repository[];
Expand Down
3 changes: 2 additions & 1 deletion test/handlers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ describe('Link handlers', function () {

repository = {
root: root.path,
remote
remote,
remoteName: 'origin'
};

handler = provider.select(repository);
Expand Down
12 changes: 7 additions & 5 deletions test/link-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ describe('LinkHandler', function () {

repository = {
root: root.path,
remote: 'http://example.com'
remote: 'http://example.com',
remoteName: 'origin'
};
});

Expand Down Expand Up @@ -73,12 +74,12 @@ describe('LinkHandler', function () {
).to.equal('foo');
});

it('should use the default branch name as the "ref" value when the link type is "defaultBranch".', async () => {
sinon.stub(Settings.prototype, 'getDefaultBranch').returns('bar');
it('should use the custom branch name as the "ref" value when the link type is "customBranch".', async () => {
sinon.stub(Settings.prototype, 'getCustomBranch').returns('bar');

await setupRepository(root.path);

expect(await createUrl({ url: '{{ ref }}' }, { type: 'defaultBranch' })).to.equal(
expect(await createUrl({ url: '{{ ref }}' }, { type: 'customBranch' })).to.equal(
'bar'
);
});
Expand Down Expand Up @@ -322,7 +323,8 @@ describe('LinkHandler', function () {

repository = {
root: link,
remote: 'http://example.com'
remote: 'http://example.com',
remoteName: 'origin'
};

foo = path.join(real, 'foo.js');
Expand Down
12 changes: 9 additions & 3 deletions test/repository-finder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ describe('RepositoryFinder', function () {

expect(await finder.findRepository(root.path)).to.deep.equal({
root: root.path,
remoteName: 'origin',
remote: 'https://github.com/example/repo'
});
});
Expand All @@ -108,6 +109,7 @@ describe('RepositoryFinder', function () {

expect(await finder.findRepository(child)).to.deep.equal({
root: root.path,
remoteName: 'origin',
remote: 'https://github.com/example/repo'
});
});
Expand All @@ -123,6 +125,7 @@ describe('RepositoryFinder', function () {

expect(await finder.findRepository(file)).to.deep.equal({
root: root.path,
remoteName: 'origin',
remote: 'https://github.com/example/repo'
});
});
Expand All @@ -135,6 +138,7 @@ describe('RepositoryFinder', function () {

expect(await finder.findRepository(worktree.path)).to.deep.equal({
root: worktree.path,
remoteName: 'origin',
remote: 'https://github.com/example/repo'
});
});
Expand All @@ -147,6 +151,7 @@ describe('RepositoryFinder', function () {

expect(await finder.findRepository(root.path)).to.deep.equal({
root: root.path,
remoteName: 'origin',
remote: 'https://github.com/example/repo'
});
});
Expand All @@ -159,6 +164,7 @@ describe('RepositoryFinder', function () {

expect(await finder.findRepository(root.path)).to.deep.equal({
root: root.path,
remoteName: 'alpha',
remote: 'https://github.com/example/alpha'
});
});
Expand Down Expand Up @@ -268,9 +274,9 @@ describe('RepositoryFinder', function () {
repositories.sort((x, y) => x.root.localeCompare(y.root));

expect(repositories).to.deep.equal([
{ root: alpha, remote: 'https://github.com/example/alpha' },
{ root: beta, remote: undefined },
{ root: gamma, remote: 'https://github.com/example/gamma' }
{ root: alpha, remoteName: 'origin', remote: 'https://github.com/example/alpha' },
{ root: beta, remoteName: undefined, remote: undefined },
{ root: gamma, remoteName: 'origin', remote: 'https://github.com/example/gamma' }
]);
});

Expand Down
10 changes: 5 additions & 5 deletions test/settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ describe('Settings', () => {
});
});

describe('getDefaultBranch', () => {
describe('getCustomBranch', () => {
it('should return "master" if there is no stored value.', () => {
setup({ defaultBranch: undefined });
expect(settings.getDefaultBranch()).to.equal('master');
setup({ customBranch: undefined });
expect(settings.getCustomBranch()).to.equal('master');
});

it('should return the stored value when it exists.', () => {
setup({ defaultBranch: 'foo' });
expect(settings.getDefaultBranch()).to.equal('foo');
setup({ customBranch: 'foo' });
expect(settings.getCustomBranch()).to.equal('foo');
});
});

Expand Down
4 changes: 2 additions & 2 deletions test/utilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { hasRemote, normalizeUrl } from '../src/utilities';
describe('utilities', () => {
describe('hasRemote', () => {
it('returns true when repository has a remote.', () => {
expect(hasRemote({ remote: 'a', root: 'b' })).to.be.true;
expect(hasRemote({ remote: 'a', root: 'b', remoteName: 'origin' })).to.be.true;
});

it('returns false when repository does not have a remote.', () => {
expect(hasRemote({ remote: undefined, root: 'b' })).to.be.false;
expect(hasRemote({ remote: undefined, root: 'b', remoteName: 'origin' })).to.be.false;
});
});

Expand Down

0 comments on commit 6ba265e

Please sign in to comment.