Skip to content

Commit

Permalink
Adds bitbucket server support
Browse files Browse the repository at this point in the history
  • Loading branch information
eamodio committed Sep 12, 2017
1 parent 62580da commit 21e0963
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Clicking on `Changes` will run the `Compare File Revisions` command (`gitlens.diffWith`)
- Clicking the current and previous commit ids will run the `Show Commit Details` command (`gitlens.showQuickCommitDetails`)
- Adds support for custom remote services - see [#120](https://github.com/eamodio/vscode-gitlens/issues/120)
- Adds support for Bitbucket Server (previously called Stash) remote services - see [#120](https://github.com/eamodio/vscode-gitlens/issues/120)
- Adds `Compare File Revisions` command (`gitlens.diffWith`) - compares the specified file revisions
- Adds `Open Branches in Remote` command (`gitlens.openBranchesInRemote`) - opens the branches in the supported remote service
- Adds `Stash Changes` command (`gitlens.stashSave`) to the source control group context menu -- can now stash a group of files
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Search Commits` command (`gitlens.showCommitSearch`) with a shortcut of `alt+/` to search for commits by message, author, file(s), or commit id

- Adds commands to open files, commits, branches, and the repository in the supported remote services, currently **BitBucket, GitHub, GitLab, and Visual Studio Team Services** — only available if a Git upstream service is configured in the repository
- Also supports [custom](#custom-remote-settings) remote services, such as **BitBucket, Bitbucket Server (previously called Stash), GitHub, GitLab**
- `Open Branches in Remote` command (`gitlens.openBranchesInRemote`) — opens the branches in the supported remote service
- `Open Branch in Remote` command (`gitlens.openBranchInRemote`) — opens the current branch commits in the supported remote service
- `Open Commit in Remote` command (`gitlens.openCommitInRemote`) — opens the commit revision of the active line in the supported remote service
Expand Down Expand Up @@ -350,7 +351,7 @@ GitLens is highly customizable and provides many configuration settings to allow
|`gitlens.gitExplorer.stashFormat`|Specifies the format of stashed changes in the `GitLens` custom view<br />Available tokens<br /> ${id} - commit id<br /> ${author} - commit author<br /> ${message} - commit message<br /> ${ago} - relative commit date (e.g. 1 day ago)<br /> ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)<br /> ${authorAgo} - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|`gitlens.gitExplorer.stashFileFormat`|Specifies the format of a stashed file in the `GitLens` custom view<br />Available tokens<br /> ${file} - file name<br /> ${filePath} - file name and path<br /> ${path} - file path

### GitLens Custom Remotes Settings
### Custom Remotes Settings

|Name | Description
|-----|------------
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,11 @@
"type": "string",
"enum": [
"Bitbucket",
"BitbucketServer",
"GitHub",
"GitLab"
],
"description": "Specifies the type of the custom remote service\n `Bitbucket`, `GitHub`, or `GitLab`"
"description": "Specifies the type of the custom remote service\n `Bitbucket`, `BitbucketServer`, `GitHub`, or `GitLab`"
},
"domain": {
"type": "string",
Expand Down
1 change: 1 addition & 0 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type CustomRemoteType =
'GitLab';
export const CustomRemoteType = {
Bitbucket: 'Bitbucket' as CustomRemoteType,
BitbucketServer: 'BitbucketServer' as CustomRemoteType,
GitHub: 'GitHub' as CustomRemoteType,
GitLab: 'GitLab' as CustomRemoteType
};
Expand Down
47 changes: 47 additions & 0 deletions src/git/remotes/bitbucket-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';
import { Range } from 'vscode';
import { RemoteProvider } from './provider';

export class BitbucketServerService extends RemoteProvider {

constructor(public domain: string, public path: string, public custom: boolean = false) {
super(domain, path);
}

get name() {
return this.formatName('Bitbucket Server');
}

protected get baseUrl() {
const [project, repo] = super.splitPath();
return `https://${this.domain}/projects/${project}/repos/${repo}`;
}

protected getUrlForBranches(): string {
return `${this.baseUrl}/branches`;
}

protected getUrlForBranch(branch: string): string {
return `${this.baseUrl}/commits?until=${branch}`;
}

protected getUrlForCommit(sha: string): string {
return `${this.baseUrl}/commits/${sha}`;
}

protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line = '';
if (range) {
if (range.start.line === range.end.line) {
line = `#${range.start.line}`;
}
else {
line = `#${range.start.line}-${range.end.line}`;
}
}

if (sha) return `${this.baseUrl}/browse/${fileName}?at=${sha}${line}`;
if (branch) return `${this.baseUrl}/browse/${fileName}?at=${branch}${line}`;
return `${this.baseUrl}/browse/${fileName}${line}`;
}
}
4 changes: 2 additions & 2 deletions src/git/remotes/bitbucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { RemoteProvider } from './provider';

