Skip to content

Commit

Permalink
Reworks Azure DevOps remote parsing
Browse files Browse the repository at this point in the history
Fixes vs-ssh domain issue
Adds better display path for ADO remotes
Adds full urls to remote tooltips
  • Loading branch information
eamodio committed Jan 23, 2019
1 parent 070aa8e commit c4a83e7
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 24 deletions.
8 changes: 5 additions & 3 deletions src/git/parsers/remoteParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,17 @@ export class GitRemoteParser {
const uniqueness = `${domain}/${path}`;
let remote: GitRemote | undefined = groups[uniqueness];
if (remote === undefined) {
const provider = providerFactory(domain, path);

remote = new GitRemote(
repoPath,
uniqueness,
// Stops excessive memory usage -- https://bugs.chromium.org/p/v8/issues/detail?id=2869
(' ' + match[1]).substr(1),
scheme,
domain,
path,
providerFactory(domain, path),
provider !== undefined ? provider.domain : domain,
provider !== undefined ? provider.path : path,
provider,
// Stops excessive memory usage -- https://bugs.chromium.org/p/v8/issues/detail?id=2869
[{ url: url, type: (' ' + match[3]).substr(1) as GitRemoteType }]
);
Expand Down
50 changes: 33 additions & 17 deletions src/git/remotes/azure-devops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,36 @@ import { Range } from 'vscode';
import { RemoteProvider } from './provider';

const issueEnricherRegex = /(^|\s)(#([0-9]+))\b/gi;
const stripGitRegex = /\/_git\/?/i;

const sshDomainRegex = /^ssh\./i;
const gitRegex = /\/_git\/?/i;
const legacyDefaultCollectionRegex = /^DefaultCollection\//i;
const orgAndProjectRegex = /^(.*?)\/(.*?)\/(.*)/;
const sshDomainRegex = /^(ssh|vs-ssh)\./i;
const sshPathRegex = /^\/?v\d\//i;

export class AzureDevOpsRemote extends RemoteProvider {
constructor(domain: string, path: string, protocol?: string, name?: string) {
domain = domain.replace(sshDomainRegex, '');
path = path.replace(sshPathRegex, '').replace(stripGitRegex, '/');
constructor(domain: string, path: string, protocol?: string, name?: string, legacy: boolean = false) {
if (sshDomainRegex.test(domain)) {
path = path.replace(sshPathRegex, '');
domain = domain.replace(sshDomainRegex, '');

super(domain, path, protocol, name);
}
// Add in /_git/ into ssh urls
const match = orgAndProjectRegex.exec(path);
if (match != null) {
const [, org, project, rest] = match;

// Handle legacy vsts urls
if (legacy) {
domain = `${org}.${domain}`;
path = `${project}/_git/${rest}`;
}
else {
path = `${org}/${project}/_git/${rest}`;
}
}
}

get baseUrl() {
const [orgAndProject, repo] = this.splitPath();
return `https://${this.domain}/${orgAndProject}/_git/${repo}`;
super(domain, path, protocol, name);
}

get icon() {
Expand All @@ -29,9 +43,17 @@ export class AzureDevOpsRemote extends RemoteProvider {
return 'Azure DevOps';
}

private _displayPath: string | undefined;
get displayPath(): string {
if (this._displayPath === undefined) {
this._displayPath = this.path.replace(gitRegex, '/').replace(legacyDefaultCollectionRegex, '');
}
return this._displayPath;
}

enrichMessage(message: string): string {
// Strip off any `_git` part from the repo url
const baseUrl = this.baseUrl.replace(stripGitRegex, '/');
const baseUrl = this.baseUrl.replace(gitRegex, '/');
// Matches #123
return message.replace(issueEnricherRegex, `$1[$2](${baseUrl}/_workitems/edit/$3 "Open Work Item $2")`);
}
Expand Down Expand Up @@ -63,10 +85,4 @@ export class AzureDevOpsRemote extends RemoteProvider {
if (branch) return `${this.baseUrl}/?path=%2F${fileName}&version=GB${branch}&_a=contents${line}`;
return `${this.baseUrl}?path=%2F${fileName}${line}`;
}

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

}
5 changes: 4 additions & 1 deletion src/git/remotes/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ const defaultProviders: RemoteProviders = [
[/\bdev\.azure\.com$/i, (domain: string, path: string) => new AzureDevOpsRemote(domain, path)],
[/\bbitbucket\b/i, (domain: string, path: string) => new BitbucketServerRemote(domain, path)],
[/\bgitlab\b/i, (domain: string, path: string) => new GitLabRemote(domain, path)],
[/\bvisualstudio\.com$/i, (domain: string, path: string) => new AzureDevOpsRemote(domain, path)]
[
/\bvisualstudio\.com$/i,
(domain: string, path: string) => new AzureDevOpsRemote(domain, path, undefined, undefined, true)
]
];

export class RemoteProviderFactory {
Expand Down
4 changes: 4 additions & 0 deletions src/git/remotes/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export abstract class RemoteProvider {
return 'remote';
}

get displayPath(): string {
return this.path;
}

abstract get name(): string;

protected get baseUrl() {
Expand Down
12 changes: 9 additions & 3 deletions src/views/nodes/remoteNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ export class RemoteNode extends ViewNode<RepositoriesView> {
);
item.description = `${separator}${GlyphChars.Space} ${
this.remote.provider !== undefined ? this.remote.provider.name : this.remote.domain
} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${this.remote.path}`;
} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${
this.remote.provider !== undefined ? this.remote.provider.displayPath : this.remote.path
}`;
item.contextValue = ResourceType.Remote;
if (this.remote.default) {
item.contextValue += '+default';
Expand All @@ -110,9 +112,13 @@ export class RemoteNode extends ViewNode<RepositoriesView> {
}

item.id = this.id;
item.tooltip = `${this.remote.name}\n${this.remote.path} (${
item.tooltip = `${this.remote.name} (${
this.remote.provider !== undefined ? this.remote.provider.name : this.remote.domain
})`;
})\n${this.remote.provider !== undefined ? this.remote.provider.displayPath : this.remote.path}\n`;

for (const type of this.remote.types) {
item.tooltip += `\n${type.url} (${type.type})`;
}

return item;
}
Expand Down

0 comments on commit c4a83e7

Please sign in to comment.