✨ feat(vscode): 新增 GitHub provider,凭据借 gh 登录,删工单走 GraphQL、依赖按内部 id 换算
This commit is contained in:
1 parent
451bc91a6b
commit
7351b6247f
12 files changed
+1010
-47
No files matched your search
+18
-21
@@ -11,6 +11,9 @@ import { workspace } from 'vscode'
|
||||
import { getToken } from '../auth/secrets'
|
||||
import { detectRepo } from '../git/remote'
|
||||
import { GiteaProvider } from './gitea/provider'
|
||||
import { GH_LOGIN_HINT, readGhToken } from './github/ghAuth'
|
||||
import { GitHubProvider } from './github/provider'
|
||||
import { forgeKindForHost } from './types'
|
||||
|
||||
/** 一个工作区对应的代码托管仓库,和访问它用的 [ForgeProvider]。 */
|
||||
export interface ForgeContext {
|
||||
@@ -24,37 +27,31 @@ export interface ForgeContext {
|
||||
|
||||
/**
|
||||
* 解析结果;失败时 `message` 是可以直接给人看的原因,`reason` 给需要分情况处理的调用方:
|
||||
* `no-workspace` 没打开工作区,`no-remote` 没有能认出的 origin,`no-credentials` 没有凭据,`unsupported` 这一家还不支持。
|
||||
* `no-workspace` 没打开工作区,`no-remote` 没有能认出的 origin,`no-credentials` 没有凭据。
|
||||
*/
|
||||
export type ForgeResolution
|
||||
= | { ok: true, forge: ForgeContext }
|
||||
| { ok: false, reason: 'no-workspace' | 'no-remote', message: string }
|
||||
| { ok: false, reason: 'no-credentials' | 'unsupported', message: string, kind: ForgeKind, host: string }
|
||||
| { ok: false, reason: 'no-credentials', message: string, kind: ForgeKind, host: string }
|
||||
|
||||
/** host 小写后是 `github.com` 的是 GitHub,其余都当 Gitea;不认 GitHub Enterprise。 */
|
||||
export function forgeKindForHost(host: string): ForgeKind {
|
||||
return host.toLowerCase() === 'github.com' ? 'github' : 'gitea'
|
||||
}
|
||||
|
||||
/** 给指定的仓库造 [ForgeContext];webhook 记下的仓库不一定是当前工作区的 origin,所以单独开放。 */
|
||||
/**
|
||||
* 给指定的仓库造 [ForgeContext];webhook 记下的仓库不一定是当前工作区的 origin,所以单独开放。
|
||||
*
|
||||
* GitHub 的凭据现取 gh 的登录,Gitea 的凭据是用户在设置里填、存在 SecretStorage 里的 token。
|
||||
*/
|
||||
export async function openForge(ctx: ExtensionContext, workspaceRoot: string, remote: Remote): Promise<ForgeResolution> {
|
||||
const kind = forgeKindForHost(remote.host)
|
||||
if (kind === 'github')
|
||||
return { ok: false, reason: 'unsupported', kind, host: remote.host, message: '暂未支持 GitHub 仓库' }
|
||||
const repo = { workspaceRoot, kind, host: remote.host, owner: remote.owner, repo: remote.repo }
|
||||
if (kind === 'github') {
|
||||
const token = await readGhToken()
|
||||
if (!token)
|
||||
return { ok: false, reason: 'no-credentials', kind, host: remote.host, message: GH_LOGIN_HINT }
|
||||
return { ok: true, forge: { ...repo, provider: new GitHubProvider({ owner: remote.owner, repo: remote.repo, token }) } }
|
||||
}
|
||||
const token = await getToken(ctx, remote.host)
|
||||
if (!token)
|
||||
return { ok: false, reason: 'no-credentials', kind, host: remote.host, message: `请先配置 ${remote.host} 的访问令牌` }
|
||||
return {
|
||||
ok: true,
|
||||
forge: {
|
||||
workspaceRoot,
|
||||
kind,
|
||||
host: remote.host,
|
||||
owner: remote.owner,
|
||||
repo: remote.repo,
|
||||
provider: new GiteaProvider({ ...remote, token }),
|
||||
},
|
||||
}
|
||||
return { ok: true, forge: { ...repo, provider: new GiteaProvider({ ...remote, token }) } }
|
||||
}
|
||||
|
||||
/** 解析当前工作区(第一个工作区文件夹)的代码托管仓库。 */
|
||||
|
||||
Reference in new issue
Block a user