rulebookguard 0.1.0 → 0.1.1
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.md +5 -2
- package/dist/cli.mjs +29 -10
- package/dist/index.d.mts +4 -1
- package/dist/index.mjs +1 -1
- package/dist/{lint-V-Uw5ueZ.mjs → lint-DtD_Ekei.mjs} +2 -1
- package/package.json +1 -1
- package/schemas/v1/config.schema.json +2 -1
package/README.md
CHANGED
|
@@ -36,9 +36,12 @@ testGlobs: # required: files scanned for @rule tags
|
|
|
36
36
|
- 'src/**/*.test.ts'
|
|
37
37
|
- 'tests/**/test_*.py'
|
|
38
38
|
contextBudget: 30 # default: 30; lint warns when a context holds more rules
|
|
39
|
+
language: es # default: en; language of the text that rulebookguard generates
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
`schema` and `testGlobs` are required (`testGlobs: []` is valid but finds no tags). Unknown fields are rejected.
|
|
42
|
+
`schema` and `testGlobs` are required (`testGlobs: []` is valid but finds no tags). Unknown fields are rejected.
|
|
43
|
+
|
|
44
|
+
`language` (`en` or `es`) sets the language of the text rulebookguard writes for you, such as the template of `new`. Rule content is free text and is never checked for language, so rules can be written in any language whatever this setting says. `language` needs rulebookguard 0.1.1 or later; older versions reject it as an unknown field. The JSON Schemas ship with the package under `rulebookguard/schemas/v1/`.
|
|
42
45
|
|
|
43
46
|
Inside a git work tree, files are listed with `git ls-files --cached --others --exclude-standard`, so anything in `.gitignore` (`dist/`, `coverage/`, caches) is never matched by anchors or test globs; files inside submodules are listed too. A submodule path that is a symlink, or that resolves outside the rulebook root, is skipped. A test file that is a symlink is scanned for `@rule` tags only when its target lies inside the rulebook root. If one submodule cannot be listed, commands print `warning: could not list files of submodule "<path>" (<reason>); skipping it.` and keep the rest of the git listing. Outside git, or when the rulebook root itself is git-ignored, the whole tree is walked, skipping only `.git` and `node_modules`. If git fails (for example, git is missing from `PATH` or the repository has dubious ownership), commands print one warning on stderr and walk the tree instead.
|
|
44
47
|
|
|
@@ -224,7 +227,7 @@ Exits 1 for an unknown id.
|
|
|
224
227
|
|
|
225
228
|
### `new <context>`
|
|
226
229
|
|
|
227
|
-
Scaffolds the next free id of a context as a `proposed` rule and prints its path. Ids are never reused, and an existing file is never overwritten.
|
|
230
|
+
Scaffolds the next free id of a context as a `proposed` rule and prints its path. Ids are never reused, and an existing file is never overwritten. The placeholder text of the new rule follows `language` in the config.
|
|
228
231
|
|
|
229
232
|
```sh
|
|
230
233
|
$ rulebookguard new clients
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { M as FormatError, N as formatIssue, _ as expandGlobs, a as CliError, c as openCatalog, d as scanTestTags, h as rulesForPath, l as writeJson, o as findRule, r as lintCommand, s as gitFallbackWarning, u as writeLines, y as toRepoPath } from "./lint-
|
|
2
|
+
import { M as FormatError, N as formatIssue, _ as expandGlobs, a as CliError, c as openCatalog, d as scanTestTags, h as rulesForPath, l as writeJson, o as findRule, r as lintCommand, s as gitFallbackWarning, u as writeLines, y as toRepoPath } from "./lint-DtD_Ekei.mjs";
|
|
3
3
|
import { readdir, writeFile } from "node:fs/promises";
|
|
4
4
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
@@ -17,32 +17,51 @@ async function newCommand(catalog, io, name) {
|
|
|
17
17
|
const id = `R-${context.prefix}-${String(last + 1).padStart(3, "0")}`;
|
|
18
18
|
const file = `${directory}/${id}.md`;
|
|
19
19
|
try {
|
|
20
|
-
await writeFile(join(catalog.root, file), template(id, context.context), { flag: "wx" });
|
|
20
|
+
await writeFile(join(catalog.root, file), template(id, context.context, catalog.config.language ?? "en"), { flag: "wx" });
|
|
21
21
|
} catch (error) {
|
|
22
22
|
if (error.code === "EEXIST") throw new CliError(`${file} already exists; nothing was written.`);
|
|
23
23
|
throw error;
|
|
24
24
|
}
|
|
25
25
|
writeLines(io, [file]);
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
const TEMPLATE_TEXT = {
|
|
28
|
+
en: {
|
|
29
|
+
summary: "TODO: one-line summary of the rule.",
|
|
30
|
+
title: "TODO: rule title",
|
|
31
|
+
intro: "TODO: state the rule in full, then add examples as Gherkin scenarios or tables.",
|
|
32
|
+
scenario: `Scenario: TODO
|
|
33
|
+
Given TODO
|
|
34
|
+
When TODO
|
|
35
|
+
Then TODO`
|
|
36
|
+
},
|
|
37
|
+
es: {
|
|
38
|
+
summary: "TODO: resumen de la regla en una línea.",
|
|
39
|
+
title: "TODO: título de la regla",
|
|
40
|
+
intro: "TODO: describe la regla completa y agrega ejemplos como escenarios Gherkin o tablas.",
|
|
41
|
+
scenario: `# language: es
|
|
42
|
+
Escenario: TODO
|
|
43
|
+
Dado TODO
|
|
44
|
+
Cuando TODO
|
|
45
|
+
Entonces TODO`
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
function template(id, context, language) {
|
|
49
|
+
const text = TEMPLATE_TEXT[language];
|
|
28
50
|
return `---
|
|
29
51
|
id: ${id}
|
|
30
52
|
context: ${context}
|
|
31
53
|
entities: []
|
|
32
54
|
status: proposed
|
|
33
55
|
anchors: []
|
|
34
|
-
summary: '
|
|
56
|
+
summary: '${text.summary}'
|
|
35
57
|
---
|
|
36
58
|
|
|
37
|
-
#
|
|
59
|
+
# ${text.title}
|
|
38
60
|
|
|
39
|
-
|
|
61
|
+
${text.intro}
|
|
40
62
|
|
|
41
63
|
\`\`\`gherkin
|
|
42
|
-
|
|
43
|
-
Given TODO
|
|
44
|
-
When TODO
|
|
45
|
-
Then TODO
|
|
64
|
+
${text.scenario}
|
|
46
65
|
\`\`\`
|
|
47
66
|
`;
|
|
48
67
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
type RuleStatus = "proposed" | "active" | "deprecated";
|
|
2
|
+
type RuleLanguage = "en" | "es";
|
|
2
3
|
interface RulebookConfig {
|
|
3
4
|
schema: 1;
|
|
4
5
|
rulesDir: string;
|
|
5
6
|
testGlobs: string[];
|
|
6
7
|
contextBudget: number;
|
|
8
|
+
/** Language the generated rule text is written in; `en` when unset. */
|
|
9
|
+
language?: RuleLanguage;
|
|
7
10
|
}
|
|
8
11
|
interface ContextFrontmatter {
|
|
9
12
|
context: string;
|
|
@@ -146,4 +149,4 @@ interface LintOptions {
|
|
|
146
149
|
export declare function lintCatalog(catalog: Catalog, tags?: TagIndex, onGitFallback?: GitFallbackListener): Promise<LintFinding[]>;
|
|
147
150
|
export declare function pendingImplementation(catalog: Catalog, tags: TagIndex, base: string, changed: string[]): LintFinding[];
|
|
148
151
|
export declare function formatFinding(finding: LintFinding): string;
|
|
149
|
-
export type { Catalog, CatalogIssue, CatalogIssueCode, ContextDoc, ContextFrontmatter, ContextsJson, ForJson, FormatIssue, Frontmatter, GitFallbackListener, ImpactJson, LintFinding, LintJson, LintOptions, LintSeverity, ListJson, RuleDoc, RuleFrontmatter, RuleStatus, RuleSummaryJson, RuleTag, RulebookConfig, ShowJson, TagIndex, TagLocation };
|
|
152
|
+
export type { Catalog, CatalogIssue, CatalogIssueCode, ContextDoc, ContextFrontmatter, ContextsJson, ForJson, FormatIssue, Frontmatter, GitFallbackListener, ImpactJson, LintFinding, LintJson, LintOptions, LintSeverity, ListJson, RuleDoc, RuleFrontmatter, RuleLanguage, RuleStatus, RuleSummaryJson, RuleTag, RulebookConfig, ShowJson, TagIndex, TagLocation };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { k as CONFIG_FILE_NAME, T as CONTEXT_FILE_NAME, M as FormatError, b as RULE_TAG_PATTERN, g as createGlobMatcher, _ as expandGlobs, x as findRuleTags, f as findRulebookRoot, t as formatFinding, N as formatIssue, S as isRuleId, n as lintCatalog, v as listRepoFiles, p as loadCatalog, A as loadConfig, E as loadContext, C as loadRule, j as parseConfig, D as parseContext, w as parseRule, i as pendingImplementation, m as relativeToRoot, h as rulesForPath, d as scanTestTags, O as splitFrontmatter, y as toRepoPath } from "./lint-
|
|
1
|
+
export { k as CONFIG_FILE_NAME, T as CONTEXT_FILE_NAME, M as FormatError, b as RULE_TAG_PATTERN, g as createGlobMatcher, _ as expandGlobs, x as findRuleTags, f as findRulebookRoot, t as formatFinding, N as formatIssue, S as isRuleId, n as lintCatalog, v as listRepoFiles, p as loadCatalog, A as loadConfig, E as loadContext, C as loadRule, j as parseConfig, D as parseContext, w as parseRule, i as pendingImplementation, m as relativeToRoot, h as rulesForPath, d as scanTestTags, O as splitFrontmatter, y as toRepoPath } from "./lint-DtD_Ekei.mjs";
|
package/package.json
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
"schema": { "const": 1 },
|
|
8
8
|
"rulesDir": { "type": "string", "minLength": 1, "default": "docs/rules" },
|
|
9
9
|
"testGlobs": { "type": "array", "items": { "type": "string", "minLength": 1 } },
|
|
10
|
-
"contextBudget": { "type": "integer", "minimum": 1, "default": 30 }
|
|
10
|
+
"contextBudget": { "type": "integer", "minimum": 1, "default": 30 },
|
|
11
|
+
"language": { "enum": ["en", "es"] }
|
|
11
12
|
},
|
|
12
13
|
"required": ["schema", "testGlobs"],
|
|
13
14
|
"additionalProperties": false
|