diff --git a/src/constants.ts b/src/constants.ts index 2d729fd..316b8fd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -6,7 +6,7 @@ export const EXTENSION = { export const CONFIGURATION = { section: EXTENSION.id, linkType: 'linkType', - defaultBranch: 'defaultBranch', + customBranch: 'customBranch', showCopy: 'showCopy', showOpen: 'showOpen' }; diff --git a/src/link-handler.ts b/src/link-handler.ts index b8fef39..5cb263f 100644 --- a/src/link-handler.ts +++ b/src/link-handler.ts @@ -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 @@ -211,9 +211,12 @@ 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 { + private async getRef(type: LinkType, repositoryRoot: string, remoteName: string): Promise { + const remoteBranch = new RegExp(`^${remoteName}/`); + switch (type) { case 'branch': return (await git(repositoryRoot, ...this.definition.branch, 'HEAD')).trim(); @@ -221,8 +224,11 @@ export class LinkHandler { 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(); } } diff --git a/src/repository-finder.ts b/src/repository-finder.ts index 8252638..81395dc 100644 --- a/src/repository-finder.ts +++ b/src/repository-finder.ts @@ -154,15 +154,14 @@ export class RepositoryFinder { * @returns The `Repository` object. */ private async createRepository(root: string): Promise { - 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 }; } /** @@ -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 { + private async findRemote(root: string): Promise { let data: string; let remotes: Remote[]; let remote: Remote; @@ -249,7 +248,7 @@ export class RepositoryFinder { remote = remotes.sort((x, y) => x.name.localeCompare(y.name))[0]; } - return remote?.url; + return remote; } /** diff --git a/src/settings.ts b/src/settings.ts index b659cf4..2fb480f 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -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(CONFIGURATION.defaultBranch) ?? 'master'; + public getCustomBranch(): string { + return this.getConfiguration().get(CONFIGURATION.customBranch) ?? 'master'; } /** diff --git a/src/types.ts b/src/types.ts index d1dc0e3..404ad96 100644 --- a/src/types.ts +++ b/src/types.ts @@ -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. @@ -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; } /** @@ -28,6 +33,11 @@ export type RepositoryWithRemote = Omit & { * The URL of the default remote. */ readonly remote: string; + + /** + * The name of the default remote. + */ + readonly remoteName: string; }; /** diff --git a/test/commands/get-link-command.test.ts b/test/commands/get-link-command.test.ts index 6ecca65..8efb5c4 100644 --- a/test/commands/get-link-command.test.ts +++ b/test/commands/get-link-command.test.ts @@ -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') @@ -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); @@ -271,6 +271,6 @@ describe('GetLinkCommand', () => { } function getLinkTypes(): (LinkType | undefined)[] { - return ['commit', 'branch', 'defaultBranch', undefined]; + return ['commit', 'branch', 'defaultBranch', 'customBranch', undefined]; } }); diff --git a/test/commands/go-to-file-command.test.ts b/test/commands/go-to-file-command.test.ts index bd6d700..267db38 100644 --- a/test/commands/go-to-file-command.test.ts +++ b/test/commands/go-to-file-command.test.ts @@ -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[]; diff --git a/test/handlers.test.ts b/test/handlers.test.ts index 1e2b068..df7e2e2 100644 --- a/test/handlers.test.ts +++ b/test/handlers.test.ts @@ -167,7 +167,8 @@ describe('Link handlers', function () { repository = { root: root.path, - remote + remote, + remoteName: 'origin' }; handler = provider.select(repository); diff --git a/test/link-handler.test.ts b/test/link-handler.test.ts index 8202e7b..6aa633d 100644 --- a/test/link-handler.test.ts +++ b/test/link-handler.test.ts @@ -25,7 +25,8 @@ describe('LinkHandler', function () { repository = { root: root.path, - remote: 'http://example.com' + remote: 'http://example.com', + remoteName: 'origin' }; }); @@ -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' ); }); @@ -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'); diff --git a/test/repository-finder.test.ts b/test/repository-finder.test.ts index 3f129ee..3dce3a2 100644 --- a/test/repository-finder.test.ts +++ b/test/repository-finder.test.ts @@ -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' }); }); @@ -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' }); }); @@ -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' }); }); @@ -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' }); }); @@ -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' }); }); @@ -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' }); }); @@ -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' } ]); }); diff --git a/test/settings.test.ts b/test/settings.test.ts index 4da737e..855fe86 100644 --- a/test/settings.test.ts +++ b/test/settings.test.ts @@ -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'); }); }); diff --git a/test/utilities.test.ts b/test/utilities.test.ts index a07bb1b..4de368b 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -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; }); });