From 5f31775664815213061106e255ea66d8d94821b2 Mon Sep 17 00:00:00 2001 From: Cno Date: Sun, 12 Nov 2023 00:57:49 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E6=B7=BB=E5=8A=A0=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/nep/definition/4-steps.mdx | 73 ++++++++++++++++++---------------- scripts/block.ts | 5 +++ scripts/step/index.ts | 17 ++++++++ scripts/step/markdown.ts | 16 +++++++- scripts/step/type.ts | 4 ++ scripts/type.ts | 1 + src/types/steps/execute.rs | 5 +-- src/types/steps/link.rs | 7 ++-- src/types/steps/log.rs | 3 +- 9 files changed, 88 insertions(+), 43 deletions(-) diff --git a/doc/nep/definition/4-steps.mdx b/doc/nep/definition/4-steps.mdx index ccaef1f4..c3f32c7c 100644 --- a/doc/nep/definition/4-steps.mdx +++ b/doc/nep/definition/4-steps.mdx @@ -10,7 +10,7 @@ import { Tag } from "../../components/tag.tsx" ### 字段 #### from 源路径,支持相对路径和绝对路径,支持使用通配符。 -* 类型:`String` +* 类型:`String` * 示例: ```toml # 相对路径写法 @@ -21,18 +21,18 @@ import { Tag } from "../../components/tag.tsx" ``` #### to 目标路径,支持相对路径和绝对路径。 -* 类型:`String` +* 类型:`String` * 示例:`to = "./config"` #### overwrite 可选 是否覆盖,缺省为 `false`。 -* 类型:`bool` +* 类型:`bool` * 示例:`overwrite = true` ## Delete 删除文件/文件夹。 ### 字段 #### at 删除目标路径,支持相对路径和绝对路径,支持使用通配符。 -* 类型:`String` +* 类型:`String` * 示例: ```toml # 相对路径写法 @@ -43,50 +43,51 @@ import { Tag } from "../../components/tag.tsx" ``` #### force 可选 是否强制删除,缺省为 `false`。 -* 类型:`bool` +* 类型:`bool` * 示例:`force = "true"` ## Execute 执行自定义命令 ### 字段 #### command 需要执行的命令,使用终端为 cmd。 -* 类型:`String` +* 类型:`String` * 示例:`command = "./installer.exe /S"` #### pwd 可选 执行目录,缺省为包安装目录。 -* 类型:`String` +* 类型:`String` * 示例:`pwd = "${AppData}/Microsoft"` #### call_installer 可选 当前命令的语义是否为正在调用安装器,缺省为 `false`;请务必正确指定此项,因为这会影响包权限、工作流静态检查等行为。 -* 类型:`bool` +* 类型:`bool` * 示例:`call_installer = true` #### wait -可选 枚举值:`Sync` `Delay` `Abandon`,缺省为 `Sync`。 +可选 命令等待策略。 -:::tip `Sync`:同步等待命令执行完成后该步骤才会结束; + `Delay`:异步执行命令并立即完成当前步骤;在当前工作流执行完成时等待该命令执行结束,然后才会结束工作流; + `Abandon`:异步执行命令并立即完成当前步骤;在当前工作流执行完成时若此命令还未结束则直接强行停止此命令。 -::: -* 类型:`String` +* 类型:`String 枚举` +* 有效值:`Sync` `Delay` `Abandon` ,缺省值:`Sync` * 示例:`wait = "Delay"` ## Kill 杀死某个进程。 ### 字段 #### target 进程名称,大小写敏感且必须以 `.exe` 结尾。 -* 类型:`String` +* 类型:`String` * 示例:`target = "code.exe"` ## Link 创建快捷方式。 ### 字段 #### source_file 源文件路径,支持相对路径和绝对路径。 -* 类型:`String` +* 类型:`String` * 示例:`source_file = "code.exe"` #### target_name 可选 快捷方式名称,支持使用 `FOLDER/NAME` 的模式表示在创建位置的文件夾中放置快捷方式。 -* 类型:`String` +* 类型:`String` * 示例: ```toml # 创建快捷方式 @@ -97,15 +98,16 @@ import { Tag } from "../../components/tag.tsx" ``` #### target_args 可选 快捷方式的启动参数。 -* 类型:`String` +* 类型:`String` * 示例:`target_args = "--debug"` #### target_icon 可选 快捷方式图标。 -* 类型:`String` +* 类型:`String` * 示例:`target_icon = "./icons/code.ico"` #### at -可选 创建位置,是一个枚举值数组,枚举值: `Desktop` `StartMenu`。 -* 类型:`Vec` +可选 创建位置。 +* 类型:`Vec` +* 元素有效值:`Desktop` `StartMenu` ,缺省值:`["Desktop"]` * 示例:`at = ["Desktop", "StartMenu"]` ### 反向步骤 删除生成的快捷方式。 @@ -114,18 +116,19 @@ import { Tag } from "../../components/tag.tsx" ### 字段 #### msg 日志内容。 -* 类型:`String` +* 类型:`String` * 示例:`msg = "VSCode installed successfully, workflow exit."` #### level -可选 日志级别,枚举值:`Debug` `Info` `Warning` `Error` `Success`,缺省为 `Info`。 -* 类型:`String` +可选 日志级别。 +* 类型:`String 枚举` +* 有效值:`Debug` `Info` `Warning` `Error` `Success` ,缺省值:`Info` * 示例:`level = "Success"` ## Move 移动文件/文件夹。 ### 字段 #### from 源路径,支持相对路径和绝对路径,支持使用通配符。 -* 类型:`String` +* 类型:`String` * 示例: ```toml # 相对路径写法 @@ -136,18 +139,18 @@ import { Tag } from "../../components/tag.tsx" ``` #### to 目标路径,支持相对路径和绝对路径。 -* 类型:`String` +* 类型:`String` * 示例:`to = "./bin"` #### overwrite 可选 是否覆盖,缺省为 `false`。 -* 类型:`bool` +* 类型:`bool` * 示例:`overwrite = "true"` ## New 新建文件/文件夹。 ### 字段 #### at 新建位置,以 `/` 结尾表示新建一个文件夹。 -* 类型:`String` +* 类型:`String` * 示例: ```toml # 创建空文件 @@ -158,7 +161,7 @@ import { Tag } from "../../components/tag.tsx" ``` #### overwrite 可选 是否覆盖,缺省为 false。 -* 类型:`bool` +* 类型:`bool` * 示例:`overwrite = "true"` ## Path 将可执行文件/文件夹暴露到 PATH 中: @@ -167,7 +170,7 @@ import { Tag } from "../../components/tag.tsx" ### 字段 #### record 记录值,支持可执行文件/文件夾,支持相对路径和绝对路径。 -* 类型:`String` +* 类型:`String` * 示例: ```toml # 创建可执行文件入口 @@ -178,7 +181,7 @@ import { Tag } from "../../components/tag.tsx" ``` #### alias 可选 别名,仅对可执行文件生效,缺省为原文件名。 -* 类型:`String` +* 类型:`String` * 示例:`alias = "code.exe"` ### 反向步骤 删除生成的可执行文件入口或从 PATH 变量中移除目录。 @@ -187,31 +190,31 @@ import { Tag } from "../../components/tag.tsx" ### 字段 #### from 目标路径,支持相对路径和绝对路径。 -* 类型:`String` +* 类型:`String` * 示例:`from = "./config.toml.example"` #### to 新的名称。 -* 类型:`String` +* 类型:`String` * 示例:`to = "config.toml"` ## Toast 弹出消息通知。 ### 字段 #### title 消息标题。 -* 类型:`String` +* 类型:`String` * 示例:`title = "你好 Nep"` #### content 消息内容。 -* 类型:`String` +* 类型:`String` * 示例:`content = "Hello Nep"` ## Wait 等待一个指定的时间。 ### 字段 #### timeout 等待的时长,单位为 ms。 -* 类型:`u64` +* 类型:`u64` * 示例:`timeout = "3000"` #### break_if 可选 若满足指定条件则提前结束等待,该条件会在等待过程中每 500ms 检查一次。 -* 类型:`String` +* 类型:`String` * 示例:`break_if = 'Exist("${Desktop}/Visual Studio Code.lnk")'` \ No newline at end of file diff --git a/scripts/block.ts b/scripts/block.ts index 806a828e..adaf31ec 100644 --- a/scripts/block.ts +++ b/scripts/block.ts @@ -86,6 +86,11 @@ const COMMENTS_DEFINITION: Array<{ startsWith: ["//@ "], renderer: (stack) => (stack.length > 0 ? stack.join("\n") : undefined), }, + { + key: "enums", + startsWith: ["//* "], + renderer: (stack) => (stack.length > 0 ? stack.join(" ") : undefined), + }, ]; // 匹配代码块并解析注释 diff --git a/scripts/step/index.ts b/scripts/step/index.ts index 630ead5d..bd1d5edd 100644 --- a/scripts/step/index.ts +++ b/scripts/step/index.ts @@ -19,7 +19,23 @@ function formatField({ wiki, demo, extra, + enums, }: CommonFieldInfo): StepInfo["fields"][number] { + const getEnums = ( + line: string | undefined, + ): StepInfo["fields"][number]["type"]["enums"] => { + if (!line) { + return undefined; + } + const [a, defaultValue] = line.split("|"); + return { + values: a + .split(" ") + .filter((v) => !!v) + .map((val) => val.trim()), + default: defaultValue.trim(), + }; + }; const m = declaration.match(/(\w+):\s?([\w<>()]+)/); if (m) { const [, name, rawType] = m; @@ -29,6 +45,7 @@ function formatField({ type: { optional, identifier: optional ? rawType.slice(7, -1) : rawType, + enums: getEnums(enums), }, wiki, demo, diff --git a/scripts/step/markdown.ts b/scripts/step/markdown.ts index d32856c1..d6869fae 100644 --- a/scripts/step/markdown.ts +++ b/scripts/step/markdown.ts @@ -4,13 +4,27 @@ function fieldRenderer( field: StepInfo["fields"][number], titleLevel: number, ): string { + const identifier = field.type.enums + ? field.type.identifier.replace("String", "String 枚举") + : field.type.identifier; + const typeText = `* 类型:\`${identifier}\``; + const enumText = field.type.enums + ? ` +* ${identifier.includes("Vec") ? "元素" : ""}有效值:${field.type.enums.values + .map((v) => `\`${v}\``) + .join(" ")} ${ + field.type.enums.default + ? `,缺省值:\`${field.type.enums.default}\`` + : "" + }` + : ""; const demoText = field.demo ? `\n* 示例:${field.demo}` : ""; const rulesText = field.rules?.length ? "\n" + field.rules.map((rule) => `* ${rule}`).join("\n") : ""; return `${"#".repeat(titleLevel)} ${field.name} ${field.type.optional ? "可选 " : ""}${field.wiki ?? ""} -* 类型:\`${field.type.identifier}\` ${demoText} ${rulesText}`; +${typeText} ${enumText} ${demoText} ${rulesText}`; } function stepRenderer( diff --git a/scripts/step/type.ts b/scripts/step/type.ts index a81a8e2f..3c402f7e 100644 --- a/scripts/step/type.ts +++ b/scripts/step/type.ts @@ -7,6 +7,10 @@ export interface StepInfo { type: { identifier: string; optional: boolean; + enums?: { + values: string[]; + default?: string; + }; }; wiki?: string; demo?: string; diff --git a/scripts/type.ts b/scripts/type.ts index 8a58c03e..43e13a0e 100644 --- a/scripts/type.ts +++ b/scripts/type.ts @@ -7,5 +7,6 @@ export interface CommonFieldInfo { wiki?: string; demo?: string; extra?: string; + enums?: string; declaration: string; } diff --git a/src/types/steps/execute.rs b/src/types/steps/execute.rs index bb91003b..25109514 100644 --- a/src/types/steps/execute.rs +++ b/src/types/steps/execute.rs @@ -26,13 +26,12 @@ pub struct StepExecute { /// 当前命令的语义是否为正在调用安装器,缺省为 `false`;请务必正确指定此项,因为这会影响包权限、工作流静态检查等行为。 //# `call_installer = true` pub call_installer: Option, - /// 枚举值:`Sync` `Delay` `Abandon`,缺省为 `Sync`。 - /// :::tip + /// 命令等待策略。 /// `Sync`:同步等待命令执行完成后该步骤才会结束; /// `Delay`:异步执行命令并立即完成当前步骤;在当前工作流执行完成时等待该命令执行结束,然后才会结束工作流; /// `Abandon`:异步执行命令并立即完成当前步骤;在当前工作流执行完成时若此命令还未结束则直接强行停止此命令。 - /// ::: //# `wait = "Delay"` + //* Sync Delay Abandon | Sync pub wait: Option, } diff --git a/src/types/steps/link.rs b/src/types/steps/link.rs index c8b9201d..766536d9 100644 --- a/src/types/steps/link.rs +++ b/src/types/steps/link.rs @@ -121,14 +121,15 @@ pub struct StepLink { //# target_name = "Microsoft/Visual Studio Code" //# ``` pub target_name: Option, - //# `target_args = "--debug"` /// 快捷方式的启动参数。 + //# `target_args = "--debug"` pub target_args: Option, - //# `target_icon = "./icons/code.ico"` /// 快捷方式图标。 + //# `target_icon = "./icons/code.ico"` pub target_icon: Option, + /// 创建位置。 + //* Desktop StartMenu | ["Desktop"] //# `at = ["Desktop", "StartMenu"]` - /// 创建位置,是一个枚举值数组,枚举值: `Desktop` `StartMenu`。 pub at: Option>, } diff --git a/src/types/steps/log.rs b/src/types/steps/log.rs index 8cc00a02..b06f2f1e 100644 --- a/src/types/steps/log.rs +++ b/src/types/steps/log.rs @@ -14,7 +14,8 @@ pub struct StepLog { /// 日志内容。 //# `msg = "VSCode installed successfully, workflow exit."` pub msg: String, - /// 日志级别,枚举值:`Debug` `Info` `Warning` `Error` `Success`,缺省为 `Info`。 + /// 日志级别。 + //* Debug Info Warning Error Success | Info //# `level = "Success"` pub level: Option, }