Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
- run: npm run eslint
- run: npm run build
- uses: microsoft/playwright-github-action@v1
- run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} npm run test:ci
- run: npm run test:ci
15 changes: 12 additions & 3 deletions .github/workflows/test-wtih-vscode-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ on:
- master

jobs:
build:
build-with-vscode-build:
permissions:
contents: read

strategy:
matrix:
os: [macos-14]
Expand All @@ -19,14 +22,20 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
cache: 'npm'
node-version: ${{ matrix.node-version }}

- run: npm install && cd vscode-web && npm install
- run: cd vscode-web && npm run build
- name: Build VS Code web
working-directory: vscode-web
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build
- run: npm run link && npm run build
- uses: microsoft/playwright-github-action@v1
- run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} npm run test:ci
- run: npm run test:ci
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ lib
dist
out
node_modules
.worktrees/
3 changes: 0 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
29 changes: 28 additions & 1 deletion extensions/github1s/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@
"vscode": "^1.48.0"
},
"contributes": {
"resourceLabelFormatters": [
{
"scheme": "github1s",
"authority": "?*/**",
"formatting": {
"label": "${path} (${authoritySuffix})",
"separator": "/"
}
},
{
"scheme": "gitlab1s",
"authority": "?*/**",
"formatting": {
"label": "${path} (${authoritySuffix})",
"separator": "/"
}
},
{
"scheme": "bitbucket1s",
"authority": "?*/**",
"formatting": {
"label": "${path} (${authoritySuffix})",
"separator": "/"
}
}
],
"viewsContainers": {
"activitybar": [
{
Expand Down Expand Up @@ -596,7 +622,8 @@
"scripts": {
"clean": "rm -rf dist out",
"watch": "webpack --config webpack.config.js --watch",
"compile": "webpack --config webpack.config.js --mode production"
"compile": "webpack --config webpack.config.js --mode production",
"test": "node --experimental-strip-types --test test/*.test.ts"
},
"keywords": [],
"author": "",
Expand Down
11 changes: 8 additions & 3 deletions extensions/github1s/src/adapters/bitbucket1s/parse-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ const parseTreeOrBlobUrl = async (path: string): Promise<RouterState> => {
const repoFullName = `${owner}/${repo}`;
const dataSource = SourcegraphDataSource.getInstance('bitbucket');
const { ref, path: filePath } = await dataSource.extractRefPath(repoFullName, restParts.join('/'));
const fileType = await dataSource.detectPathFileType(repo, ref, filePath);
const fileType = await dataSource.detectPathFileType(repoFullName, ref, filePath);

return { pageType: fileType === FileType.Directory ? PageType.Tree : PageType.Blob, repo, ref, filePath };
return {
pageType: fileType === FileType.Directory ? PageType.Tree : PageType.Blob,
repo: repoFullName,
ref,
filePath,
};
};

const parseCommitsUrl = async (path: string): Promise<RouterState> => {
Expand Down Expand Up @@ -64,6 +69,6 @@ export const parseBitbucketPath = async (path: string): Promise<RouterState> =>
repo: 'atlassian/clover',
ref: 'HEAD',
pageType: PageType.Tree,
filePath: '',
filePath: '/',
};
};
4 changes: 2 additions & 2 deletions extensions/github1s/src/adapters/bitbucket1s/router-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ export class BitbucketRouterParser extends adapterTypes.RouterParser {
}

buildTreePath(repo: string, ref?: string, filePath?: string): string {
return ref ? (filePath ? `/${repo}/src/${ref}/${filePath}` : `/${repo}/src/${ref}`) : `/${repo}`;
return ref ? `/${repo}/src/${ref}${filePath && filePath !== '/' ? filePath : ''}` : `/${repo}`;
}

buildBlobPath(repo: string, ref: string, filePath: string, startLine?: number, endLine?: number): string {
const hash = startLine ? (endLine ? `#L${startLine}-L${endLine}` : `#L${startLine}`) : '';
return `/${repo}/src/${ref}/${filePath}${hash}`;
return `/${repo}/src/${ref}${filePath}${hash}`;
}

buildCommitListPath(repo: string): string {
Expand Down
34 changes: 18 additions & 16 deletions extensions/github1s/src/adapters/github1s/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { FILE_BLAME_QUERY } from './graphql';
import { GitHubFetcher } from './fetcher';
import { SourcegraphDataSource } from '../sourcegraph/data-source';
import { decorate, memorize } from '@/helpers/func';
import { normalizePath, trimStart, concatPath, isString } from '@/helpers/util';

const parseRepoFullName = (repoFullName: string) => {
const [owner, repo] = repoFullName.split('/');
Expand All @@ -41,7 +42,7 @@ const parseRepoFullName = (repoFullName: string) => {

const encodeFilePath = (filePath: string): string => {
const pathParts = filePath.split('/').filter(Boolean);
return pathParts.map((segment) => encodeURIComponent(segment)).join('/');
return `/${pathParts.map((segment) => encodeURIComponent(segment)).join('/')}`;
};

const FileTypeMap = {
Expand Down Expand Up @@ -104,13 +105,13 @@ export class GitHub1sDataSource extends DataSource {
@trySourcegraphApiFirst
async provideDirectory(repoFullName: string, ref: string, path: string, recursive = false): Promise<Directory> {
const fetcher = GitHubFetcher.getInstance();
const encodedPath = encodeFilePath(path);
const encodedPath = trimStart(encodeFilePath(path), '/');
// github api will return all files if `recursive` exists, even the value if false
const recursiveParams = recursive ? { recursive } : {};
const requestParams = { ref, path: encodedPath, ...parseRepoFullName(repoFullName), ...recursiveParams };
const { data } = await fetcher.request('GET /repos/{owner}/{repo}/git/trees/{ref}:{path}', requestParams);
const parseTreeItem = (treeItem): DirectoryEntry => ({
path: treeItem.path,
path: concatPath(path, treeItem.path),
type: FileTypeMap[treeItem.type] || FileType.File,
commitSha: FileTypeMap[treeItem.type] === FileType.Submodule ? treeItem.sha || 'HEAD' : undefined,
size: treeItem.size,
Expand All @@ -126,7 +127,7 @@ export class GitHub1sDataSource extends DataSource {
async provideFile(repoFullName: string, ref: string, path: string): Promise<File> {
const fetcher = GitHubFetcher.getInstance();
const { owner, repo } = parseRepoFullName(repoFullName);
const requestParams = { owner, repo, ref, path };
const requestParams = { owner, repo, ref, path: trimStart(path, '/') };
const { data } = await fetcher.request('GET /repos/{owner}/{repo}/contents/{path}', requestParams);
return { content: toUint8Array((data as any).content) };
}
Expand Down Expand Up @@ -156,16 +157,16 @@ export class GitHub1sDataSource extends DataSource {
const matchPathRef = (ref) => refAndPath.startsWith(`${ref}/`) || refAndPath === ref;
const matchedRef = this.matchedRefsMap.get(repoFullName)?.find(matchPathRef);
if (matchedRef) {
return { ref: matchedRef, path: refAndPath.slice(matchedRef.length + 1) };
return { ref: matchedRef, path: normalizePath(refAndPath.slice(matchedRef.length + 1)) };
}
const mapKey = `${repoFullName} ${refAndPath}`;
if (!this.refPathPromiseMap.has(mapKey)) {
const refPathPromise = new Promise<{ ref: string; path: string }>(async (resolve, reject) => {
if (!refAndPath) {
return resolve({ ref: await this.getDefaultBranch(repoFullName), path: '' });
return resolve({ ref: await this.getDefaultBranch(repoFullName), path: '/' });
}
if (refAndPath.match(/^HEAD(\/.*)?$/i)) {
return resolve({ ref: 'HEAD', path: refAndPath.slice(5) });
return resolve({ ref: 'HEAD', path: normalizePath(refAndPath.slice(5)) });
}

const fetcher = GitHubFetcher.getInstance();
Expand All @@ -174,7 +175,8 @@ export class GitHub1sDataSource extends DataSource {
const requestUrl = `GET /repos/{owner}/{repo}/git/extract-ref/{refAndPath}`;
const response = await fetcher.request(requestUrl, requestParams).catch(reject);
response?.data?.ref && this.matchedRefsMap.get(repoFullName)?.push(response.data.ref);
return resolve(response?.data || { ref: 'HEAD', path: '' });
const result = response?.data || { ref: 'HEAD', path: '/' };
return resolve({ ...result, path: normalizePath(result.path) });
});
this.refPathPromiseMap.set(mapKey, refPathPromise);
}
Expand Down Expand Up @@ -247,7 +249,7 @@ export class GitHub1sDataSource extends DataSource {
page: options?.page,
per_page: options?.pageSize,
sha: options?.from,
path: options?.path,
path: isString(options?.path) ? trimStart(options.path, '/') : undefined,
author: options?.author,
};
const requestParams = { owner, repo, ...queryParams };
Expand Down Expand Up @@ -279,8 +281,8 @@ export class GitHub1sDataSource extends DataSource {
createTime: data.commit.author?.date ? new Date(data.commit.author.date) : undefined,
parents: data.parents.map((parent) => parent.sha) || [],
files: data.files?.map((item) => ({
path: item.filename || item.previous_filename!,
previousPath: item.previous_filename,
path: normalizePath(item.filename || item.previous_filename!),
previousPath: item.previous_filename ? normalizePath(item.previous_filename) : undefined,
status: item.status as FileChangeStatus,
})),
avatarUrl: data.author?.avatar_url,
Expand All @@ -299,8 +301,8 @@ export class GitHub1sDataSource extends DataSource {
const { data } = await fetcher.request('GET /repos/{owner}/{repo}/commits/{ref}', requestParams);
return (
data.files?.map((item) => ({
path: item.filename || item.previous_filename!,
previousPath: item.previous_filename,
path: normalizePath(item.filename || item.previous_filename!),
previousPath: item.previous_filename ? normalizePath(item.previous_filename) : undefined,
status: item.status as FileChangeStatus,
})) || []
);
Expand Down Expand Up @@ -367,8 +369,8 @@ export class GitHub1sDataSource extends DataSource {
const { data } = await fetcher.request('GET /repos/{owner}/{repo}/pulls/{pull_number}/files', filesRequestParams);

return data.map((item) => ({
path: item.filename,
previousPath: item.previous_filename,
path: normalizePath(item.filename),
previousPath: item.previous_filename ? normalizePath(item.previous_filename) : undefined,
status: item.status as FileChangeStatus,
}));
}
Expand All @@ -377,7 +379,7 @@ export class GitHub1sDataSource extends DataSource {
async provideFileBlameRanges(repoFullName: string, ref: string, path: string): Promise<BlameRange[]> {
const fetcher = GitHubFetcher.getInstance();
const { owner, repo } = parseRepoFullName(repoFullName);
const requestParams = { owner, repo, ref, path };
const requestParams = { owner, repo, ref, path: trimStart(path, '/') };
const data = await fetcher.graphql(FILE_BLAME_QUERY, requestParams);
const blameRanges = (data as any)?.repository?.object?.blame?.ranges;

Expand Down
2 changes: 1 addition & 1 deletion extensions/github1s/src/adapters/github1s/parse-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,6 @@ export const parseGitHubPath = async (path: string): Promise<RouterState> => {
repo: DEFAULT_REPO,
ref: await getDefaultBranch(DEFAULT_REPO),
pageType: PageType.Tree,
filePath: '',
filePath: '/',
};
};
4 changes: 2 additions & 2 deletions extensions/github1s/src/adapters/github1s/router-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ export class GitHub1sRouterParser extends adapterTypes.RouterParser {
}

buildTreePath(repo: string, ref?: string, filePath?: string): string {
return ref ? (filePath ? `/${repo}/tree/${ref}/${filePath}` : `/${repo}/tree/${ref}`) : `/${repo}`;
return ref ? `/${repo}/tree/${ref}${filePath && filePath !== '/' ? filePath : ''}` : `/${repo}`;
}

buildBlobPath(repo: string, ref: string, filePath: string, startLine?: number, endLine?: number): string {
const hash = startLine ? (endLine ? `#L${startLine}-L${endLine}` : `#L${startLine}`) : '';
return `/${repo}/blob/${ref}/${filePath}${hash}`;
return `/${repo}/blob/${ref}${filePath}${hash}`;
}

buildCommitListPath(repo: string): string {
Expand Down
33 changes: 17 additions & 16 deletions extensions/github1s/src/adapters/gitlab1s/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { matchSorter } from 'match-sorter';
import { GitLabFetcher } from './fetcher';
import { SourcegraphDataSource } from '../sourcegraph/data-source';
import { decorate, memorize } from '@/helpers/func';
import { trimStart, normalizePath, isString } from '@/helpers/util';

const FileTypeMap = {
blob: FileType.File,
Expand Down Expand Up @@ -102,13 +103,13 @@ export class GitLab1sDataSource extends DataSource {
let page = 1;
let files = [];
const parseTreeItem = (treeItem): DirectoryEntry => ({
path: treeItem.path.slice(path.length),
path: normalizePath(treeItem.path),
type: FileTypeMap[treeItem.type] || FileType.File,
commitSha: FileTypeMap[treeItem.id] === FileType.Submodule ? treeItem.sha || 'HEAD' : undefined,
commitSha: FileTypeMap[treeItem.type] === FileType.Submodule ? treeItem.sha || 'HEAD' : undefined,
size: treeItem.size,
});
while (page > 0) {
const requestParams = { ref, page, path, repo, recursive };
const requestParams = { ref, page, path: trimStart(path, '/'), repo, recursive };
const { data, headers } = await fetcher.request(
'GET /projects/{repo}/repository/tree?recursive={recursive}&per_page=100&page={page}&ref={ref}&path={path}',
requestParams,
Expand All @@ -127,7 +128,7 @@ export class GitLab1sDataSource extends DataSource {
@trySourcegraphApiFirst
async provideFile(repo: string, ref: string, path: string): Promise<File> {
const fetcher = GitLabFetcher.getInstance();
const requestParams = { ref, path, repo };
const requestParams = { ref, path: trimStart(path, '/'), repo };
const { data } = await fetcher.request('GET /projects/{repo}/repository/files/{path}?ref={ref}', requestParams);
return { content: toUint8Array((data as any).content) };
}
Expand Down Expand Up @@ -164,24 +165,24 @@ export class GitLab1sDataSource extends DataSource {
@trySourcegraphApiFirst
async extractRefPath(repo: string, refAndPath: string): Promise<{ ref: string; path: string }> {
if (!refAndPath) {
return { ref: await this.getDefaultBranch(repo), path: '' };
return { ref: await this.getDefaultBranch(repo), path: '/' };
}
if (refAndPath.match(/^HEAD(\/.*)?$/i)) {
return { ref: 'HEAD', path: refAndPath.slice(5) };
return { ref: 'HEAD', path: normalizePath(refAndPath.slice(5)) };
}
if (!this.matchedRefsMap.has(repo)) {
this.matchedRefsMap.set(repo, []);
}
const matchPathRef = (ref) => refAndPath.startsWith(`${ref}/`) || refAndPath === ref;
const pathRef = this.matchedRefsMap.get(repo)?.find(matchPathRef);
if (pathRef) {
return { ref: pathRef, path: refAndPath.slice(pathRef.length + 1) };
return { ref: pathRef, path: normalizePath(refAndPath.slice(pathRef.length + 1)) };
}
const [branches, tags] = await this.prepareAllRefs(repo);
const exactRef = [...branches, ...tags].map((item) => item.name).find(matchPathRef);
const ref = exactRef || refAndPath.split('/')[0] || 'HEAD';
exactRef && this.matchedRefsMap.get(repo)?.push(ref);
return { ref, path: refAndPath.slice(ref.length + 1) };
return { ref, path: normalizePath(refAndPath.slice(ref.length + 1)) };
}

async prepareAllRefs(repo: string) {
Expand Down Expand Up @@ -250,7 +251,7 @@ export class GitLab1sDataSource extends DataSource {
page: options?.page,
per_page: options?.pageSize,
sha: options?.from,
path: options?.path,
path: isString(options?.path) ? trimStart(options.path, '/') : undefined,
author: options?.author,
};
const requestParams = { repo, ...queryParams };
Expand Down Expand Up @@ -286,8 +287,8 @@ export class GitLab1sDataSource extends DataSource {
createTime: data.created_at ? new Date(data.created_at) : undefined,
parents: data.parent_ids || [],
files: data.files?.map((item) => ({
path: item.filename || item.previous_filename!,
previousPath: item.previous_filename,
path: normalizePath(item.filename || item.previous_filename!),
previousPath: item.previous_filename ? normalizePath(item.previous_filename) : undefined,
status: item.status as FileChangeStatus,
})),
avatarUrl: data?.avatar_url,
Expand All @@ -301,8 +302,8 @@ export class GitLab1sDataSource extends DataSource {
const { data } = await fetcher.request('GET /projects/{repo}/repository/commits/{ref}/diff', requestParams);
return (
data?.map((item) => ({
path: item.new_path || item.old_path!,
previousPath: item.old_path,
path: normalizePath(item.new_path || item.old_path!),
previousPath: item.old_path ? normalizePath(item.old_path) : undefined,
status: item.new_file
? FileChangeStatus.Added
: item.deleted_file
Expand Down Expand Up @@ -373,8 +374,8 @@ export class GitLab1sDataSource extends DataSource {
);

return data.changes.map((item) => ({
path: item.new_path,
previousPath: item.old_path,
path: normalizePath(item.new_path),
previousPath: item.old_path ? normalizePath(item.old_path) : undefined,
status: item.new_file
? FileChangeStatus.Added
: item.deleted_file
Expand All @@ -388,7 +389,7 @@ export class GitLab1sDataSource extends DataSource {
@trySourcegraphApiFirst
async provideFileBlameRanges(repo: string, ref: string, path: string): Promise<BlameRange[]> {
const fetcher = GitLabFetcher.getInstance();
const requestParams = { repo, ref, path };
const requestParams = { repo, ref, path: trimStart(path, '/') };
const { data } = await fetcher.request(
'GET /projects/{repo}/repository/files/{path}/blame?ref={ref}',
requestParams,
Expand Down
Loading
Loading