From 9b813e2d538de3562f3c2d0fd39eb31a9df84667 Mon Sep 17 00:00:00 2001 From: netcon Date: Sat, 24 Feb 2024 04:57:04 +0800 Subject: [PATCH] fix: gitlab private repo auth --- extensions/github1s/package.json | 8 ++-- .../src/adapters/github1s/authentication.ts | 2 +- .../src/adapters/github1s/data-source.ts | 16 ++++--- .../github1s/src/adapters/github1s/fetcher.ts | 7 ++-- .../src/adapters/github1s/parse-path.ts | 2 +- .../src/adapters/github1s/router-parser.ts | 3 +- .../src/adapters/github1s/settings.ts | 2 +- .../github1s/src/adapters/github1s/token.ts | 2 +- .../src/adapters/gitlab1s/authentication.ts | 2 +- .../src/adapters/gitlab1s/data-source.ts | 42 +++++++++---------- .../github1s/src/adapters/gitlab1s/fetcher.ts | 2 +- .../src/adapters/gitlab1s/parse-path.ts | 2 +- .../src/adapters/gitlab1s/router-parser.ts | 3 +- .../src/adapters/gitlab1s/settings.ts | 2 +- .../github1s/src/adapters/gitlab1s/token.ts | 2 +- .../src/adapters/sourcegraph/data-source.ts | 3 +- extensions/github1s/src/adapters/types.ts | 22 ++++------ extensions/github1s/src/changes/files.ts | 15 +++---- extensions/github1s/src/changes/quick-diff.ts | 4 +- extensions/github1s/src/commands/global.ts | 11 ----- extensions/github1s/src/global.d.ts | 13 ++---- extensions/github1s/src/helpers/async.ts | 2 +- extensions/github1s/src/helpers/date.ts | 2 + .../src/repository/code-review-manager.ts | 32 +++++++++----- extensions/github1s/src/statusbar/gitpod.ts | 32 -------------- extensions/github1s/src/statusbar/index.ts | 3 +- .../github1s/src/views/code-review-list.ts | 23 +++++++--- extensions/github1s/src/views/commit-list.ts | 11 ++++- extensions/github1s/webpack.config.js | 8 ++-- src/config.ts | 4 +- src/global.d.ts | 2 + webpack.config.js | 2 + 32 files changed, 136 insertions(+), 150 deletions(-) delete mode 100644 extensions/github1s/src/statusbar/gitpod.ts diff --git a/extensions/github1s/package.json b/extensions/github1s/package.json index e232fb253..ddc8c25b3 100644 --- a/extensions/github1s/package.json +++ b/extensions/github1s/package.json @@ -562,22 +562,22 @@ { "command": "github1s.commands.openFilePreviousRevision", "when": "resourceScheme =~ /^(github1s|gitlab1s|bitbucket1s)/", - "group": "navigation@98" + "group": "navigation@4" }, { "command": "github1s.commands.openFileNextRevision", "when": "resourceScheme =~ /^(github1s|gitlab1s|bitbucket1s)/", - "group": "navigation@99" + "group": "navigation@5" }, { "command": "github1s.commands.openEditorGutterBlame", "when": "!isInDiffEditor && github1s:features:gutterBlame:enabled && !github1s:features:gutterBlame:open", - "group": "navigation@4" + "group": "navigation@6" }, { "command": "github1s.commands.closeEditorGutterBlame", "when": "!isInDiffEditor && github1s:features:gutterBlame:enabled && github1s:features:gutterBlame:open", - "group": "navigation@4" + "group": "navigation@6" } ] } diff --git a/extensions/github1s/src/adapters/github1s/authentication.ts b/extensions/github1s/src/adapters/github1s/authentication.ts index e13fb9407..41a914e2b 100644 --- a/extensions/github1s/src/adapters/github1s/authentication.ts +++ b/extensions/github1s/src/adapters/github1s/authentication.ts @@ -26,7 +26,7 @@ export class GitHub1sAuthenticationView { authenticationFormTitle: 'Authenticating to GitHub', OAuthButtonText: 'Connect to GitHub', OAuthButtonLogo: 'assets/pages/assets/github.svg', - createTokenLink: 'https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s', + createTokenLink: `${GITHUB_ORIGIN}/settings/tokens/new?scopes=repo&description=GitHub1s`, rateLimitDocLink: 'https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting', rateLimitDocLinkText: 'GitHub Rate limiting Documentation', authenticationFeatures: [ diff --git a/extensions/github1s/src/adapters/github1s/data-source.ts b/extensions/github1s/src/adapters/github1s/data-source.ts index 786b88c43..098fda975 100644 --- a/extensions/github1s/src/adapters/github1s/data-source.ts +++ b/extensions/github1s/src/adapters/github1s/data-source.ts @@ -325,13 +325,15 @@ export class GitHub1sDataSource extends DataSource { createTime: new Date(item.created_at), mergeTime: item.merged_at ? new Date(item.merged_at) : null, closeTime: item.closed_at ? new Date(item.closed_at) : null, - head: { label: item.head.label, commitSha: item.head.sha }, - base: { label: item.base.label, commitSha: item.base.sha }, + source: item.base.label, + target: item.head.label, + sourceSha: item.base.sha, + targetSha: item.head.sha, avatarUrl: item.user?.avatar_url, })); } - async provideCodeReview(repoFullName: string, id: string): Promise { + async provideCodeReview(repoFullName: string, id: string) { const fetcher = GitHubFetcher.getInstance(); const { owner, repo } = parseRepoFullName(repoFullName); const pullRequestParams = { owner, repo, pull_number: Number(id) }; @@ -345,8 +347,10 @@ export class GitHub1sDataSource extends DataSource { createTime: new Date(data.created_at), mergeTime: data.merged_at ? new Date(data.merged_at) : null, closeTime: data.closed_at ? new Date(data.closed_at) : null, - head: { label: data.head.label, commitSha: data.head.sha }, - base: { label: data.base.label, commitSha: data.base.sha }, + source: data.base.label, + target: data.head.label, + sourceSha: data.base.sha, + targetSha: data.head.sha, avatarUrl: data.user?.avatar_url, }; } @@ -426,6 +430,6 @@ export class GitHub1sDataSource extends DataSource { } provideUserAvatarLink(user: string): string { - return `https://github.com/${user}.png`; + return `${GITHUB_ORIGIN}/${user}.png`; } } diff --git a/extensions/github1s/src/adapters/github1s/fetcher.ts b/extensions/github1s/src/adapters/github1s/fetcher.ts index ab7f1189a..dff718f70 100644 --- a/extensions/github1s/src/adapters/github1s/fetcher.ts +++ b/extensions/github1s/src/adapters/github1s/fetcher.ts @@ -76,7 +76,7 @@ export class GitHubFetcher { // initial fetcher methods in this way for correct `request/graphql` type inference initFetcherMethods() { const accessToken = GitHubTokenManager.getInstance().getToken(); - const octokit = new Octokit({ auth: accessToken, request: { fetch } }); + const octokit = new Octokit({ auth: accessToken, request: { fetch }, baseUrl: GITHUB_API_PREFIX }); this._originalRequest = octokit.request; this.request = Object.assign((...args: Parameters) => { @@ -93,9 +93,8 @@ export class GitHubFetcher { }, this._originalRequest); this.graphql = Object.assign(async (...args: Parameters) => { - // graphql API only worked for authenticated users if (!GitHubTokenManager.getInstance().getToken()) { - const message = 'GraphQL API only worked for authenticated users'; + const message = 'GraphQL API only works for authenticated users'; await GitHub1sAuthenticationView.getInstance().open(message, true); } return octokit.graphql(...args); @@ -119,7 +118,7 @@ export class GitHubFetcher { const response = await this._originalRequest?.('GET /repos/{owner}/{repo}', { owner, repo }); response?.data?.private && (await this.setUseSourcegraphApiFirst(false)); return response?.data || null; - })).then(() => null); + })).catch(() => null); } public async useSourcegraphApiFirst(repo?: string): Promise { diff --git a/extensions/github1s/src/adapters/github1s/parse-path.ts b/extensions/github1s/src/adapters/github1s/parse-path.ts index 185d4c0f4..b4e6e5916 100644 --- a/extensions/github1s/src/adapters/github1s/parse-path.ts +++ b/extensions/github1s/src/adapters/github1s/parse-path.ts @@ -84,7 +84,7 @@ const parsePullUrl = async (path: string): Promise => { return { repo: `${owner}/${repo}`, pageType: PageType.CodeReview, - ref: codeReview.head.commitSha, + ref: codeReview.targetSha, codeReviewId, }; }; diff --git a/extensions/github1s/src/adapters/github1s/router-parser.ts b/extensions/github1s/src/adapters/github1s/router-parser.ts index 15d911e81..99345bb33 100644 --- a/extensions/github1s/src/adapters/github1s/router-parser.ts +++ b/extensions/github1s/src/adapters/github1s/router-parser.ts @@ -3,6 +3,7 @@ * @author netcon */ +import { joinPath } from '@/helpers/util'; import * as adapterTypes from '../types'; import { parseGitHubPath } from './parse-path'; @@ -46,6 +47,6 @@ export class GitHub1sRouterParser extends adapterTypes.RouterParser { } buildExternalLink(path: string): string { - return 'https://github.com' + (path.startsWith('/') ? path : `/${path}`); + return joinPath(GITHUB_ORIGIN, path); } } diff --git a/extensions/github1s/src/adapters/github1s/settings.ts b/extensions/github1s/src/adapters/github1s/settings.ts index 09e50bbd5..1cd063293 100644 --- a/extensions/github1s/src/adapters/github1s/settings.ts +++ b/extensions/github1s/src/adapters/github1s/settings.ts @@ -33,7 +33,7 @@ export class GitHub1sSettingsViewProvider implements vscode.WebviewViewProvider 'For API requests using Authentication, you can make up to 5,000 requests per hour.', ], OAuthButtonText: 'Connect to GitHub', - createTokenLink: 'https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s', + createTokenLink: `${GITHUB_ORIGIN}/settings/tokens/new?scopes=repo&description=GitHub1s`, }; public registerListeners(webviewView: vscode.WebviewView) { diff --git a/extensions/github1s/src/adapters/github1s/token.ts b/extensions/github1s/src/adapters/github1s/token.ts index 259171450..69e4e8f4e 100644 --- a/extensions/github1s/src/adapters/github1s/token.ts +++ b/extensions/github1s/src/adapters/github1s/token.ts @@ -49,7 +49,7 @@ export class GitHubTokenManager { return Promise.resolve(null); } const fetchOptions = accessToken ? { headers: { Authorization: `token ${accessToken}` } } : {}; - return fetch('https://api.github.com/user', fetchOptions) + return fetch(`${GITHUB_API_PREFIX}/user`, fetchOptions) .then((response) => { if (response.status === 401) { return null; diff --git a/extensions/github1s/src/adapters/gitlab1s/authentication.ts b/extensions/github1s/src/adapters/gitlab1s/authentication.ts index c5bc5a640..920ec6b63 100644 --- a/extensions/github1s/src/adapters/gitlab1s/authentication.ts +++ b/extensions/github1s/src/adapters/gitlab1s/authentication.ts @@ -14,7 +14,7 @@ export class GitLab1sAuthenticationView extends GitHub1sAuthenticationView { authenticationFormTitle: 'Authenticating to GitLab', OAuthButtonText: 'Connect to GitLab', OAuthButtonLogo: 'assets/pages/assets/gitlab.svg', - createTokenLink: 'https://gitlab.com/-/profile/personal_access_tokens?scopes=read_api&name=GitLab1s', + createTokenLink: `${GITLAB_ORIGIN}/-/profile/personal_access_tokens?scopes=read_api&name=GitLab1s`, authenticationFeatures: [ { text: 'Access GitLab personal repository', diff --git a/extensions/github1s/src/adapters/gitlab1s/data-source.ts b/extensions/github1s/src/adapters/gitlab1s/data-source.ts index 914643b7c..23d1a49c5 100644 --- a/extensions/github1s/src/adapters/gitlab1s/data-source.ts +++ b/extensions/github1s/src/adapters/gitlab1s/data-source.ts @@ -39,16 +39,16 @@ const FileTypeMap = { commit: FileType.Submodule, }; -const getPullState = (pull: { state: string; merged_at: string | null }): CodeReviewState => { - // current pull request is open - if (pull.state === 'opened') { +const getMergeRequestState = (mergeRequest: { state: string; merged_at: string | null }): CodeReviewState => { + // current merge request is open + if (mergeRequest.state === 'opened') { return CodeReviewState.Open; } - // current pull request is merged - if (pull.state === 'closed' && pull.merged_at) { + // current merge request is merged + if (mergeRequest.state === 'closed' && mergeRequest.merged_at) { return CodeReviewState.Merged; } - // current pull is closed + // current merge is closed return CodeReviewState.Merged; }; @@ -141,7 +141,6 @@ export class GitLab1sDataSource extends DataSource { name: item.name, commitSha: item.commit.id, description: `${ref === 'heads' ? 'Branch' : 'Tag'} at ${item.commit.short_id}`, - isDefault: item.default, })); } @@ -332,33 +331,34 @@ export class GitLab1sDataSource extends DataSource { return data.map((item) => ({ id: `${item.iid}`, title: item.title, - state: getPullState(item), + state: getMergeRequestState(item), creator: item.author?.name || item.author?.username, createTime: new Date(item.created_at), - // Some versions do not have a merged_at field - mergeTime: item.merged_at ? new Date(item.merged_at) : item.updated_at ? new Date(item.updated_at) : null, + mergeTime: item.merged_at ? new Date(item.merged_at) : null, closeTime: item.closed_at ? new Date(item.closed_at) : null, - head: { label: item.labels[0], commitSha: item.sha }, - base: { label: item.labels[1], commitSha: '' }, // Populated when getting changes + source: item.source_branch, + target: item.target_branch, avatarUrl: item.author?.avatar_url, })); } - async provideCodeReview(repo: string, id: string): Promise { + async provideCodeReview(repo: string, id: string) { const fetcher = GitLabFetcher.getInstance(); - const pullRequestParams = { repo, pull_number: Number(id) }; - const { data } = await fetcher.request('GET /projects/{repo}/merge_requests/{pull_number}', pullRequestParams); + const requestParams = { repo, id }; + const { data } = await fetcher.request('GET /projects/{repo}/merge_requests/{id}', requestParams); return { id: `${data.iid}`, title: data.title, - state: getPullState(data), + state: getMergeRequestState(data), creator: data.author?.name || data.author?.username, createTime: new Date(data.created_at), mergeTime: data.merged_at ? new Date(data.merged_at) : null, closeTime: data.closed_at ? new Date(data.closed_at) : null, - head: { label: data.labels[0], commitSha: data.diff_refs.head_sha }, - base: { label: data.labels[1], commitSha: data.diff_refs.base_sha }, + source: data.source_branch, + target: data.target_branch, + sourceSha: data.diff_refs.base_sha, + targetSha: data.diff_refs.head_sha, avatarUrl: data.author?.avatar_url, }; } @@ -367,9 +367,9 @@ export class GitLab1sDataSource extends DataSource { async provideCodeReviewChangedFiles(repo: string, id: string, options?: CommonQueryOptions): Promise { const fetcher = GitLabFetcher.getInstance(); const pageParams = { per_page: options?.pageSize, page: options?.page }; - const filesRequestParams = { repo, pull_number: Number(id), ...pageParams }; + const filesRequestParams = { repo, id, ...pageParams }; const { data } = await fetcher.request( - 'GET /projects/{repo}/merge_requests/{pull_number}/changes?per_page={per_page}&page={page}', + 'GET /projects/{repo}/merge_requests/{id}/changes?per_page={per_page}&page={page}', filesRequestParams ); @@ -383,8 +383,6 @@ export class GitLab1sDataSource extends DataSource { : item.renamed_file ? FileChangeStatus.Renamed : FileChangeStatus.Modified, - head: data.diff_refs.head_sha, - base: data.diff_refs.base_sha, })); } diff --git a/extensions/github1s/src/adapters/gitlab1s/fetcher.ts b/extensions/github1s/src/adapters/gitlab1s/fetcher.ts index 95487d462..b7523a42e 100644 --- a/extensions/github1s/src/adapters/gitlab1s/fetcher.ts +++ b/extensions/github1s/src/adapters/gitlab1s/fetcher.ts @@ -72,7 +72,7 @@ export class GitLabFetcher { accessToken?.length < 60 ? { headers: { 'PRIVATE-TOKEN': `${accessToken}` } } : { headers: { Authorization: `Bearer ${accessToken}` } }; - return fetch(`${GITLAB_DOMAIN}/api/v4` + path, { + return fetch(GITLAB_API_PREFIX + path, { ...fetchOptions, method, }).then(async (response: Response & { data: any }) => { diff --git a/extensions/github1s/src/adapters/gitlab1s/parse-path.ts b/extensions/github1s/src/adapters/gitlab1s/parse-path.ts index e30616a5f..6b56dabe1 100644 --- a/extensions/github1s/src/adapters/gitlab1s/parse-path.ts +++ b/extensions/github1s/src/adapters/gitlab1s/parse-path.ts @@ -83,7 +83,7 @@ const parseMergeRequestUrl = async (path: string): Promise => { return { repo: `${owner}/${repo}`, pageType: PageType.CodeReview, - ref: codeReview.base.commitSha, + ref: codeReview.targetSha, codeReviewId, }; }; diff --git a/extensions/github1s/src/adapters/gitlab1s/router-parser.ts b/extensions/github1s/src/adapters/gitlab1s/router-parser.ts index fb61711d1..2e1809fbd 100644 --- a/extensions/github1s/src/adapters/gitlab1s/router-parser.ts +++ b/extensions/github1s/src/adapters/gitlab1s/router-parser.ts @@ -3,6 +3,7 @@ * @author netcon */ +import { joinPath } from '@/helpers/util'; import * as adapterTypes from '../types'; import { parseGitLabPath } from './parse-path'; @@ -46,6 +47,6 @@ export class GitLab1sRouterParser extends adapterTypes.RouterParser { } buildExternalLink(path: string): string { - return GITLAB_DOMAIN + (path.startsWith('/') ? path : `/${path}`); + return joinPath(GITLAB_ORIGIN, path); } } diff --git a/extensions/github1s/src/adapters/gitlab1s/settings.ts b/extensions/github1s/src/adapters/gitlab1s/settings.ts index a5c968498..c77ea3e23 100644 --- a/extensions/github1s/src/adapters/gitlab1s/settings.ts +++ b/extensions/github1s/src/adapters/gitlab1s/settings.ts @@ -19,6 +19,6 @@ export class GitLab1sSettingsViewProvider extends GitHub1sSettingsViewProvider { "Your token will only be stored locally in your browser. Don't forget to clean it while you are using a public device.", ], OAuthButtonText: 'Connect to GitLab', - createTokenLink: 'https://gitlab.com/-/profile/personal_access_tokens?scopes=read_api&name=GitLab1s', + createTokenLink: `${GITLAB_ORIGIN}/-/profile/personal_access_tokens?scopes=read_api&name=GitLab1s`, }; } diff --git a/extensions/github1s/src/adapters/gitlab1s/token.ts b/extensions/github1s/src/adapters/gitlab1s/token.ts index 869ac3af5..19a9ea1e0 100644 --- a/extensions/github1s/src/adapters/gitlab1s/token.ts +++ b/extensions/github1s/src/adapters/gitlab1s/token.ts @@ -24,7 +24,7 @@ export class GitLabTokenManager extends GitHubTokenManager { accessToken?.length < 60 ? { headers: { 'PRIVATE-TOKEN': `${accessToken}` } } : { headers: { Authorization: `Bearer ${accessToken}` } }; - return fetch(`${GITLAB_DOMAIN}/api/v4/user`, fetchOptions) + return fetch(`${GITLAB_API_PREFIX}/user`, fetchOptions) .then((response) => { if (response.status === 401) { return null; diff --git a/extensions/github1s/src/adapters/sourcegraph/data-source.ts b/extensions/github1s/src/adapters/sourcegraph/data-source.ts index 215f4eb50..20eba8f4a 100644 --- a/extensions/github1s/src/adapters/sourcegraph/data-source.ts +++ b/extensions/github1s/src/adapters/sourcegraph/data-source.ts @@ -62,8 +62,7 @@ export class SourcegraphDataSource extends DataSource { return `github.com/${repo}`; } if (this.platform === 'gitlab') { - // return `gitlab.com/${repo}`; - return `${GITLAB_DOMAIN.replace('https://', '')}/${repo}`; + return `gitlab.com/${repo}`; } if (this.platform === 'bitbucket') { return `bitbucket.org/${repo}`; diff --git a/extensions/github1s/src/adapters/types.ts b/extensions/github1s/src/adapters/types.ts index 949fcc381..bdef13c89 100644 --- a/extensions/github1s/src/adapters/types.ts +++ b/extensions/github1s/src/adapters/types.ts @@ -44,7 +44,6 @@ export interface Branch { name: string; commitSha?: string; description?: string; - isDefault?: boolean; } export interface Tag { @@ -127,14 +126,10 @@ export interface CodeReview { createTime: Date; mergeTime: Date | null; closeTime: Date | null; - head: { - label: string; - commitSha: string; - }; - base: { - label: string; - commitSha: string; - }; + source: string; + target: string; + sourceSha?: string; + targetSha?: string; avatarUrl?: string; } @@ -151,8 +146,6 @@ export interface ChangedFile { path: string; // only exists for renamed file previousPath?: string; - head?: string; - base?: string; } export interface BlameRange { @@ -241,7 +234,10 @@ export class DataSource { } // optionally return changed files (if `files` exists can reduce api calls) - provideCodeReview(repo: string, id: string): Promisable<(CodeReview & { files?: ChangedFile[] }) | null> { + provideCodeReview( + repo: string, + id: string + ): Promisable<(CodeReview & { sourceSha: string; targetSha: string; files?: ChangedFile[] }) | null> { return null; } @@ -384,7 +380,7 @@ export class RouterParser { // convert giving path to the external link (using for jumping back to origin platform) buildExternalLink(path: string): Promisable { - return 'https://github.com' + path; + return path; } } diff --git a/extensions/github1s/src/changes/files.ts b/extensions/github1s/src/changes/files.ts index 5aec79ae0..62d19665b 100644 --- a/extensions/github1s/src/changes/files.ts +++ b/extensions/github1s/src/changes/files.ts @@ -19,22 +19,23 @@ interface VSCodeChangedFile { } // get the change files of a codeReview -export const getCodeReviewChangedFiles = async (codeReview: adapterTypes.CodeReview) => { +export const getCodeReviewChangedFiles = async ( + codeReview: adapterTypes.CodeReview & { sourceSha: string; targetSha: string } +) => { const scheme = adapterManager.getCurrentScheme(); const { repo } = await router.getState(); - const repository = Repository.getInstance(scheme, repo); - const changedFiles = await repository.getCodeReviewChangedFiles(codeReview.id); - // cann't get base sha from mergeList - const [{ base: baseSha = '' } = {}] = changedFiles; const baseRootUri = vscode.Uri.parse('').with({ scheme: scheme, - authority: `${repo}+${codeReview.base.commitSha || baseSha}`, + authority: `${repo}+${codeReview.targetSha}`, path: '/', }); const headRootUri = baseRootUri.with({ - authority: `${repo}+${codeReview.head.commitSha}`, + authority: `${repo}+${codeReview.sourceSha}`, }); + const repository = Repository.getInstance(scheme, repo); + const changedFiles = await repository.getCodeReviewChangedFiles(codeReview.id); + return changedFiles.map((changedFile) => { // the `previous_filename` field only exists in `RENAMED` file, // fallback to `filename` otherwise diff --git a/extensions/github1s/src/changes/quick-diff.ts b/extensions/github1s/src/changes/quick-diff.ts index 654f57755..507b89b38 100644 --- a/extensions/github1s/src/changes/quick-diff.ts +++ b/extensions/github1s/src/changes/quick-diff.ts @@ -27,11 +27,11 @@ const getOriginalResourceForPull = async (uri: vscode.Uri, codeReviewId: string) } const codeReview = await repository.getCodeReviewItem(codeReviewId); - if (!codeReview?.base?.commitSha) { + if (!codeReview?.targetSha) { return null; } - const originalAuthority = `${routeState.repo}+${codeReview!.base.commitSha}`; + const originalAuthority = `${routeState.repo}+${codeReview!.targetSha}`; const originalPath = changedFile.previousPath ? `/${changedFile.previousPath}` : uri.path; return uri.with({ authority: originalAuthority, path: originalPath }); diff --git a/extensions/github1s/src/commands/global.ts b/extensions/github1s/src/commands/global.ts index 6d370b0f3..9f152f947 100644 --- a/extensions/github1s/src/commands/global.ts +++ b/extensions/github1s/src/commands/global.ts @@ -18,16 +18,6 @@ export const commandOpenOnOfficialPage = async () => { return vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(externalLink)); }; -export const commandOpenGitpod = () => { - return router.getAuthority().then((currentAuthority) => { - const [currentRepo] = currentAuthority.split('+'); - vscode.commands.executeCommand( - 'vscode.open', - vscode.Uri.parse(`https://gitpod.io/#https://github.com/${currentRepo}`) - ); - }); -}; - const repoPickItemButtons = [{ iconPath: new vscode.ThemeIcon('close') }]; const getRecentRepoPickItems = () => @@ -91,7 +81,6 @@ export const registerGlobalCommands = (context: vscode.ExtensionContext) => { vscode.commands.registerCommand('github1s.commands.openOnBitbucket', commandOpenOnOfficialPage), vscode.commands.registerCommand('github1s.commands.openOnNpm', commandOpenOnOfficialPage), vscode.commands.registerCommand('github1s.commands.openOnOfficialPage', commandOpenOnOfficialPage), - vscode.commands.registerCommand('github1s.commands.openOnGitPod', commandOpenGitpod), vscode.commands.registerCommand('github1s.commands.openRepository', commandOpenRepository), vscode.commands.registerCommand('github1s.commands.openOnlineEditor', commandOpenOnlineEditor), vscode.commands.registerCommand('remoteHub.openRepository', commandOpenRepository) diff --git a/extensions/github1s/src/global.d.ts b/extensions/github1s/src/global.d.ts index 70830df1b..819440645 100644 --- a/extensions/github1s/src/global.d.ts +++ b/extensions/github1s/src/global.d.ts @@ -1,9 +1,4 @@ -/** - * gitlab domain - */ -declare const GITLAB_DOMAIN: string; - -/** - * gitlab create token url - */ -declare const GITLAB_CREATE_TOKEN_URL: string; +declare const GITHUB_ORIGIN: string; +declare const GITHUB_API_PREFIX: string; +declare const GITLAB_ORIGIN: string; +declare const GITLAB_API_PREFIX: string; diff --git a/extensions/github1s/src/helpers/async.ts b/extensions/github1s/src/helpers/async.ts index 93fa2cc15..6d37f3d72 100644 --- a/extensions/github1s/src/helpers/async.ts +++ b/extensions/github1s/src/helpers/async.ts @@ -3,7 +3,7 @@ */ // below code is comes from: -//https://github.com/microsoft/vscode/blob/a3415e669a8f3879c290af5616a8ed45dd0534af/src/vs/base/common/async.ts#L344 +// https://github.com/microsoft/vscode/blob/a3415e669a8f3879c290af5616a8ed45dd0534af/src/vs/base/common/async.ts#L344 export class Barrier { private _isOpen: boolean; private _promise: Promise; diff --git a/extensions/github1s/src/helpers/date.ts b/extensions/github1s/src/helpers/date.ts index 0af117de9..0e36b4bff 100644 --- a/extensions/github1s/src/helpers/date.ts +++ b/extensions/github1s/src/helpers/date.ts @@ -9,3 +9,5 @@ import * as relativeTimePlugin from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTimePlugin); export const relativeTimeTo = (date: dayjs.ConfigType) => dayjs().to(dayjs(date)); + +export const toISOString = (date: dayjs.ConfigType) => dayjs(date).toISOString(); diff --git a/extensions/github1s/src/repository/code-review-manager.ts b/extensions/github1s/src/repository/code-review-manager.ts index df497725b..4fefe8b65 100644 --- a/extensions/github1s/src/repository/code-review-manager.ts +++ b/extensions/github1s/src/repository/code-review-manager.ts @@ -88,18 +88,30 @@ export class CodeReviewManager { return this._codeReviewList; }); - getItem = reuseable(async (codeReviewId: string, forceUpdate = false): Promise => { - if (forceUpdate || !this._codeReviewMap.has(codeReviewId)) { - const dataSource = await adapterManager.getAdapter(this._scheme).resolveDataSource(); - const codeReview = await dataSource.provideCodeReview(this._repo, codeReviewId); - codeReview && this._codeReviewMap.set(codeReviewId, codeReview); - if (codeReview?.files) { - const manager = CodeReviewChangedFilesManager.getInstance(this._scheme, this._repo, codeReviewId); - manager.setChangedFiles(codeReview.files); + getItem = reuseable( + async ( + codeReviewId: string, + forceUpdate = false + ): Promise<(CodeReview & { sourceSha: string; targetSha: string }) | null> => { + const isShaExists = (codeReview: CodeReview) => codeReview.sourceSha && codeReview.targetSha; + if ( + forceUpdate || + !this._codeReviewMap.has(codeReviewId) || + !isShaExists(this._codeReviewMap.get(codeReviewId)!) + ) { + const dataSource = await adapterManager.getAdapter(this._scheme).resolveDataSource(); + const codeReview = await dataSource.provideCodeReview(this._repo, codeReviewId); + codeReview && this._codeReviewMap.set(codeReviewId, codeReview); + if (codeReview?.files) { + const manager = CodeReviewChangedFilesManager.getInstance(this._scheme, this._repo, codeReviewId); + manager.setChangedFiles(codeReview.files); + } } + return (this._codeReviewMap.get(codeReviewId) || null) as + | (CodeReview & { sourceSha: string; targetSha: string }) + | null; } - return this._codeReviewMap.get(codeReviewId) || null; - }); + ); loadMore = reuseable(async (): Promise => { const dataSource = await adapterManager.getAdapter(this._scheme).resolveDataSource(); diff --git a/extensions/github1s/src/statusbar/gitpod.ts b/extensions/github1s/src/statusbar/gitpod.ts deleted file mode 100644 index 122d61566..000000000 --- a/extensions/github1s/src/statusbar/gitpod.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file Show Gitpod In Status Bar - * @author mikenikles - */ - -import * as vscode from 'vscode'; -import router from '@/router'; -import { PlatformName } from '../adapters/types'; -import { adapterManager } from '../adapters'; - -const getGitpodRepoUri = async () => { - const { repo } = await router.getState(); - return vscode.Uri.parse(`https://gitpod.io/#https://github.com/${repo}`); -}; - -export const showGitpod = async () => { - if (adapterManager.getCurrentAdapter().platformName !== PlatformName.GitHub) { - return; - } - - const gitpodRepoUri = await getGitpodRepoUri(); - const item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 0); - - item.text = ' $(pencil) Develop your project on Gitpod'; - item.tooltip = 'Edit files, open/review PRs, use Docker - all online.'; - item.command = { - title: `Open Gitpod`, - command: 'vscode.open', - arguments: [gitpodRepoUri], - }; - item.show(); -}; diff --git a/extensions/github1s/src/statusbar/index.ts b/extensions/github1s/src/statusbar/index.ts index d43cb68a7..aafd4f3a5 100644 --- a/extensions/github1s/src/statusbar/index.ts +++ b/extensions/github1s/src/statusbar/index.ts @@ -4,10 +4,9 @@ */ import { updateCheckoutTo } from './checkout'; -import { showGitpod } from './gitpod'; import { showSponsors } from './sponsors'; export const decorateStatusBar = () => { - showSponsors().then(() => showGitpod()); + showSponsors(); updateCheckoutTo(); }; diff --git a/extensions/github1s/src/views/code-review-list.ts b/extensions/github1s/src/views/code-review-list.ts index 945a105e6..40d79aea6 100644 --- a/extensions/github1s/src/views/code-review-list.ts +++ b/extensions/github1s/src/views/code-review-list.ts @@ -8,7 +8,7 @@ import * as queryString from 'query-string'; import router from '@/router'; import { Barrier } from '@/helpers/async'; import { Repository } from '@/repository'; -import { relativeTimeTo } from '@/helpers/date'; +import { relativeTimeTo, toISOString } from '@/helpers/date'; import adapterManager from '@/adapters/manager'; import * as adapterTypes from '@/adapters/types'; import { getChangedFileDiffCommand, getCodeReviewChangedFiles } from '@/changes/files'; @@ -63,6 +63,15 @@ export const getCodeReviewTreeItemDescription = (codeReview: adapterTypes.CodeRe return `by ${codeReview.creator} was closed ${relativeTimeTo(codeReview.closeTime!)}`; }; +export const getCodeReviewTreeItemTooltip = (codeReview: adapterTypes.CodeReview): string => { + const titleText = `#${codeReview.id} ${codeReview.title.split(/[\r\n]/)[0]}`; + const ISOTimeStr = codeReview.createTime ? toISOString(codeReview.createTime) : null; + const directionText = `${codeReview.target} ← ${codeReview.source}`; + const infoText = [codeReview.state, directionText].filter(Boolean).join(', '); + const detailText = [codeReview.creator, ISOTimeStr].filter(Boolean).join(', '); + return `${titleText}\n(${infoText})\n(${detailText})`; +}; + export interface CodeReviewTreeItem extends vscode.TreeItem { codeReview: adapterTypes.CodeReview; } @@ -132,7 +141,7 @@ export class CodeReviewTreeDataProvider implements vscode.TreeDataProvider { const label = getCodeReviewTreeItemLabel(codeReview); const description = getCodeReviewTreeItemDescription(codeReview); - const tooltip = `${label} (${description})`; + const tooltip = getCodeReviewTreeItemTooltip(codeReview); const iconPath = vscode.Uri.parse(codeReview?.avatarUrl || ''); const contextValue = 'github1s:viewItems:codeReviewListItem'; @@ -157,7 +166,11 @@ export class CodeReviewTreeDataProvider implements vscode.TreeDataProvider { this._loadingBarrier && (await this._loadingBarrier.wait()); - const changedFiles = await getCodeReviewChangedFiles(codeReview); + const scheme = adapterManager.getCurrentScheme(); + const { repo } = await router.getState(); + const repository = Repository.getInstance(scheme, repo); + const _codeReview = await repository.getCodeReviewItem(codeReview.id); + const changedFiles = _codeReview ? await getCodeReviewChangedFiles(_codeReview) : []; const changedFileItems = changedFiles.map((changedFile) => { const filePath = changedFile.headFileUri.path; const id = `${codeReview.id} ${filePath}`; @@ -173,9 +186,7 @@ export class CodeReviewTreeDataProvider implements vscode.TreeDataProvider { + const shortCommitSha = commit.sha.slice(0, 7); + const ISOTimeStr = commit.createTime ? toISOString(commit.createTime) : null; + const detailText = [shortCommitSha, commit.author, ISOTimeStr].filter(Boolean).join(', '); + return `${commit.message}\n(${detailText})`; +}; + export interface CommitTreeItem extends vscode.TreeItem { commit: adapterTypes.Commit; } @@ -95,7 +102,7 @@ export class CommitTreeDataProvider implements vscode.TreeDataProvider { const label = commit.message.split(/[\r\n]/)[0]; const description = getCommitTreeItemDescription(commit); - const tooltip = `${commit.message}\n(${description})`; + const tooltip = getCommitTreeItemTooltip(commit); const iconPath = vscode.Uri.parse(commit.avatarUrl || ''); const contextValue = 'github1s:viewItems:commitListItem'; diff --git a/extensions/github1s/webpack.config.js b/extensions/github1s/webpack.config.js index 3044047f8..70dfcee6c 100644 --- a/extensions/github1s/webpack.config.js +++ b/extensions/github1s/webpack.config.js @@ -62,10 +62,10 @@ module.exports = /** @type WebpackConfig */ { devtool: 'source-map', plugins: [ new webpack.DefinePlugin({ - GITLAB_DOMAIN: JSON.stringify(process.env.GITLAB_DOMAIN || 'https://gitlab.com'), - GITLAB_CREATE_TOKEN_URL: JSON.stringify( - process.env.GITLAB_CREATE_TOKEN_URL || '/-/profile/personal_access_tokens' - ), + GITHUB_ORIGIN: JSON.stringify(process.env.GITHUB_DOMAIN || 'https://github.com'), + GITHUB_API_PREFIX: JSON.stringify(process.env.GITHUB_API_PREFIX || 'https://api.github.com'), + GITLAB_ORIGIN: JSON.stringify(process.env.GITLAB_DOMAIN || 'https://gitlab.com'), + GITLAB_API_PREFIX: JSON.stringify(process.env.GITLAB_API_PREFIX || 'https://gitlab.com/api/v4'), }), new webpack.ProvidePlugin({ process: 'process/browser.js', diff --git a/src/config.ts b/src/config.ts index 5ea1325f1..cf45b86ca 100644 --- a/src/config.ts +++ b/src/config.ts @@ -71,7 +71,7 @@ export const createVSCodeWebConfig = (platform: Platform, repository: string): a logo: { title: 'Open on GitLab', icon: gitlabLogoUrl, - onClick: () => (repository ? openOfficialPage('https://gitlab.com') : openGitHub1sPage()), + onClick: () => (repository ? openOfficialPage(GITLAB_ORIGIN) : openGitHub1sPage()), }, }; } @@ -120,7 +120,7 @@ export const createVSCodeWebConfig = (platform: Platform, repository: string): a logo: { title: 'Open on GitHub', icon: githubLogoUrl, - onClick: () => (repository ? openOfficialPage('https://github.com') : openGitHub1sPage()), + onClick: () => (repository ? openOfficialPage(GITHUB_ORIGIN) : openGitHub1sPage()), }, }; }; diff --git a/src/global.d.ts b/src/global.d.ts index b4e7d7a85..44f885da9 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -4,3 +4,5 @@ declare module '*.svg' { } declare const STATIC_HASH: string; +declare const GITHUB_ORIGIN: string; +declare const GITLAB_ORIGIN: string; diff --git a/webpack.config.js b/webpack.config.js index e585845f0..be29df858 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -93,6 +93,8 @@ module.exports = (env, argv) => { }), new webpack.DefinePlugin({ STATIC_HASH: JSON.stringify(STATIC_HASH), + GITHUB_ORIGIN: JSON.stringify(process.env.GITHUB_DOMAIN || 'https://github.com'), + GITLAB_ORIGIN: JSON.stringify(process.env.GITLAB_DOMAIN || 'https://gitlab.com'), }), generate({ file: `static-${STATIC_HASH}/config/extensions.js`,