-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add checkVSCodePlugins webtools #7
base: master
Are you sure you want to change the base?
Changes from all commits
15f0a3e
c8eb7fe
2db618a
b68bb03
ed7a97c
13a5204
4b80e33
6ca0ecc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import { DoctorLevel } from "@doctors/core"; | ||
import { IApi } from "../type"; | ||
import { exec } from "child_process"; | ||
import { chalkByDoctorLevel } from "@doctors/utils"; | ||
|
||
/* VSCode plugins type */ | ||
export type VSCodePluginsConfig = ( | ||
| string | ||
| { name: string; desc: string; version?: string } | ||
)[]; | ||
|
||
/* Constants */ | ||
const FEATURE_NAME = "VSCode Plugins"; | ||
const BASIC_VSCODE_PLUGINS: VSCodePluginsConfig = []; | ||
const OUTPUT_DEMARCATORS = "\n\t- "; | ||
|
||
/** | ||
* Execute command | ||
*/ | ||
function execCommand(command: string): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
const child = exec(command, (error, stdout, stderr) => { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
resolve(stdout.trim()); | ||
} | ||
}); | ||
|
||
child.on("close", () => { | ||
child.kill(); | ||
}); | ||
}); | ||
} | ||
|
||
async function filterPluginsConfig( | ||
plugins: VSCodePluginsConfig | ||
): Promise<[string[], string[]]> { | ||
const failedRecords: string[] = []; | ||
const successRecords: string[] = []; | ||
|
||
try { | ||
const localPluginsMap = await getLocalPlugins(); | ||
plugins.forEach((item) => { | ||
if (typeof item === "string" && !localPluginsMap.has(item)) { | ||
const name = item; | ||
failedRecords.push(`${name} plugin: You should install ${name} plugin`); | ||
} else if (typeof item === "object" && item !== null) { | ||
const { name, desc, version: targetVersion } = item; | ||
if (!localPluginsMap.has(name)) { | ||
failedRecords.push( | ||
`${name} plugin: You should install ${name}@${targetVersion} plugin` | ||
); | ||
} else { | ||
// check version | ||
if (targetVersion != null) { | ||
const localVersion = localPluginsMap.get(name) as string; | ||
if (compareVersion(localVersion, targetVersion) < 0) { | ||
failedRecords.push( | ||
`${name} plugin: You should update the ${name} plugin to version v${targetVersion} and above ${chalkByDoctorLevel( | ||
DoctorLevel.ERROR, | ||
"Now: v" + localVersion | ||
)}` | ||
); | ||
} | ||
} | ||
successRecords.push(`Installed ${name} plugin: ${desc}`); | ||
} | ||
} | ||
}); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
|
||
return [failedRecords, successRecords]; | ||
} | ||
|
||
/** | ||
* Get local VSCode plugins | ||
*/ | ||
async function getLocalPlugins() { | ||
const stdout = | ||
(await execCommand("code --list-extensions --show-versions")) || ""; | ||
const pluginMap = stdout.split("\n").reduce((map, item) => { | ||
const [name, version] = item.split("@"); | ||
map.set(name, version); | ||
return map; | ||
}, new Map<string, string>()); | ||
return pluginMap; | ||
} | ||
|
||
/** | ||
* Compare version numbers | ||
*/ | ||
function compareVersion(a: string, b: string) { | ||
const versionReg = /^\d+?(\.\d+){0,2}$/; | ||
if (!versionReg.test(a) || !versionReg.test(b)) { | ||
throw TypeError( | ||
`There is an error in the version resolution of the VSCode plugin ${ | ||
versionReg.test(a) ? b : a | ||
}, please make sure you have configured the version number in the correct format` | ||
); | ||
} | ||
let aV = a.split(".").map(Number), | ||
bV = b.split(".").map(Number); | ||
|
||
for (let i = 0; i < 3; i++) { | ||
if (aV[i] == null || bV[i] == null) { | ||
if (aV[i] == null) return -1; | ||
else return 1; | ||
} | ||
if (aV[i] > bV[i]) { | ||
return 1; | ||
} else if (aV[i] < bV[i]) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
export default (api: IApi) => { | ||
api.addDoctorWebToolsCheck(async () => { | ||
const vscodePlugins: VSCodePluginsConfig = [ | ||
...BASIC_VSCODE_PLUGINS, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以写几个最通用的先 |
||
...(api.userConfig.webTools?.vscode?.morePlugins || []), | ||
]; | ||
|
||
const [failedRecords, successRecords] = await filterPluginsConfig( | ||
vscodePlugins | ||
); | ||
|
||
if (failedRecords.length === 0) { | ||
let description = | ||
successRecords.length === 0 | ||
? "You have installed all the required VSCode plugins" | ||
: `${OUTPUT_DEMARCATORS}${successRecords.join(OUTPUT_DEMARCATORS)}\n`; | ||
return { | ||
label: FEATURE_NAME, | ||
description, | ||
doctorLevel: DoctorLevel.SUCCESS, | ||
}; | ||
} else { | ||
return { | ||
label: FEATURE_NAME, | ||
description: `${OUTPUT_DEMARCATORS}${failedRecords.join( | ||
OUTPUT_DEMARCATORS | ||
)}\n`, | ||
doctorLevel: DoctorLevel.ERROR, | ||
}; | ||
} | ||
}); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export default [ | ||
require.resolve("./checkNode"), | ||
require.resolve("./checkChrome"), | ||
require.resolve("./checkVSCodePlugins"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 按照到类型放在一起比较合适一点 api.addDoctorWebToolsCheckBefore(()=>{
console.log('以下是对常用 VsCodePlugin 进行检测') // 当然 ui 可以随意diy
}) |
||
require.resolve("./checkDefaultBrowser"), | ||
]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,12 @@ import type { Awaitable } from "@doctors/utils"; | |
export interface ConfigSchema { | ||
webTools: { | ||
nodeVersion: DoctorLevel; | ||
vscode: { | ||
morePlugins: ( | ||
| string | ||
| { name: string; desc: string; version?: string } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里可以抽出来一个 type ExtraPlugin = |
||
)[]; | ||
}; | ||
}; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
提取 通用 utils 到 @dodctors/utils 这个包