Skip to content

Commit 50d6e08

Browse files
author
guqiankun.gqk
committed
feat: 增加blame插件
1 parent acd641d commit 50d6e08

6 files changed

Lines changed: 224 additions & 3 deletions

File tree

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@
153153
"publisher": "cloud-ide-ext",
154154
"name": "antcode-scaning",
155155
"version": "0.0.8"
156+
},
157+
{
158+
"publisher": "cloud-ide-ext",
159+
"name": "acr-editor-blame",
160+
"version": "0.0.1"
156161
}
157162
]
158163
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { apiService } from './api.service';
2+
import { FileWithCommit, TreeEntry } from './types/file';
3+
import { Blame } from './types/commit';
4+
5+
export const repoService = {
6+
async getFileList(projectId: number, refName: string, path: string, withCommit?: boolean) {
7+
return (await apiService.get(`/webapi/projects/${projectId}/repository/tree`, {
8+
refName,
9+
path,
10+
withCommit,
11+
})) as FileWithCommit[];
12+
},
13+
14+
async getTreeEntry(projectId: number, refName: string, path: string) {
15+
return (await apiService.get(`/api/v3/projects/${projectId}/repository/tree_entry`, {
16+
refName,
17+
path,
18+
})) as TreeEntry;
19+
},
20+
21+
async getFileDetail(projectId: number, ref: string, filepath: string, charsetName?: string) {
22+
return await apiService.get(
23+
`/api/v3/projects/${projectId}/repository/blobs/${encodeURIComponent(ref)}`,
24+
{
25+
filepath,
26+
charsetName,
27+
},
28+
{
29+
disableResponseConvert: true,
30+
getOriginalResponse: true,
31+
}
32+
);
33+
},
34+
35+
async getCodeSymbols(projectId: number, ref: string, filepath: string) {
36+
return await apiService.get(
37+
`/api/v3/projects/${projectId}/repository/file_symbols/${encodeURIComponent(ref)}/`,
38+
{
39+
filepath,
40+
}
41+
);
42+
},
43+
44+
async getCodeBlame(projectId: number, sha: string, filePath: string) {
45+
return (await apiService.get(`/api/v3/projects/${projectId}/repository/blame`, {
46+
sha,
47+
filePath,
48+
})) as Blame[];
49+
},
50+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Commit } from './commit';
2+
3+
export enum FileListType {
4+
tree = 'tree',
5+
blob = 'blob',
6+
commit = 'commit',
7+
}
8+
9+
export interface File {
10+
id: string;
11+
mode: string;
12+
name: string;
13+
path: string;
14+
type: FileListType;
15+
url?: string;
16+
}
17+
18+
export interface FileWithCommit extends File {
19+
commit?: Commit;
20+
}
21+
22+
export interface FileDetail {
23+
charsetName: string;
24+
content: string;
25+
fileName: string;
26+
filePath: string;
27+
highlightedContent: string;
28+
ref: string;
29+
size: number;
30+
}
31+
32+
export interface TreeEntry extends File {
33+
size: number;
34+
render: string;
35+
}
36+
37+
export enum FileShowType {
38+
text = 'text',
39+
image = 'image',
40+
download = 'download',
41+
}

packages/integrations/src/antcode-cr/index.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import React from 'react';
2-
import { useEffect, useRef } from 'react';
2+
import { useEffect, useRef, useState } from 'react';
33
import ReactDOM from 'react-dom';
44
import { Button, Switch } from 'antd';
55
import 'antd/dist/antd.css';
6+
import type { CheckboxChangeEvent } from 'antd/lib/checkbox';
67

78
import AntcodeCR from '@alipay/alex-acr';
89
import { IAntcodeCRProps } from '@alipay/alex-acr/lib/modules/antcode-service/base';
@@ -20,12 +21,15 @@ import {
2021
} from './antcode/components';
2122
import { projectService } from './antcode/project.service';
2223
import { lsifService } from './antcode/lsif.service';
24+
import { repoService } from './antcode/repo.service';
2325
import { FileActionHeader, FileAction } from './antcode/types/file-action';
2426
import { useFileReadMarkChange$ } from './hooks';
2527
import { useLoadLocalExtensionMetadata } from '../common/local-extension.module';
2628
import acrPlugin from '../common/plugin';
29+
import CodeBlamePlugin, { ExtensionCommand } from '../common/code-blame.plugin';
2730
import CodeScaningPlugin from '../common/code-scaning.plugin';
2831
import CodeScaning from '@alipay/alex/extensions/cloud-ide-ext.antcode-scaning';
32+
import CodeBlame from '@alipay/alex/extensions/cloud-ide-ext.acr-editor-blame';
2933
import { mockService } from './antcode/mock.service';
3034
import './style.less';
3135

@@ -78,6 +82,29 @@ const App = () => {
7882
CodeScaningPlugin.commands?.executeCommand('antcode-cr.update', 'annotations', annotationPacks);
7983
}, [annotationPacks]);
8084