export class BitbucketService extends RemoteProvider {

constructor(public domain: string, public path: string) {
constructor(public domain: string, public path: string, public custom: boolean = false) {
super(domain, path);
}

get name() {
return 'Bitbucket';
return this.formatName('Bitbucket');
}

protected getUrlForBranches(): string {
Expand Down
16 changes: 9 additions & 7 deletions src/git/remotes/factory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';
import { ExtensionContext, workspace } from 'vscode';
import { BitbucketService } from './bitbucket';
import { BitbucketServerService } from './bitbucket-server';
import { CustomRemoteType, IConfig, IRemotesConfig } from '../../configuration';
import { ExtensionKey } from '../../constants';
import { GitHubService } from './github';
Expand All @@ -14,11 +15,12 @@ export { RemoteProvider };

const UrlRegex = /^(?:git:\/\/(.*?)\/|https:\/\/(.*?)\/|http:\/\/(.*?)\/|git@(.*):|ssh:\/\/(?:.*@)?(.*?)(?::.*?)?\/)(.*)$/;

function getProviderKey(type: CustomRemoteType) {
function getCustomProvider(type: CustomRemoteType) {
switch (type) {
case CustomRemoteType.Bitbucket: return 'bitbucket.org';
case CustomRemoteType.GitHub: return 'github.com';
case CustomRemoteType.GitLab: return 'gitlab.com';
case CustomRemoteType.Bitbucket: return (domain: string, path: string) => new BitbucketService(domain, path, true);
case CustomRemoteType.BitbucketServer: return (domain: string, path: string) => new BitbucketServerService(domain, path, true);
case CustomRemoteType.GitHub: return (domain: string, path: string) => new GitHubService(domain, path, true);
case CustomRemoteType.GitLab: return (domain: string, path: string) => new GitLabService(domain, path, true);
}
return undefined;
}
Expand All @@ -43,10 +45,10 @@ function onConfigurationChanged() {
remotesCfg = cfg.remotes;
if (remotesCfg != null && remotesCfg.length > 0) {
for (const svc of remotesCfg) {
const key = getProviderKey(svc.type);
if (key === undefined) continue;
const provider = getCustomProvider(svc.type);
if (provider === undefined) continue;

providerMap.set(svc.domain.toLowerCase(), providerMap.get(key)!);
providerMap.set(svc.domain.toLowerCase(), provider);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/git/remotes/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { RemoteProvider } from './provider';

export class GitHubService extends RemoteProvider {

constructor(public domain: string, public path: string) {
constructor(public domain: string, public path: string, public custom: boolean = false) {
super(domain, path);
}

get name() {
return 'GitHub';
return this.formatName('GitHub');
}

protected getUrlForBranches(): string {
Expand Down
4 changes: 2 additions & 2 deletions src/git/remotes/gitlab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { GitHubService } from './github';

export class GitLabService extends GitHubService {

constructor(public domain: string, public path: string) {
constructor(public domain: string, public path: string, public custom: boolean = false) {
super(domain, path);
}

get name() {
return 'GitLab';
return this.formatName('GitLab');
}
}
11 changes: 10 additions & 1 deletion src/git/remotes/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,23 @@ export function getNameFromRemoteResource(resource: RemoteResource) {

export abstract class RemoteProvider {

constructor(public domain: string, public path: string) { }
constructor(public domain: string, public path: string, public custom: boolean = false) { }

abstract get name(): string;

protected get baseUrl() {
return `https://${this.domain}/${this.path}`;
}

protected formatName(name: string) {
return `${name}${this.custom ? ` (${this.domain})` : ''}`;
}

protected splitPath(): [string, string] {
const index = this.path.indexOf('/');
return [ this.path.substring(0, index), this.path.substring(index + 1) ];
}

protected abstract getUrlForBranches(): string;
protected abstract getUrlForBranch(branch: string): string;
protected abstract getUrlForCommit(sha: string): string;
Expand Down

0 comments on commit 21e0963

Please sign in to comment.