ts-repo-utils 7.8.0 → 7.8.2
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/dist/cmd/assert-repo-is-clean.mjs +2 -1
- package/dist/cmd/assert-repo-is-clean.mjs.map +1 -1
- package/dist/cmd/check-should-run-type-checks.mjs +2 -1
- package/dist/cmd/check-should-run-type-checks.mjs.map +1 -1
- package/dist/cmd/format-diff-from.mjs +2 -1
- package/dist/cmd/format-diff-from.mjs.map +1 -1
- package/dist/cmd/format-uncommitted.mjs +2 -1
- package/dist/cmd/format-uncommitted.mjs.map +1 -1
- package/dist/cmd/gen-index-ts.mjs +2 -1
- package/dist/cmd/gen-index-ts.mjs.map +1 -1
- package/dist/functions/assert-ext.d.mts +0 -1
- package/dist/functions/assert-ext.d.mts.map +1 -1
- package/dist/functions/create-result-assert.d.mts +0 -1
- package/dist/functions/create-result-assert.d.mts.map +1 -1
- package/dist/functions/diff.d.mts +0 -1
- package/dist/functions/diff.d.mts.map +1 -1
- package/dist/functions/exec-async.d.mts +0 -1
- package/dist/functions/exec-async.d.mts.map +1 -1
- package/dist/functions/format.d.mts +0 -1
- package/dist/functions/format.d.mts.map +1 -1
- package/dist/functions/format.mjs +8 -2
- package/dist/functions/format.mjs.map +1 -1
- package/dist/functions/gen-index.d.mts +0 -1
- package/dist/functions/gen-index.d.mts.map +1 -1
- package/dist/functions/workspace-utils/execute-parallel.d.mts.map +1 -1
- package/dist/functions/workspace-utils/execute-parallel.mjs +4 -5
- package/dist/functions/workspace-utils/execute-parallel.mjs.map +1 -1
- package/dist/functions/workspace-utils/run-cmd-in-parallel.d.mts.map +1 -1
- package/dist/functions/workspace-utils/run-cmd-in-parallel.mjs +2 -1
- package/dist/functions/workspace-utils/run-cmd-in-parallel.mjs.map +1 -1
- package/dist/functions/workspace-utils/run-cmd-in-stages.d.mts.map +1 -1
- package/dist/functions/workspace-utils/run-cmd-in-stages.mjs +2 -1
- package/dist/functions/workspace-utils/run-cmd-in-stages.mjs.map +1 -1
- package/dist/node-global.d.mts +0 -1
- package/dist/node-global.d.mts.map +1 -1
- package/package.json +16 -15
- package/src/cmd/assert-repo-is-clean.mts +1 -1
- package/src/cmd/check-should-run-type-checks.mts +1 -1
- package/src/cmd/format-diff-from.mts +1 -1
- package/src/cmd/format-uncommitted.mts +1 -1
- package/src/cmd/gen-index-ts.mts +1 -1
- package/src/functions/diff.test.mts +60 -8
- package/src/functions/exec-async.test.mts +17 -2
- package/src/functions/format.mts +11 -3
- package/src/functions/format.test.mts +57 -9
- package/src/functions/workspace-utils/execute-parallel.mts +4 -5
- package/src/functions/workspace-utils/run-cmd-in-parallel.mts +2 -1
- package/src/functions/workspace-utils/run-cmd-in-stages.mts +2 -1
- package/src/functions/workspace-utils/run-cmd-in-stages.test.mts +4 -3
- package/src/node-global.mts +0 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable vitest/no-conditional-expect */
|
|
2
1
|
import dedent from 'dedent';
|
|
3
2
|
import { Result } from 'ts-data-forge';
|
|
4
3
|
import '../node-global.mjs';
|
|
@@ -15,14 +14,14 @@ import {
|
|
|
15
14
|
formatUncommittedFiles,
|
|
16
15
|
} from './format.mjs';
|
|
17
16
|
|
|
18
|
-
vi.mock('./diff.mjs', () => ({
|
|
17
|
+
vi.mock(import('./diff.mjs'), () => ({
|
|
19
18
|
getDiffFrom: vi.fn(),
|
|
20
19
|
getModifiedFiles: vi.fn(),
|
|
21
20
|
getStagedFiles: vi.fn(),
|
|
22
21
|
getUntrackedFiles: vi.fn(),
|
|
23
22
|
}));
|
|
24
23
|
|
|
25
|
-
describe(
|
|
24
|
+
describe(formatFilesGlob, () => {
|
|
26
25
|
const testDir = path.join(
|
|
27
26
|
process.cwd(),
|
|
28
27
|
`test-format-files-${crypto.randomUUID()}`,
|
|
@@ -71,10 +70,12 @@ describe('formatFilesGlob', () => {
|
|
|
71
70
|
|
|
72
71
|
// Format TypeScript files
|
|
73
72
|
const result = await formatFilesGlob(`${testDir}/*.ts`, { silent: true });
|
|
73
|
+
|
|
74
74
|
expect(Result.isOk(result)).toBe(true);
|
|
75
75
|
|
|
76
76
|
// Check that files were formatted
|
|
77
77
|
const content1 = await readTestFile(file1);
|
|
78
|
+
|
|
78
79
|
expect(content1).toBe(
|
|
79
80
|
`${dedent`
|
|
80
81
|
const foo = 'bar';
|
|
@@ -83,6 +84,7 @@ describe('formatFilesGlob', () => {
|
|
|
83
84
|
);
|
|
84
85
|
|
|
85
86
|
const content2 = await readTestFile(file2);
|
|
87
|
+
|
|
86
88
|
expect(content2).toBe(
|
|
87
89
|
`${dedent`
|
|
88
90
|
function test(x: number, y: string) {
|
|
@@ -93,6 +95,7 @@ describe('formatFilesGlob', () => {
|
|
|
93
95
|
|
|
94
96
|
// Check that non-matching file was not touched
|
|
95
97
|
const mdContent = await readTestFile(path.join(testDir, 'test.md'));
|
|
98
|
+
|
|
96
99
|
expect(mdContent).toBe('# Test\n\nSome spaces');
|
|
97
100
|
} finally {
|
|
98
101
|
// Cleanup
|
|
@@ -105,6 +108,7 @@ describe('formatFilesGlob', () => {
|
|
|
105
108
|
const result = await formatFilesGlob('/non-existent-path/*.ts', {
|
|
106
109
|
silent: true,
|
|
107
110
|
});
|
|
111
|
+
|
|
108
112
|
expect(Result.isOk(result)).toBe(true);
|
|
109
113
|
});
|
|
110
114
|
|
|
@@ -126,10 +130,12 @@ describe('formatFilesGlob', () => {
|
|
|
126
130
|
const result = await formatFilesGlob(`${testDir}/**/*.ts`, {
|
|
127
131
|
silent: true,
|
|
128
132
|
});
|
|
133
|
+
|
|
129
134
|
expect(Result.isOk(result)).toBe(true);
|
|
130
135
|
|
|
131
136
|
// Check that nested file was formatted
|
|
132
137
|
const content = await readTestFile(nestedFile);
|
|
138
|
+
|
|
133
139
|
expect(content).toBe(
|
|
134
140
|
`${dedent`
|
|
135
141
|
export const helper = (x: number) => {
|
|
@@ -144,7 +150,7 @@ describe('formatFilesGlob', () => {
|
|
|
144
150
|
});
|
|
145
151
|
});
|
|
146
152
|
|
|
147
|
-
describe(
|
|
153
|
+
describe(formatFiles, () => {
|
|
148
154
|
const testDir = path.join(
|
|
149
155
|
process.cwd(),
|
|
150
156
|
`test-format-files-list-${crypto.randomUUID()}`,
|
|
@@ -188,10 +194,12 @@ describe('formatFiles', () => {
|
|
|
188
194
|
const result = await formatFiles([file1, file2], {
|
|
189
195
|
silent: true,
|
|
190
196
|
});
|
|
197
|
+
|
|
191
198
|
expect(Result.isOk(result)).toBe(true);
|
|
192
199
|
|
|
193
200
|
// Check formatted content
|
|
194
201
|
const content1 = await readTestFile(file1);
|
|
202
|
+
|
|
195
203
|
expect(content1).toBe(
|
|
196
204
|
`${dedent`
|
|
197
205
|
const x = { a: 1, b: 2 };
|
|
@@ -199,6 +207,7 @@ describe('formatFiles', () => {
|
|
|
199
207
|
);
|
|
200
208
|
|
|
201
209
|
const content2 = await readTestFile(file2);
|
|
210
|
+
|
|
202
211
|
expect(content2).toBe(
|
|
203
212
|
`${dedent`
|
|
204
213
|
function test() {
|
|
@@ -216,11 +225,12 @@ describe('formatFiles', () => {
|
|
|
216
225
|
const result = await formatFiles([], {
|
|
217
226
|
silent: true,
|
|
218
227
|
});
|
|
228
|
+
|
|
219
229
|
expect(Result.isOk(result)).toBe(true);
|
|
220
230
|
});
|
|
221
231
|
});
|
|
222
232
|
|
|
223
|
-
describe(
|
|
233
|
+
describe(formatUncommittedFiles, () => {
|
|
224
234
|
const testDir = path.join(
|
|
225
235
|
process.cwd(),
|
|
226
236
|
`test-format-uncommitted-${crypto.randomUUID()}`,
|
|
@@ -272,6 +282,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
272
282
|
);
|
|
273
283
|
|
|
274
284
|
const result = await formatUncommittedFiles({ silent: true });
|
|
285
|
+
|
|
275
286
|
expect(Result.isOk(result)).toBe(true);
|
|
276
287
|
|
|
277
288
|
// Verify all git functions were called
|
|
@@ -282,6 +293,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
282
293
|
// Verify files were formatted
|
|
283
294
|
const verifyPromises = allFiles.map(async (file) => {
|
|
284
295
|
const content = await fs.readFile(path.join(testDir, file), 'utf8');
|
|
296
|
+
|
|
285
297
|
expect(content).toBe('const x = 1;\n');
|
|
286
298
|
});
|
|
287
299
|
await Promise.all(verifyPromises);
|
|
@@ -306,6 +318,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
306
318
|
staged: false,
|
|
307
319
|
silent: true,
|
|
308
320
|
});
|
|
321
|
+
|
|
309
322
|
expect(Result.isOk(result)).toBe(true);
|
|
310
323
|
|
|
311
324
|
expect(getUntrackedFiles).toHaveBeenCalledWith({ silent: true });
|
|
@@ -332,6 +345,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
332
345
|
staged: false,
|
|
333
346
|
silent: true,
|
|
334
347
|
});
|
|
348
|
+
|
|
335
349
|
expect(Result.isOk(result)).toBe(true);
|
|
336
350
|
|
|
337
351
|
expect(getUntrackedFiles).not.toHaveBeenCalled();
|
|
@@ -358,6 +372,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
358
372
|
staged: true,
|
|
359
373
|
silent: true,
|
|
360
374
|
});
|
|
375
|
+
|
|
361
376
|
expect(Result.isOk(result)).toBe(true);
|
|
362
377
|
|
|
363
378
|
expect(getUntrackedFiles).not.toHaveBeenCalled();
|
|
@@ -393,6 +408,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
393
408
|
staged: true,
|
|
394
409
|
silent: true,
|
|
395
410
|
});
|
|
411
|
+
|
|
396
412
|
expect(Result.isOk(result)).toBe(true);
|
|
397
413
|
|
|
398
414
|
expect(getUntrackedFiles).toHaveBeenCalledWith({ silent: true });
|
|
@@ -417,10 +433,12 @@ describe('formatUncommittedFiles', () => {
|
|
|
417
433
|
vi.mocked(getStagedFiles).mockResolvedValue(Result.ok([duplicateFile]));
|
|
418
434
|
|
|
419
435
|
const result = await formatUncommittedFiles({ silent: true });
|
|
436
|
+
|
|
420
437
|
expect(Result.isOk(result)).toBe(true);
|
|
421
438
|
|
|
422
439
|
// Verify file was formatted (only once despite appearing in all categories)
|
|
423
440
|
const content = await fs.readFile(duplicateFile, 'utf8');
|
|
441
|
+
|
|
424
442
|
expect(content).toBe('const x = 1;\n');
|
|
425
443
|
} finally {
|
|
426
444
|
await cleanupTest();
|
|
@@ -435,6 +453,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
435
453
|
vi.mocked(getStagedFiles).mockResolvedValue(Result.ok([]));
|
|
436
454
|
|
|
437
455
|
const result = await formatUncommittedFiles({ silent: true });
|
|
456
|
+
|
|
438
457
|
expect(Result.isOk(result)).toBe(true);
|
|
439
458
|
} finally {
|
|
440
459
|
await cleanupTest();
|
|
@@ -453,9 +472,11 @@ describe('formatUncommittedFiles', () => {
|
|
|
453
472
|
staged: false,
|
|
454
473
|
silent: true,
|
|
455
474
|
});
|
|
475
|
+
|
|
456
476
|
expect(Result.isErr(result)).toBe(true);
|
|
477
|
+
|
|
457
478
|
if (Result.isErr(result)) {
|
|
458
|
-
|
|
479
|
+
assert.deepStrictEqual(result.value, error);
|
|
459
480
|
}
|
|
460
481
|
} finally {
|
|
461
482
|
await cleanupTest();
|
|
@@ -474,9 +495,11 @@ describe('formatUncommittedFiles', () => {
|
|
|
474
495
|
staged: false,
|
|
475
496
|
silent: true,
|
|
476
497
|
});
|
|
498
|
+
|
|
477
499
|
expect(Result.isErr(result)).toBe(true);
|
|
500
|
+
|
|
478
501
|
if (Result.isErr(result)) {
|
|
479
|
-
|
|
502
|
+
assert.deepStrictEqual(result.value, error);
|
|
480
503
|
}
|
|
481
504
|
} finally {
|
|
482
505
|
await cleanupTest();
|
|
@@ -495,9 +518,11 @@ describe('formatUncommittedFiles', () => {
|
|
|
495
518
|
staged: true,
|
|
496
519
|
silent: true,
|
|
497
520
|
});
|
|
521
|
+
|
|
498
522
|
expect(Result.isErr(result)).toBe(true);
|
|
523
|
+
|
|
499
524
|
if (Result.isErr(result)) {
|
|
500
|
-
|
|
525
|
+
assert.deepStrictEqual(result.value, error);
|
|
501
526
|
}
|
|
502
527
|
} finally {
|
|
503
528
|
await cleanupTest();
|
|
@@ -519,10 +544,12 @@ describe('formatUncommittedFiles', () => {
|
|
|
519
544
|
vi.mocked(getStagedFiles).mockResolvedValue(Result.ok([]));
|
|
520
545
|
|
|
521
546
|
const result1 = await formatUncommittedFiles({ silent: false });
|
|
547
|
+
|
|
522
548
|
expect(Result.isOk(result1)).toBe(true);
|
|
523
549
|
// With silent: false, console output may occur
|
|
524
550
|
|
|
525
551
|
const result2 = await formatUncommittedFiles({ silent: true });
|
|
552
|
+
|
|
526
553
|
expect(Result.isOk(result2)).toBe(true);
|
|
527
554
|
// With silent: true, console output should be suppressed
|
|
528
555
|
|
|
@@ -551,9 +578,11 @@ describe('formatUncommittedFiles', () => {
|
|
|
551
578
|
vi.mocked(getStagedFiles).mockResolvedValue(Result.ok([]));
|
|
552
579
|
|
|
553
580
|
const result = await formatUncommittedFiles({ silent: true });
|
|
581
|
+
|
|
554
582
|
expect(Result.isOk(result)).toBe(true);
|
|
555
583
|
|
|
556
584
|
const content = await fs.readFile(path.join(testDir, testFile), 'utf8');
|
|
585
|
+
|
|
557
586
|
expect(content).toBe(
|
|
558
587
|
`${dedent`
|
|
559
588
|
function test() {
|
|
@@ -582,6 +611,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
582
611
|
vi.mocked(getStagedFiles).mockResolvedValue(Result.ok([]));
|
|
583
612
|
|
|
584
613
|
const result = await formatUncommittedFiles({ silent: true });
|
|
614
|
+
|
|
585
615
|
// Should handle error gracefully
|
|
586
616
|
expect(Result.isOk(result) || Result.isErr(result)).toBe(true);
|
|
587
617
|
} finally {
|
|
@@ -590,7 +620,7 @@ describe('formatUncommittedFiles', () => {
|
|
|
590
620
|
});
|
|
591
621
|
});
|
|
592
622
|
|
|
593
|
-
describe(
|
|
623
|
+
describe(formatDiffFrom, () => {
|
|
594
624
|
const testDir = path.join(
|
|
595
625
|
process.cwd(),
|
|
596
626
|
`test-format-diff-${crypto.randomUUID()}`,
|
|
@@ -628,10 +658,12 @@ describe('formatDiffFrom', () => {
|
|
|
628
658
|
vi.mocked(getStagedFiles).mockResolvedValue(Result.ok([]));
|
|
629
659
|
|
|
630
660
|
const result = await formatDiffFrom('main', { silent: true });
|
|
661
|
+
|
|
631
662
|
expect(Result.isOk(result)).toBe(true);
|
|
632
663
|
|
|
633
664
|
// Check file was formatted
|
|
634
665
|
const content = await readTestFile(file1);
|
|
666
|
+
|
|
635
667
|
expect(content).toBe(
|
|
636
668
|
`${dedent`
|
|
637
669
|
const a = 1;
|
|
@@ -676,10 +708,12 @@ describe('formatDiffFrom', () => {
|
|
|
676
708
|
includeUntracked: true,
|
|
677
709
|
silent: true,
|
|
678
710
|
});
|
|
711
|
+
|
|
679
712
|
expect(Result.isOk(result)).toBe(true);
|
|
680
713
|
|
|
681
714
|
// Check both files were formatted
|
|
682
715
|
const diffContent = await readTestFile(diffFile);
|
|
716
|
+
|
|
683
717
|
expect(diffContent).toBe(
|
|
684
718
|
`${dedent`
|
|
685
719
|
const diff = true;
|
|
@@ -687,6 +721,7 @@ describe('formatDiffFrom', () => {
|
|
|
687
721
|
);
|
|
688
722
|
|
|
689
723
|
const untrackedContent = await readTestFile(untrackedFile);
|
|
724
|
+
|
|
690
725
|
expect(untrackedContent).toBe(
|
|
691
726
|
`${dedent`
|
|
692
727
|
const untracked = true;
|
|
@@ -722,6 +757,7 @@ describe('formatDiffFrom', () => {
|
|
|
722
757
|
includeUntracked: true,
|
|
723
758
|
silent: true,
|
|
724
759
|
});
|
|
760
|
+
|
|
725
761
|
expect(Result.isOk(result)).toBe(true);
|
|
726
762
|
|
|
727
763
|
// Verify both functions were called
|
|
@@ -730,6 +766,7 @@ describe('formatDiffFrom', () => {
|
|
|
730
766
|
|
|
731
767
|
// Check that the file was formatted (content should change)
|
|
732
768
|
const finalContent = await readTestFile(sharedFile);
|
|
769
|
+
|
|
733
770
|
expect(finalContent).toBe(
|
|
734
771
|
`${dedent`
|
|
735
772
|
const shared = { value: 1 };
|
|
@@ -776,10 +813,12 @@ describe('formatDiffFrom', () => {
|
|
|
776
813
|
|
|
777
814
|
// Test default behavior (no options provided)
|
|
778
815
|
const result = await formatDiffFrom('main', { silent: true });
|
|
816
|
+
|
|
779
817
|
expect(Result.isOk(result)).toBe(true);
|
|
780
818
|
|
|
781
819
|
// Check all files were formatted
|
|
782
820
|
const diffContent = await readTestFile(diffFile);
|
|
821
|
+
|
|
783
822
|
expect(diffContent).toBe(
|
|
784
823
|
`${dedent`
|
|
785
824
|
const diff = true;
|
|
@@ -787,6 +826,7 @@ describe('formatDiffFrom', () => {
|
|
|
787
826
|
);
|
|
788
827
|
|
|
789
828
|
const stagedContent = await readTestFile(stagedFile);
|
|
829
|
+
|
|
790
830
|
expect(stagedContent).toBe(
|
|
791
831
|
`${dedent`
|
|
792
832
|
const staged = true;
|
|
@@ -794,6 +834,7 @@ describe('formatDiffFrom', () => {
|
|
|
794
834
|
);
|
|
795
835
|
|
|
796
836
|
const untrackedContent = await readTestFile(untrackedFile);
|
|
837
|
+
|
|
797
838
|
expect(untrackedContent).toBe(
|
|
798
839
|
`${dedent`
|
|
799
840
|
const untracked = true;
|
|
@@ -840,10 +881,12 @@ describe('formatDiffFrom', () => {
|
|
|
840
881
|
includeModified: false,
|
|
841
882
|
silent: true,
|
|
842
883
|
});
|
|
884
|
+
|
|
843
885
|
expect(Result.isOk(result)).toBe(true);
|
|
844
886
|
|
|
845
887
|
// Check both files were formatted
|
|
846
888
|
const diffContent = await readTestFile(diffFile);
|
|
889
|
+
|
|
847
890
|
expect(diffContent).toBe(
|
|
848
891
|
`${dedent`
|
|
849
892
|
const diff = true;
|
|
@@ -851,6 +894,7 @@ describe('formatDiffFrom', () => {
|
|
|
851
894
|
);
|
|
852
895
|
|
|
853
896
|
const stagedContent = await readTestFile(stagedFile);
|
|
897
|
+
|
|
854
898
|
expect(stagedContent).toBe(
|
|
855
899
|
`${dedent`
|
|
856
900
|
const staged = true;
|
|
@@ -888,6 +932,7 @@ describe('formatDiffFrom', () => {
|
|
|
888
932
|
includeStaged: true,
|
|
889
933
|
silent: true,
|
|
890
934
|
});
|
|
935
|
+
|
|
891
936
|
expect(Result.isOk(result)).toBe(true);
|
|
892
937
|
|
|
893
938
|
// Verify all functions were called
|
|
@@ -897,6 +942,7 @@ describe('formatDiffFrom', () => {
|
|
|
897
942
|
|
|
898
943
|
// Check that the file was formatted (content should change)
|
|
899
944
|
const finalContent = await readTestFile(sharedFile);
|
|
945
|
+
|
|
900
946
|
expect(finalContent).toBe(
|
|
901
947
|
`${dedent`
|
|
902
948
|
const shared = { value: 1 };
|
|
@@ -931,10 +977,12 @@ describe('formatDiffFrom', () => {
|
|
|
931
977
|
includeModified: false,
|
|
932
978
|
silent: true,
|
|
933
979
|
});
|
|
980
|
+
|
|
934
981
|
expect(Result.isOk(result)).toBe(true);
|
|
935
982
|
|
|
936
983
|
// Check only diff file was formatted
|
|
937
984
|
const diffContent = await readTestFile(diffFile);
|
|
985
|
+
|
|
938
986
|
expect(diffContent).toBe(
|
|
939
987
|
`${dedent`
|
|
940
988
|
const diff = true;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable require-atomic-updates */
|
|
2
|
+
import { isError } from '@sindresorhus/is';
|
|
2
3
|
import { spawn } from 'node:child_process';
|
|
3
4
|
import {
|
|
4
5
|
createPromise,
|
|
@@ -160,9 +161,7 @@ export const executeStages = async (
|
|
|
160
161
|
);
|
|
161
162
|
} catch (error) {
|
|
162
163
|
// executeParallel will throw immediately on any failure (fail-fast)
|
|
163
|
-
const errorMessage =
|
|
164
|
-
? error.message
|
|
165
|
-
: String(error);
|
|
164
|
+
const errorMessage = isError(error) ? error.message : String(error);
|
|
166
165
|
console.error(`\n❌ Stage ${i + 1} failed (fail-fast):`);
|
|
167
166
|
console.error(errorMessage);
|
|
168
167
|
throw new Error(`Stage ${i + 1} failed: ${errorMessage}`, {
|
|
@@ -240,14 +239,14 @@ const executeScript = (
|
|
|
240
239
|
).map((result) =>
|
|
241
240
|
result.then(
|
|
242
241
|
Result.mapErr((err) => {
|
|
243
|
-
const errorMessage: string =
|
|
242
|
+
const errorMessage: string = isError(err)
|
|
244
243
|
? err.message
|
|
245
244
|
: isRecord(err) && hasKey(err, 'message')
|
|
246
245
|
? (err.message?.toString() ?? 'Unknown error message')
|
|
247
246
|
: 'Unknown error';
|
|
248
247
|
|
|
249
248
|
console.error(`\nError in ${pkg.name}:`, errorMessage);
|
|
250
|
-
return
|
|
249
|
+
return isError(err) ? err : new Error(errorMessage);
|
|
251
250
|
}),
|
|
252
251
|
),
|
|
253
252
|
).value;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
|
|
3
|
+
import { isError } from '@sindresorhus/is';
|
|
3
4
|
import { executeParallel } from './execute-parallel.mjs';
|
|
4
5
|
import { getWorkspacePackages } from './get-workspace-packages.mjs';
|
|
5
6
|
|
|
@@ -43,7 +44,7 @@ export const runCmdInParallelAcrossWorkspaces = async ({
|
|
|
43
44
|
await executeParallel(filteredPackages, cmd, concurrency);
|
|
44
45
|
console.log(`\n✅ ${cmd} completed successfully (all packages)`);
|
|
45
46
|
} catch (error) {
|
|
46
|
-
const errorMessage =
|
|
47
|
+
const errorMessage = isError(error)
|
|
47
48
|
? error.message
|
|
48
49
|
: (error?.toString() ?? '');
|
|
49
50
|
console.error(`\n❌ ${cmd} failed (fail-fast mode stopped execution):`);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
|
|
3
|
+
import { isError } from '@sindresorhus/is';
|
|
3
4
|
import { executeStages } from './execute-parallel.mjs';
|
|
4
5
|
import { getWorkspacePackages } from './get-workspace-packages.mjs';
|
|
5
6
|
|
|
@@ -45,7 +46,7 @@ export const runCmdInStagesAcrossWorkspaces = async ({
|
|
|
45
46
|
await executeStages(filteredPackages, cmd, concurrency);
|
|
46
47
|
console.log(`\n✅ ${cmd} completed successfully (all stages)`);
|
|
47
48
|
} catch (error) {
|
|
48
|
-
const errorMessage =
|
|
49
|
+
const errorMessage = isError(error)
|
|
49
50
|
? error.message
|
|
50
51
|
: (error?.toString() ?? '');
|
|
51
52
|
console.error(`\n❌ ${cmd} failed (fail-fast mode stopped execution):`);
|
|
@@ -7,15 +7,15 @@ import { runCmdInStagesAcrossWorkspaces } from './run-cmd-in-stages.mjs';
|
|
|
7
7
|
import { type Package } from './types.mjs';
|
|
8
8
|
|
|
9
9
|
// Mock the dependencies
|
|
10
|
-
vi.mock('./execute-parallel.mjs', () => ({
|
|
10
|
+
vi.mock(import('./execute-parallel.mjs'), () => ({
|
|
11
11
|
executeStages: vi.fn(),
|
|
12
12
|
}));
|
|
13
13
|
|
|
14
|
-
vi.mock('./get-workspace-packages.mjs', () => ({
|
|
14
|
+
vi.mock(import('./get-workspace-packages.mjs'), () => ({
|
|
15
15
|
getWorkspacePackages: vi.fn(),
|
|
16
16
|
}));
|
|
17
17
|
|
|
18
|
-
describe(
|
|
18
|
+
describe(runCmdInStagesAcrossWorkspaces, () => {
|
|
19
19
|
type MockedSpies = Readonly<{
|
|
20
20
|
consoleLogSpy: MockInstance<typeof console.log>;
|
|
21
21
|
consoleErrorSpy: MockInstance<typeof console.error>;
|
|
@@ -217,6 +217,7 @@ describe('runCmdInStagesAcrossWorkspaces', () => {
|
|
|
217
217
|
const expectedFilteredPackages = mockPackages.filter((pkg) =>
|
|
218
218
|
pkg.name.startsWith('package-'),
|
|
219
219
|
);
|
|
220
|
+
|
|
220
221
|
expect(executeStages).toHaveBeenCalledWith(
|
|
221
222
|
expectedFilteredPackages,
|
|
222
223
|
'test',
|
package/src/node-global.mts
CHANGED