adr-kit 0.2.5 → 0.2.6
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 +47 -39
- package/README.zh.md +43 -36
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/accept.d.ts.map +1 -1
- package/dist/commands/accept.js +12 -14
- package/dist/commands/accept.js.map +1 -1
- package/dist/commands/decide.d.ts.map +1 -1
- package/dist/commands/decide.js +3 -2
- package/dist/commands/decide.js.map +1 -1
- package/dist/commands/init.js +2 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/instructions.d.ts.map +1 -1
- package/dist/commands/instructions.js +24 -25
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +14 -14
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/propose.d.ts.map +1 -1
- package/dist/commands/propose.js +12 -5
- package/dist/commands/propose.js.map +1 -1
- package/dist/commands/reject.d.ts +1 -1
- package/dist/commands/reject.d.ts.map +1 -1
- package/dist/commands/reject.js +8 -20
- package/dist/commands/reject.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +16 -2
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +15 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/supersede.d.ts.map +1 -1
- package/dist/commands/supersede.js +7 -2
- package/dist/commands/supersede.js.map +1 -1
- package/dist/core/adr.d.ts +10 -4
- package/dist/core/adr.d.ts.map +1 -1
- package/dist/core/adr.js +14 -23
- package/dist/core/adr.js.map +1 -1
- package/dist/core/git.d.ts +9 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +22 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/repository.d.ts +11 -0
- package/dist/core/repository.d.ts.map +1 -1
- package/dist/core/repository.js +89 -16
- package/dist/core/repository.js.map +1 -1
- package/dist/core/templates.d.ts +7 -7
- package/dist/core/templates.d.ts.map +1 -1
- package/dist/core/templates.js +15 -25
- package/dist/core/templates.js.map +1 -1
- package/dist/core/tool-integrations.d.ts.map +1 -1
- package/dist/core/tool-integrations.js +33 -26
- package/dist/core/tool-integrations.js.map +1 -1
- package/dist/core/validate.d.ts +6 -0
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/core/validate.js +103 -94
- package/dist/core/validate.js.map +1 -1
- package/package.json +1 -1
package/dist/core/validate.js
CHANGED
|
@@ -1,26 +1,80 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join, relative } from 'node:path';
|
|
3
|
-
import { DATE_PATTERN, hasMeaningfulBody, PROPOSAL_ERA_HEADINGS,
|
|
3
|
+
import { DATE_PATTERN, hasMeaningfulBody, PROPOSAL_ERA_HEADINGS, } from './adr.js';
|
|
4
4
|
import { ADR_DIR, CONFIG_FILE, readConfig } from './config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { listRecords } from './repository.js';
|
|
6
6
|
const DECISION_REQUIRED = ['Problem', 'Decision', 'Alternatives considered', 'Consequences'];
|
|
7
7
|
const PROPOSED_REQUIRED = ['Problem', 'Proposal', 'Alternatives considered', 'Acceptance criteria', 'Risks'];
|
|
8
|
-
|
|
8
|
+
function calendarDateIsValid(year, month, day) {
|
|
9
|
+
const date = new Date(year, month - 1, day);
|
|
10
|
+
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The parser already enforces the YYYY-MM-DD format, so this only checks
|
|
14
|
+
* calendar validity; the match is never null for a parsed record.
|
|
15
|
+
*/
|
|
16
|
+
function dateIssue(record) {
|
|
17
|
+
const match = record.date.match(DATE_PATTERN);
|
|
18
|
+
if (match === null)
|
|
19
|
+
return undefined;
|
|
20
|
+
if (!calendarDateIsValid(Number(match[1]), Number(match[2]), Number(match[3]))) {
|
|
21
|
+
return 'front matter date contains an invalid calendar date';
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/** Required-section, meaningful-body, and duplicate-section checks, shared by decisions and drafts. */
|
|
26
|
+
function sectionIssues(path, sections, required, meaningful) {
|
|
27
|
+
const issues = [];
|
|
28
|
+
const headings = new Set(sections.map((section) => section.heading));
|
|
29
|
+
for (const heading of required) {
|
|
30
|
+
if (!headings.has(heading)) {
|
|
31
|
+
issues.push({ path, message: `missing required section "## ${heading}"` });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (const heading of meaningful) {
|
|
35
|
+
const body = sections.find((section) => section.heading === heading)?.body;
|
|
36
|
+
if (!hasMeaningfulBody(body)) {
|
|
37
|
+
issues.push({ path, message: `section "## ${heading}" must contain written content` });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
for (const section of sections) {
|
|
42
|
+
if (seen.has(section.heading)) {
|
|
43
|
+
issues.push({ path, message: `duplicate section "## ${section.heading}"` });
|
|
44
|
+
}
|
|
45
|
+
seen.add(section.heading);
|
|
46
|
+
}
|
|
47
|
+
return issues;
|
|
48
|
+
}
|
|
49
|
+
function alternativesIssue(path, sections) {
|
|
50
|
+
if (!hasMeaningfulBody(sections.find((section) => section.heading === 'Alternatives considered')?.body)) {
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
path,
|
|
54
|
+
message: 'section "## Alternatives considered" must contain at least one written alternative',
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
9
60
|
export function validateRecord(root, record) {
|
|
10
61
|
const issues = [];
|
|
11
62
|
const path = relative(root, record.path);
|
|
12
63
|
for (const key of record.frontMatterExtras ?? []) {
|
|
13
64
|
issues.push({ path, message: `unknown front matter field "${key}"` });
|
|
14
65
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
66
|
+
if (record.status !== 'accepted' && record.status !== 'superseded') {
|
|
67
|
+
const hint = record.status === 'rejected'
|
|
68
|
+
? 'rejection is recorded in a decision\'s "Alternatives considered", not as a standalone status'
|
|
69
|
+
: 'proposals are ephemeral drafts in adr/.drafts/';
|
|
19
70
|
issues.push({
|
|
20
71
|
path,
|
|
21
|
-
message: `status "${record.status}"
|
|
72
|
+
message: `status "${record.status}" is not a durable decision status; ${hint}`,
|
|
22
73
|
});
|
|
23
74
|
}
|
|
75
|
+
if (record.commit !== undefined && !/^[0-9a-f]{7,40}$/.test(record.commit)) {
|
|
76
|
+
issues.push({ path, message: `commit "${record.commit}" is not a git hash` });
|
|
77
|
+
}
|
|
24
78
|
if (record.status === 'superseded') {
|
|
25
79
|
if (record.supersededBy === undefined) {
|
|
26
80
|
issues.push({ path, message: 'superseded status must reference a decision number' });
|
|
@@ -29,97 +83,57 @@ export function validateRecord(root, record) {
|
|
|
29
83
|
issues.push({ path, message: 'a decision cannot supersede itself' });
|
|
30
84
|
}
|
|
31
85
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
const month = Number(dateMatch[2]);
|
|
38
|
-
const day = Number(dateMatch[3]);
|
|
39
|
-
const date = new Date(year, month - 1, day);
|
|
40
|
-
if (date.getFullYear() !== year ||
|
|
41
|
-
date.getMonth() !== month - 1 ||
|
|
42
|
-
date.getDate() !== day) {
|
|
43
|
-
issues.push({ path, message: 'front matter date contains an invalid calendar date' });
|
|
44
|
-
}
|
|
86
|
+
const dateError = dateIssue(record);
|
|
87
|
+
if (dateError !== undefined)
|
|
88
|
+
issues.push({ path, message: dateError });
|
|
89
|
+
if (!/^[1-9]\d*-[a-z0-9一-鿿-]+\.md$/.test(record.fileName)) {
|
|
90
|
+
issues.push({ path, message: 'decision file name must be "N-slug.md"' });
|
|
45
91
|
}
|
|
46
|
-
if (record.
|
|
47
|
-
|
|
48
|
-
issues.push({ path, message: 'decision file name must be "N-slug.md"' });
|
|
49
|
-
}
|
|
50
|
-
if (record.number === undefined) {
|
|
51
|
-
issues.push({ path, message: 'accepted decision title must be "# ADR: N <title>"' });
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
if (!record.fileName.startsWith(`${record.number}-`)) {
|
|
55
|
-
issues.push({ path, message: `file name number must match title number ${record.number}` });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
92
|
+
if (record.number === undefined) {
|
|
93
|
+
issues.push({ path, message: 'accepted decision title must be "# ADR: N <title>"' });
|
|
58
94
|
}
|
|
59
|
-
else {
|
|
60
|
-
|
|
61
|
-
const match = record.fileName.match(datePattern);
|
|
62
|
-
if (match === null) {
|
|
63
|
-
issues.push({ path, message: 'file name must be "YYYY-MM-DD-slug.md"' });
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
const year = Number(match[1]);
|
|
67
|
-
const month = Number(match[2]);
|
|
68
|
-
const day = Number(match[3]);
|
|
69
|
-
const date = new Date(year, month - 1, day);
|
|
70
|
-
if (date.getFullYear() !== year ||
|
|
71
|
-
date.getMonth() !== month - 1 ||
|
|
72
|
-
date.getDate() !== day) {
|
|
73
|
-
issues.push({ path, message: 'file name contains an invalid calendar date' });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
95
|
+
else if (!record.fileName.startsWith(`${record.number}-`)) {
|
|
96
|
+
issues.push({ path, message: `file name number must match title number ${record.number}` });
|
|
76
97
|
}
|
|
77
|
-
|
|
78
|
-
? DECISION_REQUIRED
|
|
79
|
-
: record.folder === 'proposed'
|
|
80
|
-
? PROPOSED_REQUIRED
|
|
81
|
-
: REJECTED_REQUIRED;
|
|
98
|
+
issues.push(...sectionIssues(path, record.sections, DECISION_REQUIRED, ['Problem', 'Decision']));
|
|
82
99
|
const headings = new Set(record.sections.map((section) => section.heading));
|
|
83
|
-
for (const heading of
|
|
84
|
-
if (
|
|
85
|
-
issues.push({ path, message: `missing required section "## ${heading}"` });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
const meaningfulHeadings = record.folder === 'decisions'
|
|
89
|
-
? ['Problem', 'Decision']
|
|
90
|
-
: ['Problem', 'Proposal'];
|
|
91
|
-
for (const heading of meaningfulHeadings) {
|
|
92
|
-
const body = record.sections.find((section) => section.heading === heading)?.body;
|
|
93
|
-
if (!hasMeaningfulBody(body)) {
|
|
100
|
+
for (const heading of PROPOSAL_ERA_HEADINGS) {
|
|
101
|
+
if (headings.has(heading)) {
|
|
94
102
|
issues.push({
|
|
95
103
|
path,
|
|
96
|
-
message: `section "## ${heading}"
|
|
104
|
+
message: `accepted decision must not contain proposal-era section "## ${heading}"`,
|
|
97
105
|
});
|
|
98
106
|
}
|
|
99
107
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
issues.push(...alternativesIssue(path, record.sections));
|
|
109
|
+
return issues;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Validate a draft proposal in `adr/.drafts/` before `accept` promotes it.
|
|
113
|
+
* Drafts are ephemeral and deliberately outside the `adrkit validate` surface;
|
|
114
|
+
* this is the gate that keeps a half-written proposal from becoming a decision.
|
|
115
|
+
*/
|
|
116
|
+
export function validateDraft(root, draft) {
|
|
117
|
+
const issues = [];
|
|
118
|
+
const path = relative(root, draft.path);
|
|
119
|
+
for (const key of draft.frontMatterExtras ?? []) {
|
|
120
|
+
issues.push({ path, message: `unknown front matter field "${key}"` });
|
|
106
121
|
}
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
if (headings.has(heading)) {
|
|
110
|
-
issues.push({
|
|
111
|
-
path,
|
|
112
|
-
message: `accepted decision must not contain proposal-era section "## ${heading}"`,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
122
|
+
if (draft.status !== 'proposed') {
|
|
123
|
+
issues.push({ path, message: `draft status must be "proposed"` });
|
|
116
124
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
const dateError = dateIssue(draft);
|
|
126
|
+
if (dateError !== undefined)
|
|
127
|
+
issues.push({ path, message: dateError });
|
|
128
|
+
const match = draft.fileName.match(/^(\d{4})-(\d{2})-(\d{2})-[a-z0-9一-鿿-]+\.md$/);
|
|
129
|
+
if (match === null) {
|
|
130
|
+
issues.push({ path, message: 'draft file name must be "YYYY-MM-DD-slug.md"' });
|
|
131
|
+
}
|
|
132
|
+
else if (!calendarDateIsValid(Number(match[1]), Number(match[2]), Number(match[3]))) {
|
|
133
|
+
issues.push({ path, message: 'file name contains an invalid calendar date' });
|
|
122
134
|
}
|
|
135
|
+
issues.push(...sectionIssues(path, draft.sections, PROPOSED_REQUIRED, ['Problem', 'Proposal']));
|
|
136
|
+
issues.push(...alternativesIssue(path, draft.sections));
|
|
123
137
|
return issues;
|
|
124
138
|
}
|
|
125
139
|
export function validateRepository(root) {
|
|
@@ -139,11 +153,6 @@ export function validateRepository(root) {
|
|
|
139
153
|
});
|
|
140
154
|
}
|
|
141
155
|
}
|
|
142
|
-
for (const folder of FOLDERS) {
|
|
143
|
-
if (!existsSync(join(root, ADR_DIR, folder))) {
|
|
144
|
-
issues.push({ path: `${ADR_DIR}/${folder}`, message: 'missing folder' });
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
156
|
let records;
|
|
148
157
|
try {
|
|
149
158
|
records = listRecords(root);
|
|
@@ -158,7 +167,7 @@ export function validateRepository(root) {
|
|
|
158
167
|
const decisionRecords = new Map();
|
|
159
168
|
for (const record of records) {
|
|
160
169
|
issues.push(...validateRecord(root, record));
|
|
161
|
-
if (record.
|
|
170
|
+
if (record.number !== undefined) {
|
|
162
171
|
if (decisionRecords.has(record.number)) {
|
|
163
172
|
issues.push({
|
|
164
173
|
path: relative(root, record.path),
|
|
@@ -202,7 +211,7 @@ function supersedeReferenceIssues(root, record, decisions) {
|
|
|
202
211
|
export function validateRecordReferences(root, record, records) {
|
|
203
212
|
const decisions = new Map();
|
|
204
213
|
for (const candidate of records) {
|
|
205
|
-
if (candidate.
|
|
214
|
+
if (candidate.number !== undefined) {
|
|
206
215
|
decisions.set(candidate.number, candidate);
|
|
207
216
|
}
|
|
208
217
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"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"}
|