import type { Uri } from 'vscode';
|
|
import { isLinux } from '@env/platform';
|
|
import { Schemes } from './constants';
|
|
import type { Repository } from './git/models/repository';
|
|
import { addVslsPrefixIfNeeded, normalizePath } from './system/path';
|
|
import { UriTrie } from './system/trie';
|
|
// TODO@eamodio don't import from string here since it will break the tests because of ESM dependencies
|
|
// import { CharCode } from './string';
|
|
|
|
const slash = 47; //CharCode.Slash;
|
|
|
|
export type RepoComparisonKey = string & { __type__: 'RepoComparisonKey' };
|
|
|
|
export function asRepoComparisonKey(uri: Uri): RepoComparisonKey {
|
|
const { path } = normalizeRepoUri(uri);
|
|
return path as RepoComparisonKey;
|
|
}
|
|
|
|
export function normalizeRepoUri(uri: Uri): { path: string; ignoreCase: boolean } {
|
|
let path;
|
|
switch (uri.scheme.toLowerCase()) {
|
|
case Schemes.File:
|
|
path = normalizePath(uri.fsPath);
|
|
return { path: path, ignoreCase: !isLinux };
|
|
|
|
case Schemes.Git:
|
|
case Schemes.GitLens:
|
|
path = uri.path;
|
|
if (path.charCodeAt(path.length - 1) === slash) {
|
|
path = path.slice(1, -1);
|
|
} else {
|
|
path = path.slice(1);
|
|
}
|
|
return { path: path, ignoreCase: !isLinux };
|
|
|
|
case Schemes.Virtual:
|
|
case Schemes.GitHub: {
|
|
path = uri.path;
|
|
if (path.charCodeAt(path.length - 1) === slash) {
|
|
path = path.slice(1, -1);
|
|
} else {
|
|
path = path.slice(1);
|
|
}
|
|
|
|
// TODO@eamodio Revisit this, as we can't strip off the authority details (e.g. metadata) ultimately (since you in theory could have a workspace with more than 1 virtual repo which are the same except for the authority)
|
|
const authority = uri.authority?.split('+', 1)[0];
|
|
return { path: authority ? `${authority}/${path}` : path, ignoreCase: false };
|
|
}
|
|
case Schemes.Vsls:
|
|
case Schemes.VslsScc:
|
|
// Check if this is a root live share folder, if so add the required prefix (required to match repos correctly)
|
|
path = addVslsPrefixIfNeeded(uri.path);
|
|
if (path.charCodeAt(path.length - 1) === slash) {
|
|
path = path.slice(1, -1);
|
|
} else {
|
|
path = path.slice(1);
|
|
}
|
|
|
|
return { path: path, ignoreCase: false };
|
|
|
|
case Schemes.PRs: {
|
|
path = uri.path;
|
|
if (path.charCodeAt(path.length - 1) === slash) {
|
|
path = path.slice(1, -1);
|
|
} else {
|
|
path = path.slice(1);
|
|
}
|
|
|
|
const authority = uri.authority?.split('+', 1)[0];
|
|
if (authority === Schemes.GitHub) {
|
|
return { path: authority ? `${authority}/${path}` : path, ignoreCase: false };
|
|
}
|
|
|
|
return { path: path, ignoreCase: !isLinux };
|
|
}
|
|
default:
|
|
path = uri.path;
|
|
if (path.charCodeAt(path.length - 1) === slash) {
|
|
path = path.slice(1, -1);
|
|
} else {
|
|
path = path.slice(1);
|
|
}
|
|
return { path: path, ignoreCase: false };
|
|
}
|
|
}
|
|
|
|
export class Repositories {
|
|
private readonly _trie: UriTrie<Repository>;
|
|
private _count: number = 0;
|
|
|
|
constructor() {
|
|
this._trie = new UriTrie<Repository>(normalizeRepoUri);
|
|
}
|
|
|
|
get count(): number {
|
|
return this._count;
|
|
}
|
|
|
|
add(repository: Repository): boolean {
|
|
const added = this._trie.set(repository.uri, repository);
|
|
if (added) {
|
|
this._count++;
|
|
}
|
|
return added;
|
|
}
|
|
|
|
clear(): void {
|
|
this._count = 0;
|
|
this._trie.clear();
|
|
}
|
|
|
|
forEach(fn: (repository: Repository) => void, thisArg?: unknown): void {
|
|
for (const value of this._trie.getDescendants()) {
|
|
fn.call(thisArg, value);
|
|
}
|
|
}
|
|
|
|
get(uri: Uri): Repository | undefined {
|
|
return this._trie.get(uri);
|
|
}
|
|
|
|
getClosest(uri: Uri): Repository | undefined {
|
|
return this._trie.getClosest(uri);
|
|
}
|
|
|
|
has(uri: Uri): boolean {
|
|
return this._trie.has(uri);
|
|
}
|
|
|
|
remove(uri: Uri, dispose: boolean = true): boolean {
|
|
const deleted = this._trie.delete(uri, dispose);
|
|
if (deleted) {
|
|
this._count--;
|
|
}
|
|
return deleted;
|
|
}
|
|
|
|
values(): IterableIterator<Repository> {
|
|
return this._trie.getDescendants();
|
|
}
|
|
}
|