@chengzhao-dev/dsh-cpp-workflow 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +5 -3
- package/README.md +5 -3
- package/package.json +3 -1
- package/skills/developing-cpp/examples/comments-declaration.md +8 -10
- package/skills/developing-cpp/references/comments.md +12 -13
- package/skills/developing-cpp/references/file-template.md +6 -8
- package/skills/developing-cpp/scripts/checking-comments.mjs +25 -6
package/README.en.md
CHANGED
|
@@ -19,13 +19,13 @@ The exception material follows the C++ Core Guidelines' Error handling section a
|
|
|
19
19
|
Pinned npm install:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.5.
|
|
22
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.5.5
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The matching Git tag:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.5.
|
|
28
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.5.5
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The desktop app owns the `desktop` profile. If the command-line `add` is rejected, add the plugin in the app settings and use the same pinned npm version. A Git tag install uses the prebuilt `lib/` committed in the repository and runs no build on the target machine; the package has no install script that needs approval.
|
|
@@ -103,9 +103,11 @@ npm ci
|
|
|
103
103
|
npm test # build, three-skill structural check, gate/environment/schema/comment tests
|
|
104
104
|
npm run test:matrix # real build matrix: 4 templates x 5 standards
|
|
105
105
|
npm run pack:check # inspect the npm package contents
|
|
106
|
+
npm run ci # replay the Ubuntu CI job: install, test, package check
|
|
107
|
+
npm run ci:full # ci plus the standard matrix; needs a POSIX host
|
|
106
108
|
```
|
|
107
109
|
|
|
108
|
-
Source lives in `src/`; `npm run build` writes `lib/`. The structural check is `scripts/checking-skill-links.mjs`. Tests do not invoke a local compiler; the environment checks use fixed version strings. The standard matrix needs `cmake`, `ninja`, `perl`, and `clang++` (or the compiler named by `CXX`) on a POSIX host such as WSL, Linux, or macOS.
|
|
110
|
+
Source lives in `src/`; `npm run build` writes `lib/`. The structural check is `scripts/checking-skill-links.mjs`. Tests do not invoke a local compiler; the environment checks use fixed version strings. The standard matrix needs `cmake`, `ninja`, `perl`, and `clang++` (or the compiler named by `CXX`) on a POSIX host such as WSL, Linux, or macOS. On Windows, run `npm run ci` first, then run `npm run ci:full` from WSL inside the checkout.
|
|
109
111
|
|
|
110
112
|
## License
|
|
111
113
|
|
package/README.md
CHANGED
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
npm 安装钉死版本:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.5.
|
|
22
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.5.5
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
同版本的 Git 标签:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.5.
|
|
28
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.5.5
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
桌面应用独占 `desktop` profile。命令行 `add` 被拒绝时,在应用设置里添加插件,地址填同一个 npm 版本。Git 标签安装使用仓库内已构建的 `lib/`,不在目标机器上重新构建;包内也不含需要授权执行的安装脚本。
|
|
@@ -103,9 +103,11 @@ npm ci
|
|
|
103
103
|
npm test # 构建、三技能结构检查、门禁/环境/schema/注释测试
|
|
104
104
|
npm run test:matrix # 四套模板 × 五档标准的真实构建矩阵
|
|
105
105
|
npm run pack:check # 核对 npm 包内容
|
|
106
|
+
npm run ci # 复现 Ubuntu CI:安装、测试、打包检查
|
|
107
|
+
npm run ci:full # 在 ci 之上再跑标准矩阵,需 POSIX 宿主
|
|
106
108
|
```
|
|
107
109
|
|
|
108
|
-
源码在 `src/`,`npm run build` 生成 `lib/`。结构检查在 `scripts/checking-skill-links.mjs`;测试不调用本机编译器,环境检查用固定版本字符串。标准矩阵需要 POSIX 宿主上的 `cmake`、`ninja`、`perl` 和 `clang++`(或 `CXX` 指定的编译器),在 WSL/Linux/macOS 上运行。
|
|
110
|
+
源码在 `src/`,`npm run build` 生成 `lib/`。结构检查在 `scripts/checking-skill-links.mjs`;测试不调用本机编译器,环境检查用固定版本字符串。标准矩阵需要 POSIX 宿主上的 `cmake`、`ninja`、`perl` 和 `clang++`(或 `CXX` 指定的编译器),在 WSL/Linux/macOS 上运行。Windows 上先跑 `npm run ci`,再从 WSL 进入仓库跑 `npm run ci:full`。
|
|
109
111
|
|
|
110
112
|
## 许可
|
|
111
113
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chengzhao-dev/dsh-cpp-workflow",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "C++11–C++23 工程流程技能包:源码四步、CMake 三步与构建三步,按项目声明的环境组合校验 · C++11–C++23 workflow skills for DeepSeek Harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "tsc -p tsconfig.json",
|
|
45
45
|
"test": "npm run build && node scripts/checking-skill-links.mjs && node skills/building-cpp/scripts/checking-encoding.mjs --quiet && node scripts/checking-github-workflows.mjs && node --test tests/*.test.mjs",
|
|
46
|
+
"ci": "npm ci && npm test && npm run pack:check",
|
|
47
|
+
"ci:full": "npm run ci && npm run test:matrix",
|
|
46
48
|
"check:encoding": "node skills/building-cpp/scripts/checking-encoding.mjs",
|
|
47
49
|
"check:workflows": "node scripts/checking-github-workflows.mjs",
|
|
48
50
|
"test:matrix": "bash scripts/checking-standard-matrix.sh",
|
|
@@ -14,11 +14,10 @@
|
|
|
14
14
|
**好**:
|
|
15
15
|
|
|
16
16
|
```cpp
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
//===----------------------------------------------------------------------===//
|
|
17
|
+
/// @file board.h
|
|
18
|
+
/// @brief 定义井字棋棋盘、格子坐标与格子类型。
|
|
19
|
+
///
|
|
20
|
+
/// 棋盘保存九个棋盘格子的状态,提供只读查询、落子与清空棋盘。
|
|
22
21
|
```
|
|
23
22
|
|
|
24
23
|
文件头只介绍这个文件里有什么,不写作者和变更史,也不把读者指去另一个文件。
|
|
@@ -310,11 +309,10 @@ Standard: Latest
|
|
|
310
309
|
**好**:
|
|
311
310
|
|
|
312
311
|
```cpp
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
//===----------------------------------------------------------------------===//
|
|
312
|
+
/// @file board.h
|
|
313
|
+
/// @brief 棋盘状态与规则判断。
|
|
314
|
+
///
|
|
315
|
+
/// 定义 Board 的查询、落子与清空棋盘。
|
|
318
316
|
```
|
|
319
317
|
|
|
320
318
|
变更史进提交说明,外部资料进文档,团队流程进规范文件;注释只写这个文件或这个类型自己的内容,不把读者指去别的文件。
|
|
@@ -100,7 +100,7 @@ GameResult result_ = GameResult::kInProgress;
|
|
|
100
100
|
|
|
101
101
|
| 层 | 行数 | 第一句 | 写什么 |
|
|
102
102
|
| --- | --- | --- | --- |
|
|
103
|
-
| 文件头 | 3–
|
|
103
|
+
| 文件头 | 3–7 | `@file` 文件名 + `@brief` 一句话 | 本文件由哪几部分组成 |
|
|
104
104
|
| 类型注释 | 2–14 | 名词短语:这个类型或取值是什么 | 只有类的不变量 |
|
|
105
105
|
| 特殊成员 | 1–3 | 标签(默认/拷贝/移动构造函数、析构函数) | 后置条件或职责 |
|
|
106
106
|
| 函数注释 | 3–10 | 正常返回什么、失败时返回或抛什么、检查什么 | 参数与失败方式 |
|
|
@@ -109,29 +109,28 @@ GameResult result_ = GameResult::kInProgress;
|
|
|
109
109
|
|
|
110
110
|
## 布局:放在哪一层、哪一行
|
|
111
111
|
|
|
112
|
-
- `///`
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
112
|
+
- `///` 给声明与文件头:头文件里的类型、函数、枚举值、公开与私有数据成员,以及文件头的 `@file`/`@brief` 块。数据成员的主注释写在上一行;行尾 `///<` 只用于枚举项和 `struct` 的短字段。调用方和 Doxygen 从这里取契约。
|
|
113
|
+
- `///` 也给实现:函数体内的阶段与边界说明、局部变量,一律用 `///`,不混 `//`。
|
|
114
|
+
- `//` 只留给工具指令与别种文件:`// NOLINTNEXTLINE(...)`、`#endif // MACRO` 这类要被工具读取的标记,以及 CMake、YAML 等非 C++ 文件。
|
|
115
|
+
- 判断看位置:声明写契约,实现写理由,两者都用 `///`;`//` 不再表示「实现注释」。
|
|
116
116
|
- 位置固定:文件头在最上方;类型注释紧贴类型声明;特殊成员(构造、析构、拷贝与移动)排在其他函数之前;函数注释紧贴函数声明;数据成员的主注释紧贴声明上一行,不写行尾补充。
|
|
117
117
|
- 类数据成员(含私有)的主注释用 `///`;行尾 `///<` 只给枚举项和 `struct` 的短字段。
|
|
118
118
|
- 注释和它说明的声明之间不留空行;同一个声明块内,空行只用来分组。
|
|
119
119
|
|
|
120
120
|
### 文件头
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
每个手写源文件开头写一段 doxygen 文件头:第一行 `/// @file <文件名>`,第二行 `/// @brief` 一句话说明这个文件定义或实现什么,用一行 `///` 隔开后,只写本文件自己的组成部分或边界。删掉把读者指去另一个头文件、另一个目录或另一层的句子,也删掉「这一层不负责什么」。不写作者、版权年份、变更日志和外部资料路径。
|
|
123
123
|
|
|
124
124
|
```cpp
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
//===----------------------------------------------------------------------===//
|
|
125
|
+
/// @file board.h
|
|
126
|
+
/// @brief 定义井字棋棋盘、格子坐标与格子类型。
|
|
127
|
+
///
|
|
128
|
+
/// 棋盘保存九个棋盘格子的状态,提供只读查询、落子与清空棋盘。
|
|
130
129
|
```
|
|
131
130
|
|
|
132
|
-
- C++
|
|
131
|
+
- C++ 源文件用以上格式;CMake 用 `#`,YAML/JSON 用 `#`。
|
|
133
132
|
- 超过约 200 行的文件用章节横幅分组,组名是读者要跳转的锚点;一个文件不超过 8 个横幅。
|
|
134
|
-
- 文件头 3–
|
|
133
|
+
- 文件头 3–7 行;`@file` 与 `@brief` 各占一行,后面只写本文件的范围与组成,不写实现步骤、作者和变更史。
|
|
135
134
|
|
|
136
135
|
## 排版:符号、宽度、横幅与标签
|
|
137
136
|
|
|
@@ -46,11 +46,10 @@
|
|
|
46
46
|
5. `#endif // MACRO`
|
|
47
47
|
|
|
48
48
|
```cpp
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
//===----------------------------------------------------------------------===//
|
|
49
|
+
/// @file thing_table.h
|
|
50
|
+
/// @brief 定义 ThingTable 与它用到的状态。
|
|
51
|
+
///
|
|
52
|
+
/// 头文件放常量、枚举、结构体与类声明。
|
|
54
53
|
|
|
55
54
|
#ifndef PROJECT_PATH_FILE_H_
|
|
56
55
|
#define PROJECT_PATH_FILE_H_
|
|
@@ -99,9 +98,8 @@ class ThingTable {
|
|
|
99
98
|
4. 命名空间与定义
|
|
100
99
|
|
|
101
100
|
```cpp
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
//===----------------------------------------------------------------------===//
|
|
101
|
+
/// @file thing_table.cpp
|
|
102
|
+
/// @brief 实现 ThingTable 的添加与查询。
|
|
105
103
|
|
|
106
104
|
#include "project/path/thing.h"
|
|
107
105
|
|
|
@@ -25,8 +25,10 @@ const SKIP_DIR = new Set([
|
|
|
25
25
|
'.tmp', 'temp', 'third_party', 'third-party', 'external', 'vendor', 'deps', 'cmake-build-debug',
|
|
26
26
|
'cmake-build-release', '.vs', '.idea',
|
|
27
27
|
])
|
|
28
|
-
const FORBIDDEN_TAGS = ['@returns', '@
|
|
28
|
+
const FORBIDDEN_TAGS = ['@returns', '@details', '@author', '@since', '@todo', '@date', '@copyright', '@version']
|
|
29
29
|
const BANNER = /^\/\/=+-+=+\/\/$/
|
|
30
|
+
const DOXY_FILE = /^\/\/\/\s*@file\s+\S/
|
|
31
|
+
const DOXY_BRIEF = /^\/\/\/\s*@brief\s+\S/
|
|
30
32
|
const MEMBER_LIST = /提供[^。]{0,40}、[^。]{0,40}(的功能|的能力|的接口)|功能[::]/
|
|
31
33
|
const RATIONALE = /而不是|而非|代价.{0,4}忽略|只留一份|与其|比.{0,12}更|更(?:安全|快|清楚|直接|好写|难写)/
|
|
32
34
|
const FORWARD_REF = /(?:留在|归|交给|由)\s*`?[A-Z][A-Za-z0-9_]*`?/
|
|
@@ -205,16 +207,29 @@ export function checkText(text, options = {}) {
|
|
|
205
207
|
const inClass = classMemberLines(lines)
|
|
206
208
|
|
|
207
209
|
const firstContent = lines.findIndex((line) => line.trim() !== '')
|
|
208
|
-
|
|
209
|
-
|
|
210
|
+
const firstTrimmed = firstContent === -1 ? '' : lines[firstContent].trim()
|
|
211
|
+
const hasDoxyHeader = DOXY_FILE.test(firstTrimmed)
|
|
212
|
+
let doxyHeaderEnd = -1
|
|
213
|
+
if (hasDoxyHeader) {
|
|
214
|
+
doxyHeaderEnd = firstContent
|
|
215
|
+
while (doxyHeaderEnd + 1 < lines.length && lines[doxyHeaderEnd + 1].trim().startsWith('///')) doxyHeaderEnd += 1
|
|
210
216
|
}
|
|
211
|
-
if (firstContent !== -1 && BANNER.test(
|
|
217
|
+
if (requireHeader && firstContent !== -1 && !BANNER.test(firstTrimmed) && !hasDoxyHeader) {
|
|
218
|
+
add(firstContent + 1, 'header-missing', '文件开头缺少文件头:写 /// @file <文件名>,下一行写 /// @brief')
|
|
219
|
+
}
|
|
220
|
+
if (firstContent !== -1 && (BANNER.test(firstTrimmed) || hasDoxyHeader)) {
|
|
212
221
|
const own = options.fileName ? options.fileName.split(/[\\/]/).pop() : ''
|
|
222
|
+
const bannerHeader = BANNER.test(firstTrimmed)
|
|
223
|
+
if (hasDoxyHeader && !DOXY_BRIEF.test((lines[firstContent + 1] ?? '').trim())) {
|
|
224
|
+
add(firstContent + 2, 'header-brief', '文件头第二行缺少 /// @brief 一句话说明')
|
|
225
|
+
}
|
|
213
226
|
for (let index = firstContent + 1; index < lines.length; index += 1) {
|
|
214
227
|
const trimmed = lines[index].trim()
|
|
215
|
-
if (BANNER.test(trimmed) || !trimmed.startsWith('//')) break
|
|
228
|
+
if (bannerHeader ? BANNER.test(trimmed) || !trimmed.startsWith('//') : !trimmed.startsWith('///')) break
|
|
216
229
|
const names = trimmed.match(/\b[A-Za-z0-9_-]+\.(?:h|hpp|cpp|cc)\b/g) ?? []
|
|
217
|
-
|
|
230
|
+
const fileMatches = trimmed.match(/@file\s+(\S+)/)
|
|
231
|
+
const namesToCheck = fileMatches ? names.filter((name) => name !== fileMatches[1]) : names
|
|
232
|
+
for (const name of namesToCheck) {
|
|
218
233
|
if (name !== own) add(index + 1, 'header-cross-file', `文件头提到了别的源文件 ${name}:只介绍本文件,删掉跨文件句子`)
|
|
219
234
|
}
|
|
220
235
|
if (/\bapps\//.test(trimmed)) add(index + 1, 'header-cross-file', '文件头指向了另一个目录:只介绍本文件')
|
|
@@ -238,6 +253,10 @@ export function checkText(text, options = {}) {
|
|
|
238
253
|
}
|
|
239
254
|
|
|
240
255
|
for (let index = 0; index < lines.length; index += 1) {
|
|
256
|
+
if (doxyHeaderEnd !== -1 && index <= doxyHeaderEnd) {
|
|
257
|
+
index = doxyHeaderEnd
|
|
258
|
+
continue
|
|
259
|
+
}
|
|
241
260
|
if (!lines[index].trim().startsWith('///')) continue
|
|
242
261
|
if (lines[index].trim().startsWith('///<')) continue
|
|
243
262
|
const start = index
|