85+
// 插件
86+
const [pluginActivated, setPluginActivated] = useState(false);
87+
const blamePlugin = useRef(
88+
new CodeBlamePlugin(
89+
() => setPluginActivated(true),
90+
(commitId: string) =>
91+
window.open(`/${project.namespace.path}/${project.path}/commit/${commitId}`),
92+
(projectId, commitId, path) => repoService.getCodeBlame(projectId, commitId, path)
93+
)
94+
);
95+
96+
useEffect(() => {
97+
if (!pluginActivated) {
98+
return;
99+
}
100+
const projectData = {
101+
projectId: project.id,
102+
prevSha: diffsPack.fromVersion?.headCommitSha ?? diffsPack.toVersion.baseCommitSha,
103+
nextSha: diffsPack.toVersion.headCommitSha,
104+
};
105+
blamePlugin.current.commands?.executeCommand(ExtensionCommand.setProjectData, projectData);
106+
}, [pluginActivated, diffsPack]);
107+
81108
// const extensionMetadata = useLoadLocalExtensionMetadata();
82109
// if (!extensionMetadata) return null;
83110
if (!diffsPack) return null;
@@ -156,8 +183,8 @@ const App = () => {
156183
staticServicePath: Uri.parse(window.location.href)
157184
.with({ path: path.join('/antcode', project.pathWithNamespace, 'raw') })
158185
.toString(),
159-
plugins: [acrPlugin, CodeScaningPlugin],
160-
extensionMetadata: [CodeScaning],
186+
plugins: [acrPlugin, CodeScaningPlugin, blamePlugin.current],
187+
extensionMetadata: [CodeScaning, CodeBlame],
161188
// extensionMetadata,
162189
},
163190
} as IAntcodeCRProps;

packages/integrations/src/antcode-cr/style.less

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@c45: rgba(0, 0, 0, 0.45);
2+
@c85: rgba(0, 0, 0, 0.85);
13
html, body, #main {
24
overflow: visible;
35
}
@@ -21,3 +23,26 @@ html, body, #main {
2123
margin-right: 8px;
2224
}
2325
}
26+
27+
.monaco-editor-hover {
28+
border: none !important;
29+
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
30+
0 9px 28px 8px rgba(0, 0, 0, 0.05);
31+
transform: translate(-20px, 0px);
32+
}
33+
34+
.monaco-editor-hover-content .markdown-hover .hover-contents {
35+
padding: 16px;
36+
background: #fff;
37+
38+
h1 {
39+
color: @c85;
40+
font-size: 14px;
41+
line-height: 22px;
42+
}
43+
44+
p {
45+
color: @c45;
46+
}
47+
}
48+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { IPluginModule, IPluginAPI } from '@alipay/alex/lib/editor';
2+
3+
export enum ExtensionCommand {
4+
toggleBlame = 'code.blame.toggleBlame',
5+
linkToCommit = 'code.blame.linktocommit',
6+
onActive = 'code.blame.extension.active',
7+
setPerference = 'code.blame.setPerference',
8+
setProjectData = 'code.blame.setProjectData',
9+
getBlameData = 'code.blame.getBlameData',
10+
}
11+
12+
export default class IDEPlugin implements IPluginModule {
13+
commands: IPluginAPI['commands'];
14+
onActivate: () => void;
15+
linkToCommit: (commitId: string) => void;
16+
getBlame: (projectId: number, commitId: string, path: string) => Promise<any>;
17+
18+
/**
19+
* 插件 ID,用于唯一标识插件
20+
*/
21+
PLUGIN_ID = 'ACR_BLAME';
22+
23+
constructor(
24+
onActive: () => void,
25+
linkToCommit: (commitId: string) => void,
26+
getBlame: (projectId: number, commitId: string, path: string) => Promise<any>
27+
) {
28+
this.onActivate = onActive;
29+
this.linkToCommit = linkToCommit;
30+
this.getBlame = getBlame;
31+
}
32+
33+
/**
34+
* 激活插件
35+
*/
36+
activate = (ctx: IPluginAPI) => {
37+
const { commands, context } = ctx;
38+
this.commands = commands;
39+
context.subscriptions.push(
40+
commands.registerCommand(ExtensionCommand.onActive, () => {
41+
this.onActivate();
42+
}),
43+
commands.registerCommand(ExtensionCommand.linkToCommit, (params) => {
44+
const { commitId } = params;
45+
this.linkToCommit(commitId);
46+
}),
47+
commands.registerCommand(ExtensionCommand.getBlameData, async (sendData) => {
48+
const { projectId, prevSha, nextSha, filePath } = sendData;
49+
// kaitian内uri 和 antcode内不同 多了一个 /
50+
const path = filePath.startsWith('/') ? filePath.slice(1) : filePath;
51+
const response = await this.getBlame(projectId, nextSha, path).then((res) => {
52+
return res;
53+
});
54+
return response;
55+
})
56+
);
57+
};
58+
59+
/**
60+
* 注销插件,可在此时机清理副作用
61+
*/
62+
deactivate() {}
63+
64+
/**
65+
* 修改配置项
66+
* @param name 配置项名称
67+
* @param value 值
68+
* @param global 是否全局生效
69+
*/
70+
setPerference(name: string, value: string, global?: boolean) {
71+
this.commands.executeCommand(ExtensionCommand.setPerference, name, value, !!global);
72+
}
73+
}

0 commit comments

Comments
 (0)