@meza/adr-tools 1.0.12 → 2.0.0
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 +11 -6
- 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
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import childProcess, { type SpawnSyncOptionsWithStringEncoding } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export interface AdrCli {
|
|
5
|
+
run(args: string[], options?: { cwd?: string; env?: Record<string, string | undefined>; timeoutMs?: number }): string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const createAdrCli = (entrypoint: string): AdrCli => {
|
|
9
|
+
const absoluteEntrypoint = path.resolve(entrypoint);
|
|
10
|
+
const tsxCli = path.resolve(process.cwd(), 'node_modules', 'tsx', 'dist', 'cli.mjs');
|
|
11
|
+
|
|
12
|
+
const run: AdrCli['run'] = (args, options) => {
|
|
13
|
+
const result = childProcess.execFileSync(process.execPath, [tsxCli, absoluteEntrypoint, ...args], {
|
|
14
|
+
cwd: options?.cwd,
|
|
15
|
+
env: { ...process.env, ...options?.env },
|
|
16
|
+
timeout: options?.timeoutMs ?? 20000,
|
|
17
|
+
encoding: 'utf8'
|
|
18
|
+
} satisfies SpawnSyncOptionsWithStringEncoding);
|
|
19
|
+
|
|
20
|
+
return result.trimEnd();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return { run };
|
|
24
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as fs from 'fs';
|
|
1
|
+
import * as fs from 'node:fs';
|
|
3
2
|
import * as os from 'os';
|
|
4
3
|
import * as path from 'path';
|
|
5
4
|
/* eslint-disable no-sync */
|
|
6
5
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
7
7
|
|
|
8
8
|
describe('Init an ADR Repository', () => {
|
|
9
9
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
10
|
-
const
|
|
10
|
+
const cli = createAdrCli(adr);
|
|
11
11
|
|
|
12
12
|
let adrDirectory: string;
|
|
13
13
|
let workDir: string;
|
|
@@ -20,15 +20,16 @@ describe('Init an ADR Repository', () => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
afterEach(() => {
|
|
23
|
-
fs.
|
|
23
|
+
fs.rmSync(workDir, {
|
|
24
24
|
recursive: true,
|
|
25
|
+
force: true,
|
|
25
26
|
maxRetries: 3,
|
|
26
27
|
retryDelay: 500
|
|
27
28
|
});
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
it('should use the default directory', () => {
|
|
31
|
-
|
|
32
|
+
cli.run(['init'], { cwd: workDir });
|
|
32
33
|
const expectedFile: string = path.join(adrDirectory, '0001-record-architecture-decisions.md');
|
|
33
34
|
const expectedLockFile: string = path.join(adrDirectory, '.adr-sequence.lock');
|
|
34
35
|
expect(fs.existsSync(expectedFile)).toBeTruthy();
|
|
@@ -42,7 +43,7 @@ describe('Init an ADR Repository', () => {
|
|
|
42
43
|
|
|
43
44
|
it('should use an alternate directory', () => {
|
|
44
45
|
const directory: string = path.resolve(path.join(workDir, 'tmp', 'alternative-dir'));
|
|
45
|
-
|
|
46
|
+
cli.run(['init', directory], { cwd: workDir });
|
|
46
47
|
|
|
47
48
|
const expectedInitFile: string = path.join(directory, '0001-record-architecture-decisions.md');
|
|
48
49
|
const expectedLockFile: string = path.join(directory, '.adr-sequence.lock');
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { realpathSync, rmSync } from 'node:fs';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as path from 'path';
|
|
5
|
-
import * as fs from 'fs/promises';
|
|
6
5
|
/* eslint-disable no-sync */
|
|
7
6
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
8
8
|
|
|
9
9
|
describe('Linking Adrs', () => {
|
|
10
10
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
11
|
-
const
|
|
11
|
+
const cli = createAdrCli(adr);
|
|
12
12
|
|
|
13
13
|
let adrDirectory: string;
|
|
14
14
|
let workDir: string;
|
|
@@ -22,17 +22,18 @@ describe('Linking Adrs', () => {
|
|
|
22
22
|
|
|
23
23
|
afterEach(() => {
|
|
24
24
|
vi.clearAllMocks();
|
|
25
|
-
|
|
25
|
+
rmSync(workDir, {
|
|
26
26
|
recursive: true,
|
|
27
|
+
force: true,
|
|
27
28
|
maxRetries: 3,
|
|
28
29
|
retryDelay: 500
|
|
29
30
|
});
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
it('should link adrs as expected with adr new', async () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
cli.run(['new', 'First', 'Record'], { cwd: workDir });
|
|
35
|
+
cli.run(['new', 'Second', 'Record'], { cwd: workDir });
|
|
36
|
+
cli.run(['new', '-q', '-l', '1:Amends:Amended by', '-l', '2:Clarifies:Clarified by', 'Third', 'Record'], {
|
|
36
37
|
cwd: workDir
|
|
37
38
|
});
|
|
38
39
|
|
|
@@ -50,11 +51,11 @@ describe('Linking Adrs', () => {
|
|
|
50
51
|
});
|
|
51
52
|
|
|
52
53
|
it('should link adrs as expected with adr link', async () => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
cli.run(['new', 'First', 'Record'], { cwd: workDir });
|
|
55
|
+
cli.run(['new', 'Second', 'Record'], { cwd: workDir });
|
|
56
|
+
cli.run(['new', 'Third', 'Record'], { cwd: workDir });
|
|
57
|
+
cli.run(['link', '3', 'Amends', '1', 'Amended by'], { cwd: workDir });
|
|
58
|
+
cli.run(['link', '3', 'Clarifies', '2', 'Clarified by'], { cwd: workDir });
|
|
58
59
|
|
|
59
60
|
const first: string = path.join(adrDirectory, '0001-first-record.md');
|
|
60
61
|
const second: string = path.join(adrDirectory, '0002-second-record.md');
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { realpathSync, rmSync } from 'node:fs';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as path from 'path';
|
|
5
|
-
import * as fs from 'fs/promises';
|
|
6
5
|
/* eslint-disable no-sync */
|
|
7
6
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
7
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
8
8
|
|
|
9
9
|
describe('Listing', () => {
|
|
10
10
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
11
|
-
const
|
|
11
|
+
const cli = createAdrCli(adr);
|
|
12
12
|
|
|
13
13
|
let adrDirectory: string;
|
|
14
14
|
let workDir: string;
|
|
@@ -16,38 +16,45 @@ describe('Listing', () => {
|
|
|
16
16
|
beforeEach(async () => {
|
|
17
17
|
workDir = path.resolve(realpathSync(await fs.mkdtemp(path.join(os.tmpdir(), 'adr-'))));
|
|
18
18
|
adrDirectory = 'doc/adr';
|
|
19
|
-
|
|
19
|
+
cli.run(['init', adrDirectory], { cwd: workDir });
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
afterEach(() => {
|
|
23
|
-
|
|
23
|
+
rmSync(workDir, {
|
|
24
24
|
recursive: true,
|
|
25
|
+
force: true,
|
|
25
26
|
maxRetries: 3,
|
|
26
27
|
retryDelay: 500
|
|
27
28
|
});
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
it('should list an empty directory', async () => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
expect(output).toEqual('doc/adr/0001-record-architecture-decisions.md');
|
|
32
|
+
const output = cli.run(['list'], { cwd: workDir }).replace(/\r\n/g, '\n');
|
|
33
|
+
expect(output).toEqual(path.join('doc', 'adr', '0001-record-architecture-decisions.md'));
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it('should list when there is an additional one', async () => {
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
cli.run(['new', 'first'], { cwd: workDir });
|
|
38
|
+
const output = cli.run(['list'], { cwd: workDir }).replace(/\r\n/g, '\n');
|
|
39
|
+
expect(output).toEqual(
|
|
40
|
+
[path.join('doc', 'adr', '0001-record-architecture-decisions.md'), path.join('doc', 'adr', '0002-first.md')].join(
|
|
41
|
+
'\n'
|
|
42
|
+
)
|
|
43
|
+
);
|
|
41
44
|
});
|
|
42
45
|
|
|
43
46
|
it('should list when there are more', async () => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const output = child.toString().trim();
|
|
47
|
+
cli.run(['new', 'first'], { cwd: workDir });
|
|
48
|
+
cli.run(['new', 'second'], { cwd: workDir });
|
|
49
|
+
cli.run(['new', 'third'], { cwd: workDir });
|
|
50
|
+
const output = cli.run(['list'], { cwd: workDir }).replace(/\r\n/g, '\n');
|
|
49
51
|
expect(output).toEqual(
|
|
50
|
-
|
|
52
|
+
[
|
|
53
|
+
path.join('doc', 'adr', '0001-record-architecture-decisions.md'),
|
|
54
|
+
path.join('doc', 'adr', '0002-first.md'),
|
|
55
|
+
path.join('doc', 'adr', '0003-second.md'),
|
|
56
|
+
path.join('doc', 'adr', '0004-third.md')
|
|
57
|
+
].join('\n')
|
|
51
58
|
);
|
|
52
59
|
});
|
|
53
60
|
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as fs from 'fs';
|
|
1
|
+
import * as fs from 'node:fs';
|
|
3
2
|
import * as os from 'os';
|
|
4
3
|
import * as path from 'path';
|
|
5
4
|
/* eslint-disable no-sync */
|
|
6
5
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
7
7
|
|
|
8
8
|
describe('New Adrs', () => {
|
|
9
9
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
10
|
-
const
|
|
10
|
+
const cli = createAdrCli(adr);
|
|
11
11
|
|
|
12
12
|
let adrDirectory: string;
|
|
13
13
|
let workDir: string;
|
|
@@ -20,16 +20,17 @@ describe('New Adrs', () => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
afterEach(() => {
|
|
23
|
-
fs.
|
|
23
|
+
fs.rmSync(workDir, {
|
|
24
24
|
recursive: true,
|
|
25
|
+
force: true,
|
|
25
26
|
maxRetries: 3,
|
|
26
27
|
retryDelay: 500
|
|
27
28
|
});
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
it('should create a new one normally', () => {
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
cli.run(['init', adrDirectory], { cwd: workDir });
|
|
33
|
+
cli.run(['new', 'Example', 'ADR'], { cwd: workDir });
|
|
33
34
|
|
|
34
35
|
const expectedNewFile: string = path.join(adrDirectory, '0002-example-adr.md');
|
|
35
36
|
expect(fs.existsSync(expectedNewFile)).toBeTruthy();
|
|
@@ -39,7 +40,7 @@ describe('New Adrs', () => {
|
|
|
39
40
|
});
|
|
40
41
|
|
|
41
42
|
it('should create a new one even if no config exists', () => {
|
|
42
|
-
|
|
43
|
+
cli.run(['new', 'Example', 'ADR'], { cwd: workDir });
|
|
43
44
|
|
|
44
45
|
const expectedNewFile: string = path.join(adrDirectory, '0001-example-adr.md');
|
|
45
46
|
expect(fs.existsSync(expectedNewFile)).toBeTruthy();
|
|
@@ -49,8 +50,8 @@ describe('New Adrs', () => {
|
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
it('should create a table of contents upon creation', () => {
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
cli.run(['init', adrDirectory], { cwd: workDir });
|
|
54
|
+
cli.run(['new', 'Example', 'ADR'], { cwd: workDir });
|
|
54
55
|
|
|
55
56
|
const expectedNewFile: string = path.join(adrDirectory, 'decisions.md');
|
|
56
57
|
expect(fs.existsSync(expectedNewFile)).toBeTruthy();
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
6
|
+
|
|
7
|
+
const waitForFile = async (filePath: string, timeoutMs: number) => {
|
|
8
|
+
const startedAt = Date.now();
|
|
9
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
10
|
+
if (fs.existsSync(filePath)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
await new Promise((r) => setTimeout(r, 25));
|
|
14
|
+
}
|
|
15
|
+
throw new Error(`Timed out waiting for file: ${filePath}`);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe('--open-with', () => {
|
|
19
|
+
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
20
|
+
const cli = createAdrCli(adr);
|
|
21
|
+
const visualHelper =
|
|
22
|
+
process.platform === 'win32'
|
|
23
|
+
? path.resolve(path.dirname(__filename), './fake-visual.cmd')
|
|
24
|
+
: path.resolve(path.dirname(__filename), './fake-visual');
|
|
25
|
+
|
|
26
|
+
let workDir: string;
|
|
27
|
+
let adrDirectory: string;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
// @ts-ignore
|
|
31
|
+
process.env.ADR_DATE = '1992-01-12';
|
|
32
|
+
workDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'adr-')));
|
|
33
|
+
adrDirectory = path.resolve(path.join(workDir, 'doc/adr'));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
afterEach(async () => {
|
|
37
|
+
if (process.platform === 'win32') {
|
|
38
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
39
|
+
}
|
|
40
|
+
fs.rmSync(workDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 250 });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('opens the created ADR with the provided command', async () => {
|
|
44
|
+
cli.run(['new', '--open-with', visualHelper, 'Example', 'ADR'], { cwd: workDir });
|
|
45
|
+
|
|
46
|
+
const expectedOpenMarker: string = path.join(workDir, 'visual.out');
|
|
47
|
+
await waitForFile(expectedOpenMarker, 2000);
|
|
48
|
+
|
|
49
|
+
const contents = fs.readFileSync(expectedOpenMarker, 'utf8').trim();
|
|
50
|
+
const openedPath = contents.replace(/^VISUAL\s+/, '');
|
|
51
|
+
expect(path.normalize(openedPath)).toEqual(path.normalize(`${adrDirectory}/0001-example-adr.md`));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { realpathSync, rmSync } from 'node:fs';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as path from 'path';
|
|
5
|
-
import * as fs from 'fs/promises';
|
|
6
5
|
/* eslint-disable no-sync */
|
|
7
6
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
8
8
|
|
|
9
9
|
describe('Superseding Adrs', () => {
|
|
10
10
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
11
|
-
const
|
|
11
|
+
const cli = createAdrCli(adr);
|
|
12
12
|
|
|
13
13
|
let adrDirectory: string;
|
|
14
14
|
let workDir: string;
|
|
@@ -22,16 +22,17 @@ describe('Superseding Adrs', () => {
|
|
|
22
22
|
|
|
23
23
|
afterEach(() => {
|
|
24
24
|
vi.clearAllMocks();
|
|
25
|
-
|
|
25
|
+
rmSync(workDir, {
|
|
26
26
|
recursive: true,
|
|
27
|
+
force: true,
|
|
27
28
|
maxRetries: 3,
|
|
28
29
|
retryDelay: 500
|
|
29
30
|
});
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
it('should be able to supersede previous adrs', async () => {
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
cli.run(['new', 'First', 'Record'], { cwd: workDir });
|
|
35
|
+
cli.run(['new', '-s', '1', 'Second', 'Record'], { cwd: workDir });
|
|
35
36
|
|
|
36
37
|
const first: string = path.join(adrDirectory, '0001-first-record.md');
|
|
37
38
|
const second: string = path.join(adrDirectory, '0002-second-record.md');
|
|
@@ -44,9 +45,9 @@ describe('Superseding Adrs', () => {
|
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
it('should be able to supersede multiple records', async () => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
cli.run(['new', 'First', 'Record'], { cwd: workDir });
|
|
49
|
+
cli.run(['new', 'Second', 'Record'], { cwd: workDir });
|
|
50
|
+
cli.run(['new', '-s', '1', '-s', '2', 'Third', 'Record'], { cwd: workDir });
|
|
50
51
|
|
|
51
52
|
const first: string = path.join(adrDirectory, '0001-first-record.md');
|
|
52
53
|
const second: string = path.join(adrDirectory, '0002-second-record.md');
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { realpathSync, rmSync } from 'node:fs';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as path from 'path';
|
|
5
|
-
import * as fs from 'fs/promises';
|
|
6
5
|
/* eslint-disable no-sync */
|
|
7
6
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
8
8
|
|
|
9
9
|
describe('Generating TOC', () => {
|
|
10
10
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
11
|
-
const
|
|
11
|
+
const cli = createAdrCli(adr);
|
|
12
12
|
|
|
13
13
|
let adrDirectory: string;
|
|
14
14
|
let workDir: string;
|
|
@@ -22,18 +22,19 @@ describe('Generating TOC', () => {
|
|
|
22
22
|
|
|
23
23
|
afterEach(() => {
|
|
24
24
|
vi.clearAllMocks();
|
|
25
|
-
|
|
25
|
+
rmSync(workDir, {
|
|
26
26
|
recursive: true,
|
|
27
|
+
force: true,
|
|
27
28
|
maxRetries: 3,
|
|
28
29
|
retryDelay: 500
|
|
29
30
|
});
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
it('should add a path prefix to the toc when there is one supplied', async () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
cli.run(['new', 'First', 'Record'], { cwd: workDir });
|
|
35
|
+
cli.run(['new', 'Second', 'Record'], { cwd: workDir });
|
|
36
|
+
cli.run(['new', 'Third', 'Record'], { cwd: workDir });
|
|
37
|
+
cli.run(['generate', 'toc', '-p', 'foo/doc/adr/'], { cwd: workDir });
|
|
37
38
|
|
|
38
39
|
const tocFilePath: string = path.join(adrDirectory, 'decisions.md');
|
|
39
40
|
const tocContent = await fs.readFile(tocFilePath, 'utf8');
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { realpathSync, rmSync } from 'node:fs';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as path from 'path';
|
|
5
|
-
import * as fs from 'fs/promises';
|
|
6
5
|
/* eslint-disable no-sync */
|
|
7
6
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
7
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
8
8
|
|
|
9
9
|
describe('Overriding templates', () => {
|
|
10
10
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
11
|
-
const
|
|
11
|
+
const cli = createAdrCli(adr);
|
|
12
12
|
|
|
13
13
|
let adrDirectory: string;
|
|
14
14
|
let workDir: string;
|
|
@@ -18,12 +18,13 @@ describe('Overriding templates', () => {
|
|
|
18
18
|
process.env.ADR_DATE = '1992-01-12';
|
|
19
19
|
workDir = path.resolve(realpathSync(await fs.mkdtemp(path.join(os.tmpdir(), 'adr-'))));
|
|
20
20
|
adrDirectory = path.join(workDir, 'doc/adr');
|
|
21
|
-
|
|
21
|
+
cli.run(['init', adrDirectory], { cwd: workDir });
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
afterEach(() => {
|
|
25
|
-
|
|
25
|
+
rmSync(workDir, {
|
|
26
26
|
recursive: true,
|
|
27
|
+
force: true,
|
|
27
28
|
maxRetries: 3,
|
|
28
29
|
retryDelay: 500
|
|
29
30
|
});
|
|
@@ -36,8 +37,8 @@ describe('Overriding templates', () => {
|
|
|
36
37
|
'# This is an override template\nTITLE\nDATE\nNUMBER\nSTATUS'
|
|
37
38
|
);
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
cli.run(['new', 'Example', 'ADR'], { cwd: workDir });
|
|
41
|
+
cli.run(['new', 'Another', 'Example', 'ADR'], { cwd: workDir });
|
|
41
42
|
|
|
42
43
|
const expectedFile: string = path.join(adrDirectory, '0002-example-adr.md');
|
|
43
44
|
const expectedFile2: string = path.join(adrDirectory, '0003-another-example-adr.md');
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as fs from 'fs';
|
|
1
|
+
import * as fs from 'node:fs';
|
|
3
2
|
import * as os from 'os';
|
|
4
3
|
import * as path from 'path';
|
|
5
4
|
/* eslint-disable no-sync */
|
|
6
5
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
+
import { createAdrCli } from './helpers/adr-cli';
|
|
7
7
|
|
|
8
8
|
describe('deep directories', () => {
|
|
9
9
|
const adr = path.resolve(path.dirname(__filename), '../src/index.ts');
|
|
10
|
-
const
|
|
10
|
+
const cli = createAdrCli(adr);
|
|
11
11
|
|
|
12
12
|
let adrDirectory: string;
|
|
13
13
|
let workDir: string;
|
|
@@ -15,12 +15,13 @@ describe('deep directories', () => {
|
|
|
15
15
|
beforeEach(() => {
|
|
16
16
|
workDir = path.resolve(fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'adr-'))));
|
|
17
17
|
adrDirectory = path.join(workDir, 'doc/adr');
|
|
18
|
-
|
|
18
|
+
cli.run(['init', adrDirectory], { cwd: workDir });
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
afterEach(() => {
|
|
22
|
-
fs.
|
|
22
|
+
fs.rmSync(workDir, {
|
|
23
23
|
recursive: true,
|
|
24
|
+
force: true,
|
|
24
25
|
maxRetries: 3,
|
|
25
26
|
retryDelay: 500
|
|
26
27
|
});
|
|
@@ -29,17 +30,18 @@ describe('deep directories', () => {
|
|
|
29
30
|
it('can work', () => {
|
|
30
31
|
const innerPath = path.join(fs.mkdtempSync(path.resolve(workDir) + '/'), 'inner');
|
|
31
32
|
fs.mkdirSync(innerPath, { recursive: true });
|
|
32
|
-
|
|
33
|
+
cli.run(['new', 'this', 'should', 'exist'], { cwd: innerPath });
|
|
33
34
|
const expectedFile: string = path.join(adrDirectory, '0002-this-should-exist.md');
|
|
34
35
|
expect(fs.existsSync(expectedFile)).toBeTruthy();
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
it('can work when there has been no config initiated', () => {
|
|
38
|
-
|
|
39
|
+
fs.rmSync(adrDirectory, { recursive: true, force: true });
|
|
40
|
+
fs.rmSync(path.join(workDir, '.adr-dir'), { force: true });
|
|
39
41
|
|
|
40
42
|
const innerPath = path.join(fs.mkdtempSync(path.resolve(workDir) + '/'), 'inner');
|
|
41
43
|
fs.mkdirSync(innerPath, { recursive: true });
|
|
42
|
-
|
|
44
|
+
cli.run(['new', 'this', 'should', 'exist'], { cwd: innerPath });
|
|
43
45
|
const expectedFile: string = path.join(innerPath, 'doc', 'adr', '0001-this-should-exist.md');
|
|
44
46
|
expect(fs.existsSync(expectedFile)).toBeTruthy();
|
|
45
47
|
});
|
package/vitest.config.e2e.ts
CHANGED
|
@@ -3,7 +3,14 @@ import { defineConfig } from 'vitest/config';
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
test: {
|
|
5
5
|
dir: 'tests',
|
|
6
|
-
testTimeout:
|
|
6
|
+
testTimeout: 30000,
|
|
7
|
+
hookTimeout: 30000,
|
|
8
|
+
pool: 'threads',
|
|
9
|
+
poolOptions: {
|
|
10
|
+
threads: {
|
|
11
|
+
singleThread: true
|
|
12
|
+
}
|
|
13
|
+
},
|
|
7
14
|
watch: false,
|
|
8
15
|
coverage: {
|
|
9
16
|
reportsDirectory: './reports/coverage/e2e',
|
package/vitest.config.ts
CHANGED
|
@@ -3,15 +3,31 @@ import { defineConfig } from 'vitest/config';
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
test: {
|
|
5
5
|
dir: 'src',
|
|
6
|
-
testTimeout:
|
|
6
|
+
testTimeout: 30000,
|
|
7
|
+
hookTimeout: 30000,
|
|
8
|
+
pool: 'threads',
|
|
7
9
|
watch: false,
|
|
10
|
+
fileParallelism: false,
|
|
11
|
+
maxWorkers: 1,
|
|
12
|
+
minWorkers: 1,
|
|
8
13
|
poolOptions: {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
threads: {
|
|
15
|
+
isolate: false,
|
|
16
|
+
singleThread: true
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
coverage: {
|
|
20
|
+
include: ['src/**/*.ts'],
|
|
21
|
+
exclude: ['**/node_modules/**', '**/*.d.ts'],
|
|
22
|
+
all: false,
|
|
23
|
+
processingConcurrency: 1,
|
|
24
|
+
thresholds: {
|
|
25
|
+
branches: 100,
|
|
26
|
+
functions: 100,
|
|
27
|
+
lines: 100,
|
|
28
|
+
statements: 100,
|
|
29
|
+
perFile: true
|
|
30
|
+
},
|
|
15
31
|
reportsDirectory: './reports/coverage/unit',
|
|
16
32
|
reporter: ['text', 'json', 'html']
|
|
17
33
|
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
name: Sync Deps to Main
|
|
2
|
-
on:
|
|
3
|
-
schedule:
|
|
4
|
-
- cron: '9 0 * * 4'
|
|
5
|
-
|
|
6
|
-
jobs:
|
|
7
|
-
sync-branches:
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
name: Syncing dependencies
|
|
10
|
-
steps:
|
|
11
|
-
- name: Checkout
|
|
12
|
-
uses: actions/checkout@v4
|
|
13
|
-
- name: Set up Node
|
|
14
|
-
uses: actions/setup-node@v4
|
|
15
|
-
with:
|
|
16
|
-
node-version: 12
|
|
17
|
-
- name: Opening pull request
|
|
18
|
-
id: pull
|
|
19
|
-
uses: tretuna/sync-branches@1.4.0
|
|
20
|
-
with:
|
|
21
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
-
FROM_BRANCH: "dependency-update"
|
|
23
|
-
TO_BRANCH: "main"
|
|
24
|
-
PULL_REQUEST_TITLE: "chore: sync deps to main"
|
|
25
|
-
PULL_REQUEST_AUTO_MERGE_METHOD: "merge"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
name: Sync Main to Deps
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- main
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
sync-branches:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
name: Syncing branches
|
|
11
|
-
steps:
|
|
12
|
-
- name: Checkout
|
|
13
|
-
uses: actions/checkout@v4
|
|
14
|
-
- name: Set up Node
|
|
15
|
-
uses: actions/setup-node@v4
|
|
16
|
-
with:
|
|
17
|
-
node-version: 12
|
|
18
|
-
- name: Opening pull request
|
|
19
|
-
id: pull
|
|
20
|
-
uses: tretuna/sync-branches@1.4.0
|
|
21
|
-
with:
|
|
22
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
23
|
-
FROM_BRANCH: "main"
|
|
24
|
-
TO_BRANCH: "dependency-update"
|
|
25
|
-
PULL_REQUEST_TITLE: "chore: sync main to deps"
|
|
26
|
-
PULL_REQUEST_AUTO_MERGE_METHOD: "merge"
|
package/.husky/commit-msg
DELETED