ts-repo-utils 2.2.1 → 2.3.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/dist/functions/assert-repo-is-dirty.d.mts +6 -2
- package/dist/functions/assert-repo-is-dirty.d.mts.map +1 -1
- package/dist/functions/assert-repo-is-dirty.mjs +14 -8
- package/dist/functions/assert-repo-is-dirty.mjs.map +1 -1
- package/dist/functions/diff.d.mts +4 -0
- package/dist/functions/diff.d.mts.map +1 -1
- package/dist/functions/diff.mjs +16 -14
- package/dist/functions/diff.mjs.map +1 -1
- package/dist/functions/exec-async.mjs +2 -2
- package/dist/functions/exec-async.mjs.map +1 -1
- package/dist/functions/format.d.mts +12 -3
- package/dist/functions/format.d.mts.map +1 -1
- package/dist/functions/format.mjs +56 -22
- package/dist/functions/format.mjs.map +1 -1
- package/dist/functions/gen-index.d.mts +4 -1
- package/dist/functions/gen-index.d.mts.map +1 -1
- package/dist/functions/gen-index.mjs +5 -2
- package/dist/functions/gen-index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/functions/assert-repo-is-dirty.mts +20 -8
- package/src/functions/diff.mts +24 -16
- package/src/functions/diff.test.mts +34 -19
- package/src/functions/exec-async.mts +2 -2
- package/src/functions/format.mts +69 -25
- package/src/functions/format.test.mts +27 -13
- package/src/functions/gen-index.mts +8 -2
|
@@ -4,10 +4,14 @@ import '../node-global.mjs';
|
|
|
4
4
|
* @returns True if the repo is dirty, false otherwise.
|
|
5
5
|
* @throws Error if git command fails.
|
|
6
6
|
*/
|
|
7
|
-
export declare const repoIsDirty: (
|
|
7
|
+
export declare const repoIsDirty: (options?: Readonly<{
|
|
8
|
+
silent?: boolean;
|
|
9
|
+
}>) => Promise<boolean>;
|
|
8
10
|
/**
|
|
9
11
|
* Checks if the repository is dirty and exits with code 1 if it is.
|
|
10
12
|
* Shows git status and diff output before exiting.
|
|
11
13
|
*/
|
|
12
|
-
export declare const assertRepoIsDirty: (
|
|
14
|
+
export declare const assertRepoIsDirty: (options?: Readonly<{
|
|
15
|
+
silent?: boolean;
|
|
16
|
+
}>) => Promise<void>;
|
|
13
17
|
//# sourceMappingURL=assert-repo-is-dirty.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert-repo-is-dirty.d.mts","sourceRoot":"","sources":["../../src/functions/assert-repo-is-dirty.mts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"assert-repo-is-dirty.d.mts","sourceRoot":"","sources":["../../src/functions/assert-repo-is-dirty.mts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACtB,UAAU,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACvC,OAAO,CAAC,OAAO,CAGjB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACvC,OAAO,CAAC,IAAI,CAiCd,CAAC"}
|
|
@@ -6,17 +6,17 @@ import '../node-global.mjs';
|
|
|
6
6
|
* @returns True if the repo is dirty, false otherwise.
|
|
7
7
|
* @throws Error if git command fails.
|
|
8
8
|
*/
|
|
9
|
-
const repoIsDirty = async () => {
|
|
10
|
-
const status = await getGitStatus();
|
|
9
|
+
const repoIsDirty = async (options) => {
|
|
10
|
+
const status = await getGitStatus({ silent: options?.silent ?? false });
|
|
11
11
|
return status.isDirty;
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* Checks if the repository is dirty and exits with code 1 if it is.
|
|
15
15
|
* Shows git status and diff output before exiting.
|
|
16
16
|
*/
|
|
17
|
-
const assertRepoIsDirty = async () => {
|
|
17
|
+
const assertRepoIsDirty = async (options) => {
|
|
18
18
|
try {
|
|
19
|
-
const status = await getGitStatus();
|
|
19
|
+
const status = await getGitStatus({ silent: options?.silent ?? false });
|
|
20
20
|
if (!status.isDirty) {
|
|
21
21
|
echo('Repo is clean\n');
|
|
22
22
|
return;
|
|
@@ -25,11 +25,15 @@ const assertRepoIsDirty = async () => {
|
|
|
25
25
|
echo('Changed files:\n');
|
|
26
26
|
echo(status.stdout);
|
|
27
27
|
// Show files not tracked by git and unstaged changes
|
|
28
|
-
const addResult = await $('git add -N .'
|
|
28
|
+
const addResult = await $('git add -N .', {
|
|
29
|
+
silent: options?.silent ?? false,
|
|
30
|
+
});
|
|
29
31
|
if (Result.isErr(addResult)) {
|
|
30
32
|
echo('Warning: Failed to add untracked files for diff\n');
|
|
31
33
|
}
|
|
32
|
-
const diffResult = await $('git diff'
|
|
34
|
+
const diffResult = await $('git diff', {
|
|
35
|
+
silent: options?.silent ?? false,
|
|
36
|
+
});
|
|
33
37
|
if (Result.isErr(diffResult)) {
|
|
34
38
|
echo('Warning: Failed to show diff\n');
|
|
35
39
|
}
|
|
@@ -44,8 +48,10 @@ const assertRepoIsDirty = async () => {
|
|
|
44
48
|
* Gets the git status of the repository.
|
|
45
49
|
* @returns An object containing status information.
|
|
46
50
|
*/
|
|
47
|
-
const getGitStatus = async () => {
|
|
48
|
-
const res = await $('git status --porcelain'
|
|
51
|
+
const getGitStatus = async (options) => {
|
|
52
|
+
const res = await $('git status --porcelain', {
|
|
53
|
+
silent: options?.silent ?? false,
|
|
54
|
+
});
|
|
49
55
|
if (Result.isErr(res)) {
|
|
50
56
|
throw new Error(`Failed to get git status: ${res.value.message}`);
|
|
51
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert-repo-is-dirty.mjs","sources":["../../src/functions/assert-repo-is-dirty.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGA;;;;AAIG;
|
|
1
|
+
{"version":3,"file":"assert-repo-is-dirty.mjs","sources":["../../src/functions/assert-repo-is-dirty.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGA;;;;AAIG;MACU,WAAW,GAAG,OACzB,OAAwC,KACpB;AACpB,IAAA,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC;IACvE,OAAO,MAAM,CAAC,OAAO;AACvB;AAEA;;;AAGG;MACU,iBAAiB,GAAG,OAC/B,OAAwC,KACvB;AACjB,IAAA,IAAI;AACF,QAAA,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC;AAEvE,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACnB,IAAI,CAAC,iBAAiB,CAAC;YACvB;;QAGF,IAAI,CAAC,iBAAiB,CAAC;QACvB,IAAI,CAAC,kBAAkB,CAAC;AACxB,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;;AAGnB,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,cAAc,EAAE;AACxC,YAAA,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;AACjC,SAAA,CAAC;AACF,QAAA,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;YAC3B,IAAI,CAAC,mDAAmD,CAAC;;AAG3D,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,UAAU,EAAE;AACrC,YAAA,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;AACjC,SAAA,CAAC;AACF,QAAA,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;YAC5B,IAAI,CAAC,gCAAgC,CAAC;;AAGxC,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;IACf,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,qCAAqC,MAAM,CAAC,KAAK,CAAC,CAAA,EAAA,CAAI,CAAC;AAC5D,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAEnB;AAEA;;;AAGG;AACH,MAAM,YAAY,GAAG,OACnB,OAAwC,KAIrC;AACH,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,wBAAwB,EAAE;AAC5C,QAAA,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;AACjC,KAAA,CAAC;AAEF,IAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QACrB,MAAM,IAAI,KAAK,CAAC,CAAA,0BAAA,EAA6B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAA,CAAE,CAAC;;AAGnE,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK;IAE5B,OAAO;AACL,QAAA,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;QAC7B,MAAM;KACP;AACH,CAAC;;;;"}
|
|
@@ -7,6 +7,8 @@ import '../node-global.mjs';
|
|
|
7
7
|
export declare const getUntrackedFiles: (options?: Readonly<{
|
|
8
8
|
/** @default true */
|
|
9
9
|
excludeDeleted?: boolean;
|
|
10
|
+
/** @default false */
|
|
11
|
+
silent?: boolean;
|
|
10
12
|
}>) => Promise<Result<readonly string[], ExecException | Readonly<{
|
|
11
13
|
message: string;
|
|
12
14
|
}>>>;
|
|
@@ -16,6 +18,8 @@ export declare const getUntrackedFiles: (options?: Readonly<{
|
|
|
16
18
|
export declare const getDiffFrom: (base: string, options?: Readonly<{
|
|
17
19
|
/** @default true */
|
|
18
20
|
excludeDeleted?: boolean;
|
|
21
|
+
/** @default false */
|
|
22
|
+
silent?: boolean;
|
|
19
23
|
}>) => Promise<Result<readonly string[], ExecException | Readonly<{
|
|
20
24
|
message: string;
|
|
21
25
|
}>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.mts","sourceRoot":"","sources":["../../src/functions/diff.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,oBAAoB,CAAC;AAE5B;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,QAAQ,CAAC;IACjB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"diff.d.mts","sourceRoot":"","sources":["../../src/functions/diff.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,oBAAoB,CAAC;AAE5B;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,QAAQ,CAAC;IACjB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC,KACD,OAAO,CACR,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,aAAa,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA2BzE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,UAAU,QAAQ,CAAC;IACjB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC,KACD,OAAO,CACR,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,aAAa,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA2BzE,CAAC"}
|
package/dist/functions/diff.mjs
CHANGED
|
@@ -6,7 +6,13 @@ import '../node-global.mjs';
|
|
|
6
6
|
*/
|
|
7
7
|
const getUntrackedFiles = async (options) => {
|
|
8
8
|
// Get changed files from git status
|
|
9
|
-
const result = await $(
|
|
9
|
+
const result = await $([
|
|
10
|
+
`git ls-files --others --exclude-standard`,
|
|
11
|
+
// Append '--deleted' to include deleted files only if excludeDeleted is explicitly false
|
|
12
|
+
(options?.excludeDeleted ?? true) ? '' : '--deleted',
|
|
13
|
+
]
|
|
14
|
+
.filter((s) => s !== '')
|
|
15
|
+
.join(' '), { silent: options?.silent ?? false });
|
|
10
16
|
if (Result.isErr(result)) {
|
|
11
17
|
return result;
|
|
12
18
|
}
|
|
@@ -14,18 +20,8 @@ const getUntrackedFiles = async (options) => {
|
|
|
14
20
|
// Parse git status output
|
|
15
21
|
const files = stdout
|
|
16
22
|
.split('\n')
|
|
17
|
-
.
|
|
18
|
-
.
|
|
19
|
-
// Status format: "XY filename" where X and Y are status codes
|
|
20
|
-
const match = /^..\s+(.+)$/u.exec(line);
|
|
21
|
-
return match?.[1];
|
|
22
|
-
})
|
|
23
|
-
.filter((file) =>
|
|
24
|
-
// Filter out deleted files (status starts with 'D')
|
|
25
|
-
file !== undefined &&
|
|
26
|
-
((options?.excludeDeleted ?? true)
|
|
27
|
-
? !stdout.includes(`D ${file}`)
|
|
28
|
-
: true));
|
|
23
|
+
.map((s) => s.trim())
|
|
24
|
+
.filter((s) => s !== '');
|
|
29
25
|
return Result.ok(files);
|
|
30
26
|
};
|
|
31
27
|
/**
|
|
@@ -33,7 +29,13 @@ const getUntrackedFiles = async (options) => {
|
|
|
33
29
|
*/
|
|
34
30
|
const getDiffFrom = async (base, options) => {
|
|
35
31
|
// Get files that differ from base branch/commit (excluding deleted files)
|
|
36
|
-
const result = await $(
|
|
32
|
+
const result = await $([
|
|
33
|
+
`git diff --name-only`,
|
|
34
|
+
base,
|
|
35
|
+
(options?.excludeDeleted ?? true) ? '--diff-filter=d' : '',
|
|
36
|
+
]
|
|
37
|
+
.filter((s) => s !== '')
|
|
38
|
+
.join(' '), { silent: options?.silent ?? false });
|
|
37
39
|
if (Result.isErr(result)) {
|
|
38
40
|
return result;
|
|
39
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.mjs","sources":["../../src/functions/diff.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIA;;AAEG;MACU,iBAAiB,GAAG,OAC/B,
|
|
1
|
+
{"version":3,"file":"diff.mjs","sources":["../../src/functions/diff.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIA;;AAEG;MACU,iBAAiB,GAAG,OAC/B,OAKE,KAGA;;AAEF,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,CACpB;QACE,CAAA,wCAAA,CAA0C;;AAE1C,QAAA,CAAC,OAAO,EAAE,cAAc,IAAI,IAAI,IAAI,EAAE,GAAG,WAAW;AACrD;SACE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE;AACtB,SAAA,IAAI,CAAC,GAAG,CAAC,EACZ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CACrC;AAED,IAAA,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;AACxB,QAAA,OAAO,MAAM;;AAGf,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK;;IAG/B,MAAM,KAAK,GAAG;SACX,KAAK,CAAC,IAAI;SACV,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;SACnB,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;AAE1B,IAAA,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;AACzB;AAEA;;AAEG;AACI,MAAM,WAAW,GAAG,OACzB,IAAY,EACZ,OAKE,KAGA;;AAEF,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,CACpB;QACE,CAAA,oBAAA,CAAsB;QACtB,IAAI;AACJ,QAAA,CAAC,OAAO,EAAE,cAAc,IAAI,IAAI,IAAI,iBAAiB,GAAG,EAAE;AAC3D;SACE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE;AACtB,SAAA,IAAI,CAAC,GAAG,CAAC,EACZ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CACrC;AAED,IAAA,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;AACxB,QAAA,OAAO,MAAM;;AAGf,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK;;IAG/B,MAAM,KAAK,GAAG;SACX,KAAK,CAAC,IAAI;SACV,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;SACzB,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;AAEhC,IAAA,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;AACzB;;;;"}
|
|
@@ -10,14 +10,14 @@ import { Result } from 'ts-data-forge';
|
|
|
10
10
|
const $ = (cmd, options = {}) => {
|
|
11
11
|
const { silent = false, timeout = 30000 } = options;
|
|
12
12
|
if (!silent) {
|
|
13
|
-
|
|
13
|
+
echo(`$ ${cmd}`);
|
|
14
14
|
}
|
|
15
15
|
return new Promise((resolve) => {
|
|
16
16
|
const execOptions = { timeout };
|
|
17
17
|
exec(cmd, execOptions, (error, stdout, stderr) => {
|
|
18
18
|
if (!silent) {
|
|
19
19
|
if (stdout !== '') {
|
|
20
|
-
|
|
20
|
+
echo(stdout);
|
|
21
21
|
}
|
|
22
22
|
if (stderr !== '') {
|
|
23
23
|
console.error(stderr);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec-async.mjs","sources":["../../src/functions/exec-async.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGA;;;;;AAKG;AACI,MAAM,CAAC,GAAG,CACf,GAAW,EACX,OAAA,GAA4D,EAAE,KAG5D;IACF,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO;IAEnD,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,
|
|
1
|
+
{"version":3,"file":"exec-async.mjs","sources":["../../src/functions/exec-async.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGA;;;;;AAKG;AACI,MAAM,CAAC,GAAG,CACf,GAAW,EACX,OAAA,GAA4D,EAAE,KAG5D;IACF,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO;IAEnD,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,IAAI,CAAC,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAC;;AAGlB,IAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;AAC7B,QAAA,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE;AAE/B,QAAA,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,KAAI;YAC/C,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,IAAI,MAAM,KAAK,EAAE,EAAE;oBACjB,IAAI,CAAC,MAAM,CAAC;;AAEd,gBAAA,IAAI,MAAM,KAAK,EAAE,EAAE;AACjB,oBAAA,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;;;AAIzB,YAAA,IAAI,KAAK,KAAK,IAAI,EAAE;gBAClB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;iBACrB;AACL,gBAAA,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;;AAE1C,SAAC,CAAC;AACJ,KAAC,CAAC;AACJ;;;;"}
|
|
@@ -4,26 +4,35 @@ import '../node-global.mjs';
|
|
|
4
4
|
* @param files - Array of file paths to format
|
|
5
5
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
6
6
|
*/
|
|
7
|
-
export declare const formatFilesList: (files: readonly string[]
|
|
7
|
+
export declare const formatFilesList: (files: readonly string[], options?: Readonly<{
|
|
8
|
+
silent?: boolean;
|
|
9
|
+
}>) => Promise<"ok" | "err">;
|
|
8
10
|
/**
|
|
9
11
|
* Format files matching the given glob pattern using Prettier
|
|
10
12
|
* @param pathGlob - Glob pattern to match files
|
|
11
13
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
12
14
|
*/
|
|
13
|
-
export declare const formatFiles: (pathGlob: string
|
|
15
|
+
export declare const formatFiles: (pathGlob: string, options?: Readonly<{
|
|
16
|
+
silent?: boolean;
|
|
17
|
+
}>) => Promise<"ok" | "err">;
|
|
14
18
|
/**
|
|
15
19
|
* Format only files that have been changed (git status)
|
|
20
|
+
* @param options - Options for formatting
|
|
16
21
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
17
22
|
*/
|
|
18
|
-
export declare const formatUntracked: (
|
|
23
|
+
export declare const formatUntracked: (options?: Readonly<{
|
|
24
|
+
silent?: boolean;
|
|
25
|
+
}>) => Promise<"ok" | "err">;
|
|
19
26
|
/**
|
|
20
27
|
* Format only files that differ from the specified base branch or commit
|
|
21
28
|
* @param base - Base branch name or commit hash to compare against (defaults to 'main')
|
|
22
29
|
* @param options - Options for formatting
|
|
23
30
|
* @param options.includeUntracked - Include untracked files in addition to diff files (default is true)
|
|
31
|
+
* @param options.silent - Silent mode to suppress command output (default is false)
|
|
24
32
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
25
33
|
*/
|
|
26
34
|
export declare const formatDiffFrom: (base: string, options?: Readonly<{
|
|
27
35
|
includeUntracked?: boolean;
|
|
36
|
+
silent?: boolean;
|
|
28
37
|
}>) => Promise<"ok" | "err">;
|
|
29
38
|
//# sourceMappingURL=format.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.mts","sourceRoot":"","sources":["../../src/functions/format.mts"],"names":[],"mappings":"AAIA,OAAO,oBAAoB,CAAC;AAG5B;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,SAAS,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"format.d.mts","sourceRoot":"","sources":["../../src/functions/format.mts"],"names":[],"mappings":"AAIA,OAAO,oBAAoB,CAAC;AAG5B;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,SAAS,MAAM,EAAE,EACxB,UAAU,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACvC,OAAO,CAAC,IAAI,GAAG,KAAK,CA2DtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACtB,UAAU,MAAM,EAChB,UAAU,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACvC,OAAO,CAAC,IAAI,GAAG,KAAK,CAuBtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACvC,OAAO,CAAC,IAAI,GAAG,KAAK,CAqDtB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,UAAU,QAAQ,CAAC;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACnE,OAAO,CAAC,IAAI,GAAG,KAAK,CA6DtB,CAAC"}
|
|
@@ -10,36 +10,45 @@ import { getUntrackedFiles, getDiffFrom } from './diff.mjs';
|
|
|
10
10
|
* @param files - Array of file paths to format
|
|
11
11
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
12
12
|
*/
|
|
13
|
-
const formatFilesList = async (files) => {
|
|
13
|
+
const formatFilesList = async (files, options) => {
|
|
14
|
+
const silent = options?.silent ?? false;
|
|
14
15
|
if (files.length === 0) {
|
|
15
|
-
|
|
16
|
+
if (!silent) {
|
|
17
|
+
echo('No files to format');
|
|
18
|
+
}
|
|
16
19
|
return 'ok';
|
|
17
20
|
}
|
|
18
|
-
|
|
21
|
+
if (!silent) {
|
|
22
|
+
echo(`Formatting ${files.length} files...`);
|
|
23
|
+
}
|
|
19
24
|
// Format each file
|
|
20
25
|
const results = await Promise.allSettled(files.map(async (filePath) => {
|
|
21
26
|
try {
|
|
22
27
|
// Read file content
|
|
23
28
|
const content = await readFile(filePath, 'utf8');
|
|
24
29
|
// Resolve prettier config for this file
|
|
25
|
-
const
|
|
30
|
+
const prettierOptions = await prettier.resolveConfig(filePath);
|
|
26
31
|
// Check if file is ignored by prettier
|
|
27
32
|
const fileInfo = await prettier.getFileInfo(filePath, {
|
|
28
33
|
ignorePath: '.prettierignore',
|
|
29
34
|
});
|
|
30
35
|
if (fileInfo.ignored) {
|
|
31
|
-
|
|
36
|
+
if (!silent) {
|
|
37
|
+
echo(`Skipping ignored file: ${filePath}`);
|
|
38
|
+
}
|
|
32
39
|
return;
|
|
33
40
|
}
|
|
34
41
|
// Format the content
|
|
35
42
|
const formatted = await prettier.format(content, {
|
|
36
|
-
...
|
|
43
|
+
...prettierOptions,
|
|
37
44
|
filepath: filePath,
|
|
38
45
|
});
|
|
39
46
|
// Only write if content changed
|
|
40
47
|
if (formatted !== content) {
|
|
41
48
|
await writeFile(filePath, formatted, 'utf8');
|
|
42
|
-
|
|
49
|
+
if (!silent) {
|
|
50
|
+
echo(`Formatted: ${filePath}`);
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
catch (error) {
|
|
@@ -56,7 +65,8 @@ const formatFilesList = async (files) => {
|
|
|
56
65
|
* @param pathGlob - Glob pattern to match files
|
|
57
66
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
58
67
|
*/
|
|
59
|
-
const formatFiles = async (pathGlob) => {
|
|
68
|
+
const formatFiles = async (pathGlob, options) => {
|
|
69
|
+
const silent = options?.silent ?? false;
|
|
60
70
|
try {
|
|
61
71
|
// Find all files matching the glob
|
|
62
72
|
const files = await glob_(pathGlob, {
|
|
@@ -65,10 +75,12 @@ const formatFiles = async (pathGlob) => {
|
|
|
65
75
|
dot: true,
|
|
66
76
|
});
|
|
67
77
|
if (files.length === 0) {
|
|
68
|
-
|
|
78
|
+
if (!silent) {
|
|
79
|
+
echo('No files found matching pattern:', pathGlob);
|
|
80
|
+
}
|
|
69
81
|
return 'ok';
|
|
70
82
|
}
|
|
71
|
-
return await formatFilesList(files);
|
|
83
|
+
return await formatFilesList(files, { silent });
|
|
72
84
|
}
|
|
73
85
|
catch (error) {
|
|
74
86
|
console.error('Error in formatFiles:', error);
|
|
@@ -77,21 +89,29 @@ const formatFiles = async (pathGlob) => {
|
|
|
77
89
|
};
|
|
78
90
|
/**
|
|
79
91
|
* Format only files that have been changed (git status)
|
|
92
|
+
* @param options - Options for formatting
|
|
80
93
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
81
94
|
*/
|
|
82
|
-
const formatUntracked = async () => {
|
|
95
|
+
const formatUntracked = async (options) => {
|
|
96
|
+
const silent = options?.silent ?? false;
|
|
83
97
|
try {
|
|
84
|
-
const untrackedFilesResult = await getUntrackedFiles(
|
|
98
|
+
const untrackedFilesResult = await getUntrackedFiles({
|
|
99
|
+
silent,
|
|
100
|
+
});
|
|
85
101
|
if (Result.isErr(untrackedFilesResult)) {
|
|
86
102
|
console.error('Error getting changed files:', untrackedFilesResult.value);
|
|
87
103
|
return 'err';
|
|
88
104
|
}
|
|
89
105
|
const files = untrackedFilesResult.value;
|
|
90
106
|
if (files.length === 0) {
|
|
91
|
-
|
|
107
|
+
if (!silent) {
|
|
108
|
+
echo('No changed files to format');
|
|
109
|
+
}
|
|
92
110
|
return 'ok';
|
|
93
111
|
}
|
|
94
|
-
|
|
112
|
+
if (!silent) {
|
|
113
|
+
echo('Formatting changed files:', files);
|
|
114
|
+
}
|
|
95
115
|
// Filter out non-existent files before formatting
|
|
96
116
|
const fileExistenceChecks = await Promise.allSettled(files.map(async (filePath) => {
|
|
97
117
|
try {
|
|
@@ -99,14 +119,16 @@ const formatUntracked = async () => {
|
|
|
99
119
|
return filePath;
|
|
100
120
|
}
|
|
101
121
|
catch {
|
|
102
|
-
|
|
122
|
+
if (!silent) {
|
|
123
|
+
echo(`Skipping non-existent file: ${filePath}`);
|
|
124
|
+
}
|
|
103
125
|
return undefined;
|
|
104
126
|
}
|
|
105
127
|
}));
|
|
106
128
|
const existingFiles = fileExistenceChecks
|
|
107
129
|
.filter((result) => result.status === 'fulfilled' && result.value !== undefined)
|
|
108
130
|
.map((result) => result.value);
|
|
109
|
-
return await formatFilesList(existingFiles);
|
|
131
|
+
return await formatFilesList(existingFiles, { silent });
|
|
110
132
|
}
|
|
111
133
|
catch (error) {
|
|
112
134
|
console.error('Error in formatUntracked:', error);
|
|
@@ -118,12 +140,16 @@ const formatUntracked = async () => {
|
|
|
118
140
|
* @param base - Base branch name or commit hash to compare against (defaults to 'main')
|
|
119
141
|
* @param options - Options for formatting
|
|
120
142
|
* @param options.includeUntracked - Include untracked files in addition to diff files (default is true)
|
|
143
|
+
* @param options.silent - Silent mode to suppress command output (default is false)
|
|
121
144
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
122
145
|
*/
|
|
123
146
|
const formatDiffFrom = async (base, options) => {
|
|
147
|
+
const silent = options?.silent ?? false;
|
|
124
148
|
try {
|
|
125
149
|
// Get files that differ from base branch/commit (excluding deleted files)
|
|
126
|
-
const diffFromBaseResult = await getDiffFrom(base
|
|
150
|
+
const diffFromBaseResult = await getDiffFrom(base, {
|
|
151
|
+
silent,
|
|
152
|
+
});
|
|
127
153
|
if (Result.isErr(diffFromBaseResult)) {
|
|
128
154
|
console.error('Error getting changed files:', diffFromBaseResult.value);
|
|
129
155
|
return 'err';
|
|
@@ -132,7 +158,9 @@ const formatDiffFrom = async (base, options) => {
|
|
|
132
158
|
let allFiles = diffFiles;
|
|
133
159
|
// If includeUntracked is true, also get untracked files
|
|
134
160
|
if (options?.includeUntracked ?? true) {
|
|
135
|
-
const untrackedFilesResult = await getUntrackedFiles(
|
|
161
|
+
const untrackedFilesResult = await getUntrackedFiles({
|
|
162
|
+
silent,
|
|
163
|
+
});
|
|
136
164
|
if (Result.isErr(untrackedFilesResult)) {
|
|
137
165
|
console.error('Error getting untracked files:', untrackedFilesResult.value);
|
|
138
166
|
return 'err';
|
|
@@ -141,16 +169,22 @@ const formatDiffFrom = async (base, options) => {
|
|
|
141
169
|
// Combine and deduplicate files
|
|
142
170
|
const uniqueFiles = new Set([...diffFiles, ...untrackedFiles]);
|
|
143
171
|
allFiles = Array.from(uniqueFiles);
|
|
144
|
-
|
|
172
|
+
if (!silent) {
|
|
173
|
+
echo(`Formatting files that differ from ${base} and untracked files:`, allFiles);
|
|
174
|
+
}
|
|
145
175
|
}
|
|
146
176
|
else {
|
|
147
|
-
|
|
177
|
+
if (!silent) {
|
|
178
|
+
echo(`Formatting files that differ from ${base}:`, allFiles);
|
|
179
|
+
}
|
|
148
180
|
}
|
|
149
181
|
if (allFiles.length === 0) {
|
|
150
|
-
|
|
182
|
+
if (!silent) {
|
|
183
|
+
echo(`No files to format`);
|
|
184
|
+
}
|
|
151
185
|
return 'ok';
|
|
152
186
|
}
|
|
153
|
-
return await formatFilesList(allFiles);
|
|
187
|
+
return await formatFilesList(allFiles, { silent });
|
|
154
188
|
}
|
|
155
189
|
catch (error) {
|
|
156
190
|
console.error('Error in formatDiffFrom:', error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.mjs","sources":["../../src/functions/format.mts"],"sourcesContent":[null],"names":["glob"],"mappings":";;;;;;;AAOA;;;;AAIG;
|
|
1
|
+
{"version":3,"file":"format.mjs","sources":["../../src/functions/format.mts"],"sourcesContent":[null],"names":["glob"],"mappings":"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"}
|
|
@@ -15,7 +15,10 @@ export type GenIndexConfig = DeepReadonly<{
|
|
|
15
15
|
/**
|
|
16
16
|
* Generates index.mts files recursively in `config.targetDirectory`.
|
|
17
17
|
* @param config - Configuration for index file generation
|
|
18
|
+
* @param options - Additional options
|
|
18
19
|
* @throws Error if any step fails.
|
|
19
20
|
*/
|
|
20
|
-
export declare const genIndex: (config: GenIndexConfig
|
|
21
|
+
export declare const genIndex: (config: GenIndexConfig, options?: Readonly<{
|
|
22
|
+
silent?: boolean;
|
|
23
|
+
}>) => Promise<void>;
|
|
21
24
|
//# sourceMappingURL=gen-index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gen-index.d.mts","sourceRoot":"","sources":["../../src/functions/gen-index.mts"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC;IACxC,kFAAkF;IAClF,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEnC,iEAAiE;IACjE,eAAe,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;IAE/B,mEAAmE;IACnE,eAAe,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;IAE/B,gGAAgG;IAChG,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"gen-index.d.mts","sourceRoot":"","sources":["../../src/functions/gen-index.mts"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC;IACxC,kFAAkF;IAClF,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEnC,iEAAiE;IACjE,eAAe,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;IAE/B,mEAAmE;IACnE,eAAe,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;IAE/B,gGAAgG;IAChG,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GACnB,QAAQ,cAAc,EACtB,UAAU,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACvC,OAAO,CAAC,IAAI,CA4Cd,CAAC"}
|
|
@@ -6,9 +6,10 @@ import { assertPathExists } from './assert-path-exists.mjs';
|
|
|
6
6
|
/**
|
|
7
7
|
* Generates index.mts files recursively in `config.targetDirectory`.
|
|
8
8
|
* @param config - Configuration for index file generation
|
|
9
|
+
* @param options - Additional options
|
|
9
10
|
* @throws Error if any step fails.
|
|
10
11
|
*/
|
|
11
|
-
const genIndex = async (config) => {
|
|
12
|
+
const genIndex = async (config, options) => {
|
|
12
13
|
echo('Starting index file generation...\n');
|
|
13
14
|
// Merge config with defaults
|
|
14
15
|
const filledConfig = fillConfig(config);
|
|
@@ -33,7 +34,9 @@ const genIndex = async (config) => {
|
|
|
33
34
|
echo('✓ Index files generated\n');
|
|
34
35
|
// Step 3: Format generated files
|
|
35
36
|
echo('3. Formatting generated files...');
|
|
36
|
-
const fmtResult = await $('npm run fmt'
|
|
37
|
+
const fmtResult = await $('npm run fmt', {
|
|
38
|
+
silent: options?.silent ?? false,
|
|
39
|
+
});
|
|
37
40
|
if (Result.isErr(fmtResult)) {
|
|
38
41
|
throw new Error(`Formatting failed: ${fmtResult.value.message}`);
|
|
39
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gen-index.mjs","sources":["../../src/functions/gen-index.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;AAsBA
|
|
1
|
+
{"version":3,"file":"gen-index.mjs","sources":["../../src/functions/gen-index.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-repo-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript"
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"fast-glob": "^3.3.3",
|
|
59
59
|
"micromatch": "^4.0.8",
|
|
60
60
|
"prettier": "^3.6.2",
|
|
61
|
-
"ts-data-forge": "^1.
|
|
61
|
+
"ts-data-forge": "^1.2.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@eslint/js": "^9.30.0",
|
|
@@ -6,8 +6,10 @@ import '../node-global.mjs';
|
|
|
6
6
|
* @returns True if the repo is dirty, false otherwise.
|
|
7
7
|
* @throws Error if git command fails.
|
|
8
8
|
*/
|
|
9
|
-
export const repoIsDirty = async (
|
|
10
|
-
|
|
9
|
+
export const repoIsDirty = async (
|
|
10
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
11
|
+
): Promise<boolean> => {
|
|
12
|
+
const status = await getGitStatus({ silent: options?.silent ?? false });
|
|
11
13
|
return status.isDirty;
|
|
12
14
|
};
|
|
13
15
|
|
|
@@ -15,9 +17,11 @@ export const repoIsDirty = async (): Promise<boolean> => {
|
|
|
15
17
|
* Checks if the repository is dirty and exits with code 1 if it is.
|
|
16
18
|
* Shows git status and diff output before exiting.
|
|
17
19
|
*/
|
|
18
|
-
export const assertRepoIsDirty = async (
|
|
20
|
+
export const assertRepoIsDirty = async (
|
|
21
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
22
|
+
): Promise<void> => {
|
|
19
23
|
try {
|
|
20
|
-
const status = await getGitStatus();
|
|
24
|
+
const status = await getGitStatus({ silent: options?.silent ?? false });
|
|
21
25
|
|
|
22
26
|
if (!status.isDirty) {
|
|
23
27
|
echo('Repo is clean\n');
|
|
@@ -29,12 +33,16 @@ export const assertRepoIsDirty = async (): Promise<void> => {
|
|
|
29
33
|
echo(status.stdout);
|
|
30
34
|
|
|
31
35
|
// Show files not tracked by git and unstaged changes
|
|
32
|
-
const addResult = await $('git add -N .'
|
|
36
|
+
const addResult = await $('git add -N .', {
|
|
37
|
+
silent: options?.silent ?? false,
|
|
38
|
+
});
|
|
33
39
|
if (Result.isErr(addResult)) {
|
|
34
40
|
echo('Warning: Failed to add untracked files for diff\n');
|
|
35
41
|
}
|
|
36
42
|
|
|
37
|
-
const diffResult = await $('git diff'
|
|
43
|
+
const diffResult = await $('git diff', {
|
|
44
|
+
silent: options?.silent ?? false,
|
|
45
|
+
});
|
|
38
46
|
if (Result.isErr(diffResult)) {
|
|
39
47
|
echo('Warning: Failed to show diff\n');
|
|
40
48
|
}
|
|
@@ -50,11 +58,15 @@ export const assertRepoIsDirty = async (): Promise<void> => {
|
|
|
50
58
|
* Gets the git status of the repository.
|
|
51
59
|
* @returns An object containing status information.
|
|
52
60
|
*/
|
|
53
|
-
const getGitStatus = async (
|
|
61
|
+
const getGitStatus = async (
|
|
62
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
63
|
+
): Promise<{
|
|
54
64
|
isDirty: boolean;
|
|
55
65
|
stdout: string;
|
|
56
66
|
}> => {
|
|
57
|
-
const res = await $('git status --porcelain'
|
|
67
|
+
const res = await $('git status --porcelain', {
|
|
68
|
+
silent: options?.silent ?? false,
|
|
69
|
+
});
|
|
58
70
|
|
|
59
71
|
if (Result.isErr(res)) {
|
|
60
72
|
throw new Error(`Failed to get git status: ${res.value.message}`);
|
package/src/functions/diff.mts
CHANGED
|
@@ -9,12 +9,23 @@ export const getUntrackedFiles = async (
|
|
|
9
9
|
options?: Readonly<{
|
|
10
10
|
/** @default true */
|
|
11
11
|
excludeDeleted?: boolean;
|
|
12
|
+
/** @default false */
|
|
13
|
+
silent?: boolean;
|
|
12
14
|
}>,
|
|
13
15
|
): Promise<
|
|
14
16
|
Result<readonly string[], ExecException | Readonly<{ message: string }>>
|
|
15
17
|
> => {
|
|
16
18
|
// Get changed files from git status
|
|
17
|
-
const result = await $(
|
|
19
|
+
const result = await $(
|
|
20
|
+
[
|
|
21
|
+
`git ls-files --others --exclude-standard`,
|
|
22
|
+
// Append '--deleted' to include deleted files only if excludeDeleted is explicitly false
|
|
23
|
+
(options?.excludeDeleted ?? true) ? '' : '--deleted',
|
|
24
|
+
]
|
|
25
|
+
.filter((s) => s !== '')
|
|
26
|
+
.join(' '),
|
|
27
|
+
{ silent: options?.silent ?? false },
|
|
28
|
+
);
|
|
18
29
|
|
|
19
30
|
if (Result.isErr(result)) {
|
|
20
31
|
return result;
|
|
@@ -25,20 +36,8 @@ export const getUntrackedFiles = async (
|
|
|
25
36
|
// Parse git status output
|
|
26
37
|
const files = stdout
|
|
27
38
|
.split('\n')
|
|
28
|
-
.
|
|
29
|
-
.
|
|
30
|
-
// Status format: "XY filename" where X and Y are status codes
|
|
31
|
-
const match = /^..\s+(.+)$/u.exec(line);
|
|
32
|
-
return match?.[1];
|
|
33
|
-
})
|
|
34
|
-
.filter(
|
|
35
|
-
(file): file is string =>
|
|
36
|
-
// Filter out deleted files (status starts with 'D')
|
|
37
|
-
file !== undefined &&
|
|
38
|
-
((options?.excludeDeleted ?? true)
|
|
39
|
-
? !stdout.includes(`D ${file}`)
|
|
40
|
-
: true),
|
|
41
|
-
);
|
|
39
|
+
.map((s) => s.trim())
|
|
40
|
+
.filter((s) => s !== '');
|
|
42
41
|
|
|
43
42
|
return Result.ok(files);
|
|
44
43
|
};
|
|
@@ -51,13 +50,22 @@ export const getDiffFrom = async (
|
|
|
51
50
|
options?: Readonly<{
|
|
52
51
|
/** @default true */
|
|
53
52
|
excludeDeleted?: boolean;
|
|
53
|
+
/** @default false */
|
|
54
|
+
silent?: boolean;
|
|
54
55
|
}>,
|
|
55
56
|
): Promise<
|
|
56
57
|
Result<readonly string[], ExecException | Readonly<{ message: string }>>
|
|
57
58
|
> => {
|
|
58
59
|
// Get files that differ from base branch/commit (excluding deleted files)
|
|
59
60
|
const result = await $(
|
|
60
|
-
|
|
61
|
+
[
|
|
62
|
+
`git diff --name-only`,
|
|
63
|
+
base,
|
|
64
|
+
(options?.excludeDeleted ?? true) ? '--diff-filter=d' : '',
|
|
65
|
+
]
|
|
66
|
+
.filter((s) => s !== '')
|
|
67
|
+
.join(' '),
|
|
68
|
+
{ silent: options?.silent ?? false },
|
|
61
69
|
);
|
|
62
70
|
|
|
63
71
|
if (Result.isErr(result)) {
|
|
@@ -2,7 +2,7 @@ import { rm, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { Result } from 'ts-data-forge';
|
|
4
4
|
import '../node-global.mjs';
|
|
5
|
-
import { getUntrackedFiles } from './diff.mjs';
|
|
5
|
+
import { getDiffFrom, getUntrackedFiles } from './diff.mjs';
|
|
6
6
|
|
|
7
7
|
describe('diff', () => {
|
|
8
8
|
// Use project root for test files to ensure git tracking
|
|
@@ -23,7 +23,7 @@ describe('diff', () => {
|
|
|
23
23
|
|
|
24
24
|
describe('getUntrackedFiles', () => {
|
|
25
25
|
test('should return empty array when no files are changed', async () => {
|
|
26
|
-
const result = await getUntrackedFiles();
|
|
26
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
27
27
|
|
|
28
28
|
expect(Result.isOk(result)).toBe(true);
|
|
29
29
|
if (Result.isOk(result)) {
|
|
@@ -39,12 +39,12 @@ describe('diff', () => {
|
|
|
39
39
|
|
|
40
40
|
await writeFile(testFilePath, 'test content');
|
|
41
41
|
|
|
42
|
-
const result = await getUntrackedFiles();
|
|
42
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
43
43
|
|
|
44
44
|
expect(Result.isOk(result)).toBe(true);
|
|
45
45
|
if (Result.isOk(result)) {
|
|
46
46
|
const files = result.value;
|
|
47
|
-
expect(files.some((file) => file
|
|
47
|
+
expect(files.some((file) => file === testFileName)).toBe(true);
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
|
|
@@ -58,21 +58,21 @@ describe('diff', () => {
|
|
|
58
58
|
await writeFile(testFilePath, 'initial content');
|
|
59
59
|
|
|
60
60
|
// Add to git to track it
|
|
61
|
-
await $(`git add ${testFileName}
|
|
61
|
+
await $(`git add ${testFileName}`, { silent: true });
|
|
62
62
|
|
|
63
63
|
// Modify the file
|
|
64
64
|
await writeFile(testFilePath, 'modified content');
|
|
65
65
|
|
|
66
|
-
const result = await getUntrackedFiles();
|
|
66
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
67
67
|
|
|
68
68
|
expect(Result.isOk(result)).toBe(true);
|
|
69
69
|
if (Result.isOk(result)) {
|
|
70
70
|
const files = result.value;
|
|
71
|
-
expect(files.some((file) => file
|
|
71
|
+
expect(files.some((file) => file === testFileName)).toBe(false);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// Reset git state
|
|
75
|
-
await $(`git reset HEAD ${testFileName}
|
|
75
|
+
await $(`git reset HEAD ${testFileName}`, { silent: true });
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
test('should detect multiple types of changes', async () => {
|
|
@@ -86,32 +86,30 @@ describe('diff', () => {
|
|
|
86
86
|
|
|
87
87
|
// Create and track another file
|
|
88
88
|
await writeFile(modifyFile, 'initial content');
|
|
89
|
-
await $(`git add test-modify-file.tmp
|
|
89
|
+
await $(`git add test-modify-file.tmp`, { silent: true });
|
|
90
90
|
|
|
91
91
|
// Modify the tracked file
|
|
92
92
|
await writeFile(modifyFile, 'modified content');
|
|
93
93
|
|
|
94
|
-
const result = await getUntrackedFiles();
|
|
94
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
95
95
|
|
|
96
96
|
expect(Result.isOk(result)).toBe(true);
|
|
97
97
|
if (Result.isOk(result)) {
|
|
98
98
|
const files = result.value;
|
|
99
|
-
expect(files.some((file) => file
|
|
100
|
-
|
|
99
|
+
expect(files.some((file) => file === 'test-new-file.tmp')).toBe(true);
|
|
100
|
+
expect(files.some((file) => file === 'test-modify-file.tmp')).toBe(
|
|
101
|
+
false,
|
|
101
102
|
);
|
|
102
|
-
expect(
|
|
103
|
-
files.some((file) => file.includes('test-modify-file.tmp')),
|
|
104
|
-
).toBe(true);
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
// Reset git state
|
|
108
|
-
await $(`git reset HEAD test-modify-file.tmp
|
|
106
|
+
await $(`git reset HEAD test-modify-file.tmp`, { silent: true });
|
|
109
107
|
});
|
|
110
108
|
|
|
111
109
|
test('should exclude deleted files from results', async () => {
|
|
112
110
|
// This test is more complex as it requires simulating git state
|
|
113
111
|
// For now, we'll test that the function executes successfully
|
|
114
|
-
const result = await getUntrackedFiles();
|
|
112
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
115
113
|
|
|
116
114
|
expect(Result.isOk(result)).toBe(true);
|
|
117
115
|
if (Result.isOk(result)) {
|
|
@@ -127,14 +125,14 @@ describe('diff', () => {
|
|
|
127
125
|
test('should handle git command errors gracefully', async () => {
|
|
128
126
|
// This test would require mocking git command failure
|
|
129
127
|
// For now, we'll ensure the function returns a Result type
|
|
130
|
-
const result = await getUntrackedFiles();
|
|
128
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
131
129
|
|
|
132
130
|
// Should always return a Result, either Ok or Err
|
|
133
131
|
expect(Result.isOk(result) || Result.isErr(result)).toBe(true);
|
|
134
132
|
});
|
|
135
133
|
|
|
136
134
|
test('should parse git status output correctly', async () => {
|
|
137
|
-
const result = await getUntrackedFiles();
|
|
135
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
138
136
|
|
|
139
137
|
expect(Result.isOk(result)).toBe(true);
|
|
140
138
|
if (Result.isOk(result)) {
|
|
@@ -148,5 +146,22 @@ describe('diff', () => {
|
|
|
148
146
|
});
|
|
149
147
|
}
|
|
150
148
|
});
|
|
149
|
+
|
|
150
|
+
test('should work with silent option', async () => {
|
|
151
|
+
const result = await getUntrackedFiles({ silent: true });
|
|
152
|
+
|
|
153
|
+
expect(Result.isOk(result)).toBe(true);
|
|
154
|
+
if (Result.isOk(result)) {
|
|
155
|
+
expect(Array.isArray(result.value)).toBe(true);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('getDiffFrom', () => {
|
|
161
|
+
test('should work with silent option', async () => {
|
|
162
|
+
const result = await getDiffFrom('HEAD~1', { silent: true });
|
|
163
|
+
|
|
164
|
+
expect(Result.isOk(result) || Result.isErr(result)).toBe(true);
|
|
165
|
+
});
|
|
151
166
|
});
|
|
152
167
|
});
|
|
@@ -16,7 +16,7 @@ export const $ = (
|
|
|
16
16
|
const { silent = false, timeout = 30000 } = options;
|
|
17
17
|
|
|
18
18
|
if (!silent) {
|
|
19
|
-
|
|
19
|
+
echo(`$ ${cmd}`);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
return new Promise((resolve) => {
|
|
@@ -25,7 +25,7 @@ export const $ = (
|
|
|
25
25
|
exec(cmd, execOptions, (error, stdout, stderr) => {
|
|
26
26
|
if (!silent) {
|
|
27
27
|
if (stdout !== '') {
|
|
28
|
-
|
|
28
|
+
echo(stdout);
|
|
29
29
|
}
|
|
30
30
|
if (stderr !== '') {
|
|
31
31
|
console.error(stderr);
|
package/src/functions/format.mts
CHANGED
|
@@ -12,13 +12,20 @@ import { getDiffFrom, getUntrackedFiles } from './diff.mjs';
|
|
|
12
12
|
*/
|
|
13
13
|
export const formatFilesList = async (
|
|
14
14
|
files: readonly string[],
|
|
15
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
15
16
|
): Promise<'ok' | 'err'> => {
|
|
17
|
+
const silent = options?.silent ?? false;
|
|
18
|
+
|
|
16
19
|
if (files.length === 0) {
|
|
17
|
-
|
|
20
|
+
if (!silent) {
|
|
21
|
+
echo('No files to format');
|
|
22
|
+
}
|
|
18
23
|
return 'ok';
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
if (!silent) {
|
|
27
|
+
echo(`Formatting ${files.length} files...`);
|
|
28
|
+
}
|
|
22
29
|
|
|
23
30
|
// Format each file
|
|
24
31
|
const results = await Promise.allSettled(
|
|
@@ -28,7 +35,7 @@ export const formatFilesList = async (
|
|
|
28
35
|
const content = await readFile(filePath, 'utf8');
|
|
29
36
|
|
|
30
37
|
// Resolve prettier config for this file
|
|
31
|
-
const
|
|
38
|
+
const prettierOptions = await prettier.resolveConfig(filePath);
|
|
32
39
|
|
|
33
40
|
// Check if file is ignored by prettier
|
|
34
41
|
const fileInfo = await prettier.getFileInfo(filePath, {
|
|
@@ -36,20 +43,24 @@ export const formatFilesList = async (
|
|
|
36
43
|
});
|
|
37
44
|
|
|
38
45
|
if (fileInfo.ignored) {
|
|
39
|
-
|
|
46
|
+
if (!silent) {
|
|
47
|
+
echo(`Skipping ignored file: ${filePath}`);
|
|
48
|
+
}
|
|
40
49
|
return;
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
// Format the content
|
|
44
53
|
const formatted = await prettier.format(content, {
|
|
45
|
-
...
|
|
54
|
+
...prettierOptions,
|
|
46
55
|
filepath: filePath,
|
|
47
56
|
});
|
|
48
57
|
|
|
49
58
|
// Only write if content changed
|
|
50
59
|
if (formatted !== content) {
|
|
51
60
|
await writeFile(filePath, formatted, 'utf8');
|
|
52
|
-
|
|
61
|
+
if (!silent) {
|
|
62
|
+
echo(`Formatted: ${filePath}`);
|
|
63
|
+
}
|
|
53
64
|
}
|
|
54
65
|
} catch (error) {
|
|
55
66
|
console.error(`Error formatting ${filePath}:`, error);
|
|
@@ -68,7 +79,12 @@ export const formatFilesList = async (
|
|
|
68
79
|
* @param pathGlob - Glob pattern to match files
|
|
69
80
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
70
81
|
*/
|
|
71
|
-
export const formatFiles = async (
|
|
82
|
+
export const formatFiles = async (
|
|
83
|
+
pathGlob: string,
|
|
84
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
85
|
+
): Promise<'ok' | 'err'> => {
|
|
86
|
+
const silent = options?.silent ?? false;
|
|
87
|
+
|
|
72
88
|
try {
|
|
73
89
|
// Find all files matching the glob
|
|
74
90
|
const files = await glob(pathGlob, {
|
|
@@ -78,11 +94,13 @@ export const formatFiles = async (pathGlob: string): Promise<'ok' | 'err'> => {
|
|
|
78
94
|
});
|
|
79
95
|
|
|
80
96
|
if (files.length === 0) {
|
|
81
|
-
|
|
97
|
+
if (!silent) {
|
|
98
|
+
echo('No files found matching pattern:', pathGlob);
|
|
99
|
+
}
|
|
82
100
|
return 'ok';
|
|
83
101
|
}
|
|
84
102
|
|
|
85
|
-
return await formatFilesList(files);
|
|
103
|
+
return await formatFilesList(files, { silent });
|
|
86
104
|
} catch (error) {
|
|
87
105
|
console.error('Error in formatFiles:', error);
|
|
88
106
|
return 'err';
|
|
@@ -91,11 +109,18 @@ export const formatFiles = async (pathGlob: string): Promise<'ok' | 'err'> => {
|
|
|
91
109
|
|
|
92
110
|
/**
|
|
93
111
|
* Format only files that have been changed (git status)
|
|
112
|
+
* @param options - Options for formatting
|
|
94
113
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
95
114
|
*/
|
|
96
|
-
export const formatUntracked = async (
|
|
115
|
+
export const formatUntracked = async (
|
|
116
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
117
|
+
): Promise<'ok' | 'err'> => {
|
|
118
|
+
const silent = options?.silent ?? false;
|
|
119
|
+
|
|
97
120
|
try {
|
|
98
|
-
const untrackedFilesResult = await getUntrackedFiles(
|
|
121
|
+
const untrackedFilesResult = await getUntrackedFiles({
|
|
122
|
+
silent,
|
|
123
|
+
});
|
|
99
124
|
|
|
100
125
|
if (Result.isErr(untrackedFilesResult)) {
|
|
101
126
|
console.error('Error getting changed files:', untrackedFilesResult.value);
|
|
@@ -105,11 +130,15 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
|
|
|
105
130
|
const files = untrackedFilesResult.value;
|
|
106
131
|
|
|
107
132
|
if (files.length === 0) {
|
|
108
|
-
|
|
133
|
+
if (!silent) {
|
|
134
|
+
echo('No changed files to format');
|
|
135
|
+
}
|
|
109
136
|
return 'ok';
|
|
110
137
|
}
|
|
111
138
|
|
|
112
|
-
|
|
139
|
+
if (!silent) {
|
|
140
|
+
echo('Formatting changed files:', files);
|
|
141
|
+
}
|
|
113
142
|
|
|
114
143
|
// Filter out non-existent files before formatting
|
|
115
144
|
const fileExistenceChecks = await Promise.allSettled(
|
|
@@ -118,7 +147,9 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
|
|
|
118
147
|
await readFile(filePath, 'utf8');
|
|
119
148
|
return filePath;
|
|
120
149
|
} catch {
|
|
121
|
-
|
|
150
|
+
if (!silent) {
|
|
151
|
+
echo(`Skipping non-existent file: ${filePath}`);
|
|
152
|
+
}
|
|
122
153
|
return undefined;
|
|
123
154
|
}
|
|
124
155
|
}),
|
|
@@ -131,7 +162,7 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
|
|
|
131
162
|
)
|
|
132
163
|
.map((result) => result.value);
|
|
133
164
|
|
|
134
|
-
return await formatFilesList(existingFiles);
|
|
165
|
+
return await formatFilesList(existingFiles, { silent });
|
|
135
166
|
} catch (error) {
|
|
136
167
|
console.error('Error in formatUntracked:', error);
|
|
137
168
|
return 'err';
|
|
@@ -143,15 +174,20 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
|
|
|
143
174
|
* @param base - Base branch name or commit hash to compare against (defaults to 'main')
|
|
144
175
|
* @param options - Options for formatting
|
|
145
176
|
* @param options.includeUntracked - Include untracked files in addition to diff files (default is true)
|
|
177
|
+
* @param options.silent - Silent mode to suppress command output (default is false)
|
|
146
178
|
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
147
179
|
*/
|
|
148
180
|
export const formatDiffFrom = async (
|
|
149
181
|
base: string,
|
|
150
|
-
options?: Readonly<{ includeUntracked?: boolean }>,
|
|
182
|
+
options?: Readonly<{ includeUntracked?: boolean; silent?: boolean }>,
|
|
151
183
|
): Promise<'ok' | 'err'> => {
|
|
184
|
+
const silent = options?.silent ?? false;
|
|
185
|
+
|
|
152
186
|
try {
|
|
153
187
|
// Get files that differ from base branch/commit (excluding deleted files)
|
|
154
|
-
const diffFromBaseResult = await getDiffFrom(base
|
|
188
|
+
const diffFromBaseResult = await getDiffFrom(base, {
|
|
189
|
+
silent,
|
|
190
|
+
});
|
|
155
191
|
|
|
156
192
|
if (Result.isErr(diffFromBaseResult)) {
|
|
157
193
|
console.error('Error getting changed files:', diffFromBaseResult.value);
|
|
@@ -163,7 +199,9 @@ export const formatDiffFrom = async (
|
|
|
163
199
|
|
|
164
200
|
// If includeUntracked is true, also get untracked files
|
|
165
201
|
if (options?.includeUntracked ?? true) {
|
|
166
|
-
const untrackedFilesResult = await getUntrackedFiles(
|
|
202
|
+
const untrackedFilesResult = await getUntrackedFiles({
|
|
203
|
+
silent,
|
|
204
|
+
});
|
|
167
205
|
|
|
168
206
|
if (Result.isErr(untrackedFilesResult)) {
|
|
169
207
|
console.error(
|
|
@@ -179,20 +217,26 @@ export const formatDiffFrom = async (
|
|
|
179
217
|
const uniqueFiles = new Set([...diffFiles, ...untrackedFiles]);
|
|
180
218
|
allFiles = Array.from(uniqueFiles);
|
|
181
219
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
220
|
+
if (!silent) {
|
|
221
|
+
echo(
|
|
222
|
+
`Formatting files that differ from ${base} and untracked files:`,
|
|
223
|
+
allFiles,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
186
226
|
} else {
|
|
187
|
-
|
|
227
|
+
if (!silent) {
|
|
228
|
+
echo(`Formatting files that differ from ${base}:`, allFiles);
|
|
229
|
+
}
|
|
188
230
|
}
|
|
189
231
|
|
|
190
232
|
if (allFiles.length === 0) {
|
|
191
|
-
|
|
233
|
+
if (!silent) {
|
|
234
|
+
echo(`No files to format`);
|
|
235
|
+
}
|
|
192
236
|
return 'ok';
|
|
193
237
|
}
|
|
194
238
|
|
|
195
|
-
return await formatFilesList(allFiles);
|
|
239
|
+
return await formatFilesList(allFiles, { silent });
|
|
196
240
|
} catch (error) {
|
|
197
241
|
console.error('Error in formatDiffFrom:', error);
|
|
198
242
|
return 'err';
|
|
@@ -54,7 +54,7 @@ describe('formatFiles', () => {
|
|
|
54
54
|
await createTestFile('test.md', '# Test\n\nSome spaces');
|
|
55
55
|
|
|
56
56
|
// Format TypeScript files
|
|
57
|
-
const result = await formatFiles(`${testDir}/*.ts
|
|
57
|
+
const result = await formatFiles(`${testDir}/*.ts`, { silent: true });
|
|
58
58
|
expect(result).toBe('ok');
|
|
59
59
|
|
|
60
60
|
// Check that files were formatted
|
|
@@ -85,7 +85,9 @@ describe('formatFiles', () => {
|
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
test('should return ok when no files match pattern', async () => {
|
|
88
|
-
const result = await formatFiles('/non-existent-path/*.ts'
|
|
88
|
+
const result = await formatFiles('/non-existent-path/*.ts', {
|
|
89
|
+
silent: true,
|
|
90
|
+
});
|
|
89
91
|
expect(result).toBe('ok');
|
|
90
92
|
});
|
|
91
93
|
|
|
@@ -103,7 +105,9 @@ describe('formatFiles', () => {
|
|
|
103
105
|
);
|
|
104
106
|
|
|
105
107
|
// Format with recursive glob
|
|
106
|
-
const result = await formatFiles(`${testDir}/**/*.ts
|
|
108
|
+
const result = await formatFiles(`${testDir}/**/*.ts`, {
|
|
109
|
+
silent: true,
|
|
110
|
+
});
|
|
107
111
|
expect(result).toBe('ok');
|
|
108
112
|
|
|
109
113
|
// Check that nested file was formatted
|
|
@@ -159,7 +163,9 @@ describe('formatFilesList', () => {
|
|
|
159
163
|
);
|
|
160
164
|
|
|
161
165
|
// Format the files
|
|
162
|
-
const result = await formatFilesList([file1, file2]
|
|
166
|
+
const result = await formatFilesList([file1, file2], {
|
|
167
|
+
silent: true,
|
|
168
|
+
});
|
|
163
169
|
expect(result).toBe('ok');
|
|
164
170
|
|
|
165
171
|
// Check formatted content
|
|
@@ -184,7 +190,9 @@ describe('formatFilesList', () => {
|
|
|
184
190
|
});
|
|
185
191
|
|
|
186
192
|
test('should return ok for empty file list', async () => {
|
|
187
|
-
const result = await formatFilesList([]
|
|
193
|
+
const result = await formatFilesList([], {
|
|
194
|
+
silent: true,
|
|
195
|
+
});
|
|
188
196
|
expect(result).toBe('ok');
|
|
189
197
|
});
|
|
190
198
|
});
|
|
@@ -224,7 +232,7 @@ describe('formatDiffFrom', () => {
|
|
|
224
232
|
|
|
225
233
|
vi.mocked(getUntrackedFiles).mockResolvedValue(Result.ok([]));
|
|
226
234
|
|
|
227
|
-
const result = await formatDiffFrom('main');
|
|
235
|
+
const result = await formatDiffFrom('main', { silent: true });
|
|
228
236
|
expect(result).toBe('ok');
|
|
229
237
|
|
|
230
238
|
// Check file was formatted
|
|
@@ -236,7 +244,7 @@ describe('formatDiffFrom', () => {
|
|
|
236
244
|
`}\n`,
|
|
237
245
|
);
|
|
238
246
|
|
|
239
|
-
expect(getDiffFrom).toHaveBeenCalledWith('main');
|
|
247
|
+
expect(getDiffFrom).toHaveBeenCalledWith('main', { silent: true });
|
|
240
248
|
} finally {
|
|
241
249
|
await fs.rm(testDir, { recursive: true, force: true });
|
|
242
250
|
}
|
|
@@ -266,7 +274,10 @@ describe('formatDiffFrom', () => {
|
|
|
266
274
|
Result.ok([untrackedFile]),
|
|
267
275
|
);
|
|
268
276
|
|
|
269
|
-
const result = await formatDiffFrom('main', {
|
|
277
|
+
const result = await formatDiffFrom('main', {
|
|
278
|
+
includeUntracked: true,
|
|
279
|
+
silent: true,
|
|
280
|
+
});
|
|
270
281
|
expect(result).toBe('ok');
|
|
271
282
|
|
|
272
283
|
// Check both files were formatted
|
|
@@ -284,8 +295,8 @@ describe('formatDiffFrom', () => {
|
|
|
284
295
|
`}\n`,
|
|
285
296
|
);
|
|
286
297
|
|
|
287
|
-
expect(getDiffFrom).toHaveBeenCalledWith('main');
|
|
288
|
-
expect(getUntrackedFiles).
|
|
298
|
+
expect(getDiffFrom).toHaveBeenCalledWith('main', { silent: true });
|
|
299
|
+
expect(getUntrackedFiles).toHaveBeenCalledWith({ silent: true });
|
|
289
300
|
} finally {
|
|
290
301
|
await fs.rm(testDir, { recursive: true, force: true });
|
|
291
302
|
}
|
|
@@ -306,12 +317,15 @@ describe('formatDiffFrom', () => {
|
|
|
306
317
|
vi.mocked(getDiffFrom).mockResolvedValue(Result.ok([sharedFile]));
|
|
307
318
|
vi.mocked(getUntrackedFiles).mockResolvedValue(Result.ok([sharedFile]));
|
|
308
319
|
|
|
309
|
-
const result = await formatDiffFrom('main', {
|
|
320
|
+
const result = await formatDiffFrom('main', {
|
|
321
|
+
includeUntracked: true,
|
|
322
|
+
silent: true,
|
|
323
|
+
});
|
|
310
324
|
expect(result).toBe('ok');
|
|
311
325
|
|
|
312
326
|
// Verify both functions were called
|
|
313
|
-
expect(getDiffFrom).toHaveBeenCalledWith('main');
|
|
314
|
-
expect(getUntrackedFiles).
|
|
327
|
+
expect(getDiffFrom).toHaveBeenCalledWith('main', { silent: true });
|
|
328
|
+
expect(getUntrackedFiles).toHaveBeenCalledWith({ silent: true });
|
|
315
329
|
|
|
316
330
|
// Check that the file was formatted (content should change)
|
|
317
331
|
const finalContent = await readTestFile(sharedFile);
|
|
@@ -23,9 +23,13 @@ export type GenIndexConfig = DeepReadonly<{
|
|
|
23
23
|
/**
|
|
24
24
|
* Generates index.mts files recursively in `config.targetDirectory`.
|
|
25
25
|
* @param config - Configuration for index file generation
|
|
26
|
+
* @param options - Additional options
|
|
26
27
|
* @throws Error if any step fails.
|
|
27
28
|
*/
|
|
28
|
-
export const genIndex = async (
|
|
29
|
+
export const genIndex = async (
|
|
30
|
+
config: GenIndexConfig,
|
|
31
|
+
options?: Readonly<{ silent?: boolean }>,
|
|
32
|
+
): Promise<void> => {
|
|
29
33
|
echo('Starting index file generation...\n');
|
|
30
34
|
|
|
31
35
|
// Merge config with defaults
|
|
@@ -56,7 +60,9 @@ export const genIndex = async (config: GenIndexConfig): Promise<void> => {
|
|
|
56
60
|
|
|
57
61
|
// Step 3: Format generated files
|
|
58
62
|
echo('3. Formatting generated files...');
|
|
59
|
-
const fmtResult = await $('npm run fmt'
|
|
63
|
+
const fmtResult = await $('npm run fmt', {
|
|
64
|
+
silent: options?.silent ?? false,
|
|
65
|
+
});
|
|
60
66
|
if (Result.isErr(fmtResult)) {
|
|
61
67
|
throw new Error(`Formatting failed: ${fmtResult.value.message}`);
|
|
62
68
|
}
|