@meza/adr-tools 1.0.12 → 2.0.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/.github/renovate.json +2 -1
- package/.github/workflows/ci-pr.yml +2 -25
- package/.github/workflows/ci.yml +12 -46
- package/.releaserc.json +18 -8
- package/AGENTS.engineer.md +236 -0
- package/AGENTS.md +11 -0
- package/AGENTS.reviewer.md +115 -0
- package/CONTRIBUTING.md +102 -0
- package/README.md +16 -4
- package/biome.json +18 -139
- package/dist/index.js +164 -81
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +189 -0
- package/dist/index.test.js.map +1 -0
- package/dist/inject-version.test.js +27 -0
- package/dist/inject-version.test.js.map +1 -0
- package/dist/lib/adr.js +132 -27
- package/dist/lib/adr.js.map +1 -1
- package/dist/lib/adr.test.js +308 -0
- package/dist/lib/adr.test.js.map +1 -0
- package/dist/lib/config.js +3 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +60 -0
- package/dist/lib/config.test.js.map +1 -0
- package/dist/lib/links.test.js +5 -4
- package/dist/lib/links.test.js.map +1 -1
- package/dist/lib/manipulator-errors.test.js +21 -0
- package/dist/lib/manipulator-errors.test.js.map +1 -0
- package/dist/lib/manipulator.test.js +21 -1
- package/dist/lib/manipulator.test.js.map +1 -1
- package/dist/lib/numbering.js +1 -1
- package/dist/lib/numbering.js.map +1 -1
- package/dist/lib/numbering.test.js +7 -0
- package/dist/lib/numbering.test.js.map +1 -1
- package/dist/lib/opening.test.js +81 -0
- package/dist/lib/opening.test.js.map +1 -0
- package/dist/lib/prompt.js +1 -1
- package/dist/lib/prompt.js.map +1 -1
- package/dist/lib/template.test.js +62 -0
- package/dist/lib/template.test.js.map +1 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.test.d.ts +2 -0
- package/dist/types/index.test.d.ts.map +1 -0
- package/dist/types/inject-version.test.d.ts +2 -0
- package/dist/types/inject-version.test.d.ts.map +1 -0
- package/dist/types/lib/adr.d.ts +15 -0
- package/dist/types/lib/adr.d.ts.map +1 -1
- package/dist/types/lib/adr.test.d.ts +2 -0
- package/dist/types/lib/adr.test.d.ts.map +1 -0
- package/dist/types/lib/config.d.ts.map +1 -1
- package/dist/types/lib/config.test.d.ts +2 -0
- package/dist/types/lib/config.test.d.ts.map +1 -0
- package/dist/types/lib/manipulator-errors.test.d.ts +2 -0
- package/dist/types/lib/manipulator-errors.test.d.ts.map +1 -0
- package/dist/types/lib/opening.test.d.ts +2 -0
- package/dist/types/lib/opening.test.d.ts.map +1 -0
- package/dist/types/lib/prompt.d.ts.map +1 -1
- package/dist/types/lib/template.test.d.ts +2 -0
- package/dist/types/lib/template.test.d.ts.map +1 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/doc/adr/.adr-sequence.lock +1 -1
- package/doc/adr/0001-record-architecture-decisions.md +21 -0
- package/doc/adr/0002-using-heavy-e2e-tests.md +20 -0
- package/doc/adr/0003-esm.md +34 -0
- package/doc/adr/0004-gate-editor-opening-behind---open-and---open-with.md +55 -0
- package/doc/adr/decisions.md +4 -1
- package/lefthook.yml +14 -0
- package/package.json +24 -26
- package/scripts/inject-version.mjs +34 -0
- package/src/index.test.ts +212 -0
- package/src/index.ts +229 -108
- package/src/inject-version.test.ts +31 -0
- package/src/lib/adr.test.ts +376 -0
- package/src/lib/adr.ts +173 -27
- package/src/lib/config.test.ts +69 -0
- package/src/lib/config.ts +3 -2
- package/src/lib/links.test.ts +8 -4
- package/src/lib/manipulator-errors.test.ts +22 -0
- package/src/lib/manipulator.test.ts +25 -1
- package/src/lib/numbering.test.ts +8 -0
- package/src/lib/numbering.ts +1 -1
- package/src/lib/opening.test.ts +96 -0
- package/src/lib/prompt.ts +1 -1
- package/src/lib/template.test.ts +74 -0
- package/src/version.ts +1 -2
- package/tests/edit-on-create.e2e.test.ts +47 -16
- package/tests/fake-editor.cmd +2 -0
- package/tests/fake-visual.cmd +2 -0
- package/tests/funny-characters.e2e.test.ts +12 -11
- package/tests/generate-graph.e2e.test.ts +13 -17
- package/tests/helpers/adr-cli.ts +24 -0
- package/tests/init-adr-repository.e2e.test.ts +7 -6
- package/tests/linking-records.e2e.test.ts +14 -13
- package/tests/list-adrs.e2e.test.ts +26 -19
- package/tests/new-adr.e2e.test.ts +10 -9
- package/tests/open-with.e2e.test.ts +53 -0
- package/tests/superseding-records.e2e.test.ts +11 -10
- package/tests/toc-prefixing.e2e.test.ts +10 -9
- package/tests/use-template-override.e2e.test.ts +9 -8
- package/tests/work-form-other-directories.e2e.test.ts +10 -8
- package/vitest.config.e2e.ts +8 -1
- package/vitest.config.ts +20 -4
- package/.github/workflows/sync-deps-to-main.yml +0 -25
- package/.github/workflows/sync-to-deps.yml +0 -26
- package/.husky/commit-msg +0 -4
- package/CHANGELOG.md +0 -121
- package/scripts/inject-version.sh +0 -4
package/README.md
CHANGED
|
@@ -11,9 +11,9 @@ If you’re interested in reading more about what ADRs are and why they’re imp
|
|
|
11
11
|
|
|
12
12
|
## **ADR Location Convention**
|
|
13
13
|
|
|
14
|
-
By convention we store the decisions in
|
|
14
|
+
By convention we store the decisions in `doc/adr` (this repo is configured via `.adr-dir`).
|
|
15
15
|
|
|
16
|
-
You can also check where the directory is by inspecting the
|
|
16
|
+
You can also check where the directory is by inspecting the `.adr-dir` file’s contents.
|
|
17
17
|
|
|
18
18
|
## **ADR CLI in node land**
|
|
19
19
|
|
|
@@ -35,7 +35,19 @@ adr new A new decision the team has made
|
|
|
35
35
|
|
|
36
36
|
This will automatically figure out the numbering sequence, get the correct filename format and use the title inside of an ADR template.
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
By default, `adr new` only writes the file. To open it after creation, pass `--open`:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
adr new --open A new decision the team has made
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
You can also force a specific opener via `--open-with` (optionally with args):
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
adr new --open-with "code --wait" A new decision the team has made
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
When `--open` is set and `--open-with` is not, the tool prefers `VISUAL`, then `EDITOR` (but ignores npm-injected editor defaults), then falls back to the OS default opener.
|
|
39
51
|
|
|
40
52
|
### **Superseding previous decisions**
|
|
41
53
|
|
|
@@ -75,7 +87,7 @@ An ADR file MUST have a `# title` at the top and a `## Status` header.
|
|
|
75
87
|
|
|
76
88
|
## Local Development
|
|
77
89
|
|
|
78
|
-
`
|
|
90
|
+
See `CONTRIBUTING.md` for the recommended local setup and verification commands.
|
|
79
91
|
|
|
80
92
|
### Commits
|
|
81
93
|
|
package/biome.json
CHANGED
|
@@ -1,148 +1,27 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
"extends": ["@meza/biome"],
|
|
3
|
+
"files": {
|
|
4
|
+
"includes": [
|
|
5
|
+
"**/*.ts",
|
|
6
|
+
"**/*.css",
|
|
7
|
+
"**/*.tsx",
|
|
8
|
+
"**/*.json",
|
|
9
|
+
"!**/*.snap",
|
|
10
|
+
"!**/node_modules",
|
|
11
|
+
"!**/dist",
|
|
12
|
+
"!reports/**"
|
|
13
|
+
]
|
|
9
14
|
},
|
|
10
|
-
"formatter": {
|
|
11
|
-
"enabled": true,
|
|
12
|
-
"indentStyle": "space",
|
|
13
|
-
"indentWidth": 2,
|
|
14
|
-
"lineWidth": 120,
|
|
15
|
-
"lineEnding": "lf",
|
|
16
|
-
"include": ["**/*.ts", "**/*.json"],
|
|
17
|
-
"ignore": [".cache/**"],
|
|
18
|
-
"attributePosition": "auto"
|
|
19
|
-
},
|
|
20
|
-
"files": { "include": ["**/*.ts", "**/*.json"], "ignore": ["package*.json"] },
|
|
21
15
|
"linter": {
|
|
22
|
-
"enabled": true,
|
|
23
16
|
"rules": {
|
|
24
|
-
"recommended": false,
|
|
25
17
|
"complexity": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"noUselessTernary": "error",
|
|
32
|
-
"noUselessThisAlias": "error",
|
|
33
|
-
"noUselessTypeConstraint": "error",
|
|
34
|
-
"noVoid": "error",
|
|
35
|
-
"noWith": "error",
|
|
36
|
-
"useArrowFunction": "error",
|
|
37
|
-
"useLiteralKeys": "error"
|
|
38
|
-
},
|
|
39
|
-
"correctness": {
|
|
40
|
-
"noConstAssign": "error",
|
|
41
|
-
"noConstantCondition": "error",
|
|
42
|
-
"noEmptyCharacterClassInRegex": "error",
|
|
43
|
-
"noEmptyPattern": "error",
|
|
44
|
-
"noGlobalObjectCalls": "error",
|
|
45
|
-
"noInnerDeclarations": "error",
|
|
46
|
-
"noInvalidConstructorSuper": "error",
|
|
47
|
-
"noInvalidUseBeforeDeclaration": "error",
|
|
48
|
-
"noNewSymbol": "error",
|
|
49
|
-
"noNonoctalDecimalEscape": "error",
|
|
50
|
-
"noPrecisionLoss": "error",
|
|
51
|
-
"noSelfAssign": "error",
|
|
52
|
-
"noSetterReturn": "error",
|
|
53
|
-
"noSwitchDeclarations": "error",
|
|
54
|
-
"noUndeclaredVariables": "error",
|
|
55
|
-
"noUnreachable": "error",
|
|
56
|
-
"noUnreachableSuper": "error",
|
|
57
|
-
"noUnsafeFinally": "error",
|
|
58
|
-
"noUnsafeOptionalChaining": "error",
|
|
59
|
-
"noUnusedLabels": "error",
|
|
60
|
-
"noUnusedVariables": "error",
|
|
61
|
-
"useArrayLiterals": "off",
|
|
62
|
-
"useIsNan": "error",
|
|
63
|
-
"useValidForDirection": "error",
|
|
64
|
-
"useYield": "error"
|
|
65
|
-
},
|
|
66
|
-
"security": { "noGlobalEval": "error" },
|
|
67
|
-
"style": {
|
|
68
|
-
"noCommaOperator": "error",
|
|
69
|
-
"noNamespace": "off",
|
|
70
|
-
"noParameterAssign": "error",
|
|
71
|
-
"noUselessElse": "error",
|
|
72
|
-
"noVar": "off",
|
|
73
|
-
"useAsConstAssertion": "error",
|
|
74
|
-
"useBlockStatements": "error",
|
|
75
|
-
"useCollapsedElseIf": "error",
|
|
76
|
-
"useConst": "error",
|
|
77
|
-
"useShorthandAssign": "error",
|
|
78
|
-
"useSingleVarDeclarator": "off"
|
|
79
|
-
},
|
|
80
|
-
"suspicious": {
|
|
81
|
-
"noAssignInExpressions": "error",
|
|
82
|
-
"noAsyncPromiseExecutor": "error",
|
|
83
|
-
"noCatchAssign": "error",
|
|
84
|
-
"noClassAssign": "error",
|
|
85
|
-
"noCompareNegZero": "error",
|
|
86
|
-
"noConfusingLabels": "error",
|
|
87
|
-
"noConsoleLog": "off",
|
|
88
|
-
"noControlCharactersInRegex": "error",
|
|
89
|
-
"noDebugger": "error",
|
|
90
|
-
"noDoubleEquals": "error",
|
|
91
|
-
"noDuplicateCase": "error",
|
|
92
|
-
"noDuplicateClassMembers": "error",
|
|
93
|
-
"noDuplicateObjectKeys": "error",
|
|
94
|
-
"noDuplicateParameters": "error",
|
|
95
|
-
"noEmptyBlockStatements": "error",
|
|
96
|
-
"noExplicitAny": "error",
|
|
97
|
-
"noExtraNonNullAssertion": "error",
|
|
98
|
-
"noFallthroughSwitchClause": "error",
|
|
99
|
-
"noFunctionAssign": "error",
|
|
100
|
-
"noGlobalAssign": "error",
|
|
101
|
-
"noImportAssign": "error",
|
|
102
|
-
"noLabelVar": "error",
|
|
103
|
-
"noMisleadingCharacterClass": "error",
|
|
104
|
-
"noMisleadingInstantiator": "error",
|
|
105
|
-
"noPrototypeBuiltins": "error",
|
|
106
|
-
"noRedeclare": "error",
|
|
107
|
-
"noSelfCompare": "error",
|
|
108
|
-
"noShadowRestrictedNames": "error",
|
|
109
|
-
"noUnsafeDeclarationMerging": "error",
|
|
110
|
-
"noUnsafeNegation": "error",
|
|
111
|
-
"useGetterReturn": "error",
|
|
112
|
-
"useValidTypeof": "error"
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
"ignore": ["**/node_modules", "**/dist", "lib/murmurhash3.ts"]
|
|
116
|
-
},
|
|
117
|
-
"json": {
|
|
118
|
-
"formatter": {
|
|
119
|
-
"trailingCommas": "none",
|
|
120
|
-
"enabled": true
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
"javascript": {
|
|
124
|
-
"formatter": {
|
|
125
|
-
"quoteStyle": "single",
|
|
126
|
-
"enabled": true,
|
|
127
|
-
"semicolons": "always",
|
|
128
|
-
"quoteProperties": "asNeeded",
|
|
129
|
-
"trailingCommas": "none",
|
|
130
|
-
"bracketSpacing": true,
|
|
131
|
-
"bracketSameLine": true,
|
|
132
|
-
"attributePosition": "auto"
|
|
133
|
-
},
|
|
134
|
-
"globals": []
|
|
135
|
-
},
|
|
136
|
-
"overrides": [
|
|
137
|
-
{
|
|
138
|
-
"include": ["**/*.test.ts", "test/**/*.ts"],
|
|
139
|
-
"linter": {
|
|
140
|
-
"rules": {
|
|
141
|
-
"correctness": { "noInvalidUseBeforeDeclaration": "off" },
|
|
142
|
-
"style": { "noNonNullAssertion": "off" },
|
|
143
|
-
"suspicious": { "noEmptyBlockStatements": "off", "noExplicitAny": "off" }
|
|
18
|
+
"noExcessiveCognitiveComplexity": {
|
|
19
|
+
"level": "error",
|
|
20
|
+
"options": {
|
|
21
|
+
"maxAllowedComplexity": 10
|
|
22
|
+
}
|
|
144
23
|
}
|
|
145
24
|
}
|
|
146
25
|
}
|
|
147
|
-
|
|
26
|
+
}
|
|
148
27
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
3
5
|
import chalk from 'chalk';
|
|
4
6
|
import { Command } from 'commander';
|
|
5
|
-
import fs from 'fs/promises';
|
|
6
7
|
import { generateToc, init, link, listAdrs, newAdr } from './lib/adr.js';
|
|
7
8
|
import { workingDir } from './lib/config.js';
|
|
8
9
|
import { getLinksFrom, getTitleFrom } from './lib/manipulator.js';
|
|
9
10
|
import { LIB_VERSION } from './version.js';
|
|
10
|
-
const program = new Command();
|
|
11
11
|
const collectLinks = (val, memo) => {
|
|
12
12
|
memo.push(val);
|
|
13
13
|
return memo;
|
|
@@ -16,90 +16,173 @@ const collectSupersedes = (val, memo) => {
|
|
|
16
16
|
memo.push(val);
|
|
17
17
|
return memo;
|
|
18
18
|
};
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
export const defaultOnError = (program, error) => {
|
|
20
|
+
program.error(chalk.red(error.message), { exitCode: 1 });
|
|
21
|
+
};
|
|
22
|
+
const defaultDeps = {
|
|
23
|
+
generateToc,
|
|
24
|
+
init,
|
|
25
|
+
link,
|
|
26
|
+
listAdrs,
|
|
27
|
+
newAdr,
|
|
28
|
+
workingDir,
|
|
29
|
+
readFile: fs.readFile,
|
|
30
|
+
getLinksFrom,
|
|
31
|
+
getTitleFrom,
|
|
32
|
+
version: LIB_VERSION,
|
|
33
|
+
onError: defaultOnError,
|
|
34
|
+
log: console.log,
|
|
35
|
+
warn: console.warn
|
|
36
|
+
};
|
|
37
|
+
const escapeDotString = (value) => value
|
|
38
|
+
.replace(/\\/g, '\\\\')
|
|
39
|
+
.replace(/"/g, '\\"')
|
|
40
|
+
.replace(/\r\n|\n|\r/g, '\\\\n');
|
|
41
|
+
const getAdrNumberFromPath = (adrPath) => {
|
|
42
|
+
const baseName = path.basename(adrPath, '.md');
|
|
43
|
+
const match = baseName.match(/^0*(\d+)-/);
|
|
44
|
+
if (!match) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return Number.parseInt(match[1], 10);
|
|
48
|
+
};
|
|
49
|
+
const resolveGraphNodes = (adrs) => adrs
|
|
50
|
+
.map((adrPath) => ({ adrPath, number: getAdrNumberFromPath(adrPath) }))
|
|
51
|
+
.filter((node) => node.number !== undefined);
|
|
52
|
+
const appendGraphNodes = async (deps, nodes, options, lines) => {
|
|
53
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
54
|
+
const n = nodes[i].number;
|
|
55
|
+
const adrPath = nodes[i].adrPath;
|
|
56
|
+
const contents = await deps.readFile(adrPath, 'utf8');
|
|
57
|
+
const title = deps.getTitleFrom(contents);
|
|
58
|
+
const url = `${options?.prefix || ''}${path.basename(adrPath, '.md')}${options?.extension}`;
|
|
59
|
+
lines.push(` _${n} [label="${escapeDotString(title)}"; URL="${escapeDotString(url)}"];`);
|
|
60
|
+
const previous = nodes[i - 1]?.number;
|
|
61
|
+
if (previous !== undefined) {
|
|
62
|
+
lines.push(` _${previous} -> _${n} [style="dotted", weight=1];`);
|
|
32
63
|
}
|
|
33
64
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
65
|
+
};
|
|
66
|
+
const resolveTargetNodeId = (nodeIds, targetNumber) => {
|
|
67
|
+
const number = Number.parseInt(targetNumber, 10);
|
|
68
|
+
if (!Number.isFinite(number) || !nodeIds.has(number)) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return number;
|
|
72
|
+
};
|
|
73
|
+
const appendGraphEdges = async (deps, nodes, lines) => {
|
|
74
|
+
const nodeIds = new Set(nodes.map((node) => node.number));
|
|
75
|
+
for (const node of nodes) {
|
|
76
|
+
const contents = await deps.readFile(node.adrPath, 'utf8');
|
|
77
|
+
const linksInADR = deps.getLinksFrom(contents);
|
|
78
|
+
for (const link of linksInADR) {
|
|
79
|
+
if (link.label.endsWith('by')) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const target = resolveTargetNodeId(nodeIds, link.targetNumber);
|
|
83
|
+
if (target !== undefined) {
|
|
84
|
+
lines.push(` _${node.number} -> _${target} [label="${link.label}", weight=0]`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
deps.warn(`Skipping graph link from ADR ${node.number} to missing ADR ${link.targetNumber}: ${link.label}`);
|
|
43
88
|
}
|
|
44
89
|
}
|
|
45
90
|
}
|
|
46
|
-
text += '}\n';
|
|
47
|
-
console.log(text);
|
|
48
91
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
.
|
|
52
|
-
.
|
|
53
|
-
.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
`${
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
92
|
+
const generateGraph = async (deps, options) => {
|
|
93
|
+
const lines = [];
|
|
94
|
+
lines.push('digraph {');
|
|
95
|
+
lines.push(' node [shape=plaintext];');
|
|
96
|
+
lines.push(' subgraph {');
|
|
97
|
+
const adrs = await deps.listAdrs();
|
|
98
|
+
const nodes = resolveGraphNodes(adrs);
|
|
99
|
+
await appendGraphNodes(deps, nodes, options, lines);
|
|
100
|
+
lines.push(' }');
|
|
101
|
+
await appendGraphEdges(deps, nodes, lines);
|
|
102
|
+
lines.push('}');
|
|
103
|
+
deps.log(`${lines.join('\n')}\n`);
|
|
104
|
+
};
|
|
105
|
+
export const buildProgram = (deps = defaultDeps) => {
|
|
106
|
+
const program = new Command();
|
|
107
|
+
program.name('adr').version(deps.version).description('Manage Architecture Decision Logs');
|
|
108
|
+
program
|
|
109
|
+
.command('new')
|
|
110
|
+
.argument('<title...>', 'The title of the decision')
|
|
111
|
+
.option('-q, --quiet', 'Do not ask for clarification. If multiple files match the search pattern, an error will be thrown.')
|
|
112
|
+
.option('--open', 'Open the created ADR after writing it (use OS default or `--open-with`).')
|
|
113
|
+
.option('--open-with <COMMAND>', 'Open the created ADR with a specific command (optionally with args); implies `--open`.')
|
|
114
|
+
.option('-s, --supersede <SUPERSEDE>', 'A reference (number or partial filename) of a previous decision that the new decision supercedes.\n' +
|
|
115
|
+
'A Markdown link to the superceded ADR is inserted into the Status section.\n' +
|
|
116
|
+
'The status of the superceded ADR is changed to record that it has been superceded by the new ADR.', collectSupersedes, [])
|
|
117
|
+
.option('-l, --link "<TARGET:LINK:REVERSE-LINK>"', 'Links the new ADR to a previous ADR.\n' +
|
|
118
|
+
`${chalk.bold('TARGET')} is a reference (number or partial filename) of a previous decision.\n` +
|
|
119
|
+
`${chalk.bold('LINK')} is the description of the link created in the new ADR.\n` +
|
|
120
|
+
`${chalk.bold('REVERSE-LINK')} is the description of the link created in the existing ADR that will refer to the new ADR`, collectLinks, [])
|
|
121
|
+
.action(async (title, options) => {
|
|
122
|
+
try {
|
|
123
|
+
await deps.newAdr(title.join(' '), {
|
|
124
|
+
supersedes: options.supersede,
|
|
125
|
+
date: process.env.ADR_DATE,
|
|
126
|
+
suppressPrompts: options.quiet || false,
|
|
127
|
+
links: options.link,
|
|
128
|
+
open: options.open || Boolean(options.openWith),
|
|
129
|
+
openWith: options.openWith
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
deps.onError(program, e);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
const generate = program.command('generate');
|
|
137
|
+
generate
|
|
138
|
+
.command('toc')
|
|
139
|
+
.option('-p, --prefix <PREFIX>', 'The prefix to use for each file link in the generated TOC.')
|
|
140
|
+
.action((options) => deps.generateToc(options));
|
|
141
|
+
generate
|
|
142
|
+
.command('graph')
|
|
143
|
+
.option('-p, --prefix <PREFIX>', 'Prefix each decision file link with PREFIX.')
|
|
144
|
+
.option('-e, --extension <EXTENSION>', 'the file extension of the documents to which generated links refer. Defaults to .html', '.html')
|
|
145
|
+
.action(async (options) => {
|
|
146
|
+
await generateGraph(deps, options);
|
|
147
|
+
});
|
|
148
|
+
program
|
|
149
|
+
.command('link')
|
|
150
|
+
.argument('<SOURCE>', 'Full or Partial reference number to an ADR')
|
|
151
|
+
.argument('<LINK>', 'The description of the link created in the SOURCE')
|
|
152
|
+
.argument('<TARGET>', 'Full or Partial reference number to an ADR')
|
|
153
|
+
.argument('<REVERSE-LINK>', 'The description of the link created in the TARGET')
|
|
154
|
+
.option('-q, --quiet', 'Do not ask for clarification. If multiple files match the search pattern, an error will be thrown.')
|
|
155
|
+
.action(deps.link);
|
|
156
|
+
program
|
|
157
|
+
.command('init')
|
|
158
|
+
.argument('[directory]', 'Initialize a new ADR directory')
|
|
159
|
+
.action(async (directory) => {
|
|
160
|
+
await deps.init(directory);
|
|
161
|
+
});
|
|
162
|
+
program.command('list').action(async () => {
|
|
163
|
+
const adrs = await deps.listAdrs();
|
|
164
|
+
deps.log(adrs.map((adr) => path.relative(deps.workingDir(), adr)).join('\n'));
|
|
165
|
+
});
|
|
166
|
+
return program;
|
|
167
|
+
};
|
|
168
|
+
export const run = async (argv = process.argv, deps = defaultDeps) => {
|
|
169
|
+
const program = buildProgram(deps);
|
|
170
|
+
await program.parseAsync(argv);
|
|
171
|
+
return program;
|
|
172
|
+
};
|
|
173
|
+
export const isDirectRun = (argv = process.argv, moduleUrl = import.meta.url) => {
|
|
174
|
+
if (!argv[1]) {
|
|
175
|
+
return false;
|
|
69
176
|
}
|
|
70
|
-
|
|
71
|
-
|
|
177
|
+
return path.resolve(argv[1]) === fileURLToPath(moduleUrl);
|
|
178
|
+
};
|
|
179
|
+
export const maybeRun = (argv = process.argv, deps) => {
|
|
180
|
+
if (!isDirectRun(argv)) {
|
|
181
|
+
return false;
|
|
72
182
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.action((options) => generateToc(options));
|
|
79
|
-
generate
|
|
80
|
-
.command('graph')
|
|
81
|
-
.option('-p, --prefix <PREFIX>', 'Prefix each decision file link with PREFIX.')
|
|
82
|
-
.option('-e, --extension <EXTENSION>', 'the file extension of the documents to which generated links refer. Defaults to .html', '.html')
|
|
83
|
-
.action(async (options) => {
|
|
84
|
-
await generateGraph(options);
|
|
85
|
-
});
|
|
86
|
-
program
|
|
87
|
-
.command('link')
|
|
88
|
-
.argument('<SOURCE>', 'Full or Partial reference number to an ADR')
|
|
89
|
-
.argument('<LINK>', 'The description of the link created in the SOURCE')
|
|
90
|
-
.argument('<TARGET>', 'Full or Partial reference number to an ADR')
|
|
91
|
-
.argument('<REVERSE-LINK>', 'The description of the link created in the TARGET')
|
|
92
|
-
.option('-q, --quiet', 'Do not ask for clarification. If multiple files match the search pattern, an error will be thrown.')
|
|
93
|
-
.action(link);
|
|
94
|
-
program
|
|
95
|
-
.command('init')
|
|
96
|
-
.argument('[directory]', 'Initialize a new ADR directory')
|
|
97
|
-
.action(async (directory) => {
|
|
98
|
-
await init(directory);
|
|
99
|
-
});
|
|
100
|
-
program.command('list').action(async () => {
|
|
101
|
-
const adrs = await listAdrs();
|
|
102
|
-
console.log(adrs.map((adr) => path.relative(workingDir(), adr)).join('\n'));
|
|
103
|
-
});
|
|
104
|
-
program.parse();
|
|
183
|
+
const runPromise = run(argv, deps);
|
|
184
|
+
runPromise.catch(() => undefined);
|
|
185
|
+
return true;
|
|
186
|
+
};
|
|
187
|
+
maybeRun();
|
|
105
188
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":";AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"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"}
|