ts-repo-utils 2.2.2 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 (): Promise<boolean> => {
10
- const status = await getGitStatus();
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 (): Promise<void> => {
20
+ export const assertRepoIsClean = 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 (): Promise<{
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}`);
@@ -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 $('git status --porcelain');
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
- .filter((line) => line.trim() !== '')
29
- .map((line) => {
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
- `git diff --name-only ${base} ${(options?.excludeDeleted ?? true) ? '--diff-filter=d' : ''}`,
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)) {
@@ -1,8 +1,6 @@
1
- import { rm, writeFile } from 'node:fs/promises';
2
- import { join } from 'node:path';
3
1
  import { Result } from 'ts-data-forge';
4
2
  import '../node-global.mjs';
5
- import { getUntrackedFiles } from './diff.mjs';
3
+ import { getDiffFrom, getUntrackedFiles } from './diff.mjs';
6
4
 
7
5
  describe('diff', () => {
8
6
  // Use project root for test files to ensure git tracking
@@ -13,7 +11,7 @@ describe('diff', () => {
13
11
  for (const file of testFiles) {
14
12
  try {
15
13
  // eslint-disable-next-line no-await-in-loop
16
- await rm(file, { force: true });
14
+ await fs.rm(file, { force: true });
17
15
  } catch {
18
16
  // Ignore cleanup errors
19
17
  }
@@ -23,7 +21,7 @@ describe('diff', () => {
23
21
 
24
22
  describe('getUntrackedFiles', () => {
25
23
  test('should return empty array when no files are changed', async () => {
26
- const result = await getUntrackedFiles();
24
+ const result = await getUntrackedFiles({ silent: true });
27
25
 
28
26
  expect(Result.isOk(result)).toBe(true);
29
27
  if (Result.isOk(result)) {
@@ -34,84 +32,82 @@ describe('diff', () => {
34
32
  test('should detect newly created files', async () => {
35
33
  // Create a new file in project root
36
34
  const testFileName = 'test-new-file.tmp';
37
- const testFilePath = join(process.cwd(), testFileName);
35
+ const testFilePath = path.join(process.cwd(), testFileName);
38
36
  testFiles.push(testFilePath);
39
37
 
40
- await writeFile(testFilePath, 'test content');
38
+ await fs.writeFile(testFilePath, 'test content');
41
39
 
42
- const result = await getUntrackedFiles();
40
+ const result = await getUntrackedFiles({ silent: true });
43
41
 
44
42
  expect(Result.isOk(result)).toBe(true);
45
43
  if (Result.isOk(result)) {
46
44
  const files = result.value;
47
- expect(files.some((file) => file.includes(testFileName))).toBe(true);
45
+ expect(files.some((file) => file === testFileName)).toBe(true);
48
46
  }
49
47
  });
50
48
 
51
49
  test('should detect modified existing files', async () => {
52
50
  // Use an existing file in the project that we can modify safely
53
51
  const testFileName = 'test-modify-file.tmp';
54
- const testFilePath = join(process.cwd(), testFileName);
52
+ const testFilePath = path.join(process.cwd(), testFileName);
55
53
  testFiles.push(testFilePath);
56
54
 
57
55
  // Create and commit the file first
58
- await writeFile(testFilePath, 'initial content');
56
+ await fs.writeFile(testFilePath, 'initial content');
59
57
 
60
58
  // Add to git to track it
61
- await $(`git add ${testFileName}`);
59
+ await $(`git add ${testFileName}`, { silent: true });
62
60
 
63
61
  // Modify the file
64
- await writeFile(testFilePath, 'modified content');
62
+ await fs.writeFile(testFilePath, 'modified content');
65
63
 
66
- const result = await getUntrackedFiles();
64
+ const result = await getUntrackedFiles({ silent: true });
67
65
 
68
66
  expect(Result.isOk(result)).toBe(true);
69
67
  if (Result.isOk(result)) {
70
68
  const files = result.value;
71
- expect(files.some((file) => file.includes(testFileName))).toBe(true);
69
+ expect(files.some((file) => file === testFileName)).toBe(false);
72
70
  }
73
71
 
74
72
  // Reset git state
75
- await $(`git reset HEAD ${testFileName}`);
73
+ await $(`git reset HEAD ${testFileName}`, { silent: true });
76
74
  });
77
75
 
78
76
  test('should detect multiple types of changes', async () => {
79
77
  // Create multiple test files
80
- const newFile = join(process.cwd(), 'test-new-file.tmp');
81
- const modifyFile = join(process.cwd(), 'test-modify-file.tmp');
78
+ const newFile = path.join(process.cwd(), 'test-new-file.tmp');
79
+ const modifyFile = path.join(process.cwd(), 'test-modify-file.tmp');
82
80
  testFiles.push(newFile, modifyFile);
83
81
 
84
82
  // Create new file
85
- await writeFile(newFile, 'new file content');
83
+ await fs.writeFile(newFile, 'new file content');
86
84
 
87
85
  // Create and track another file
88
- await writeFile(modifyFile, 'initial content');
89
- await $(`git add test-modify-file.tmp`);
86
+ await fs.writeFile(modifyFile, 'initial content');
87
+ await $(`git add test-modify-file.tmp`, { silent: true });
90
88
 
91
89
  // Modify the tracked file
92
- await writeFile(modifyFile, 'modified content');
90
+ await fs.writeFile(modifyFile, 'modified content');
93
91
 
94
- const result = await getUntrackedFiles();
92
+ const result = await getUntrackedFiles({ silent: true });
95
93
 
96
94
  expect(Result.isOk(result)).toBe(true);
97
95
  if (Result.isOk(result)) {
98
96
  const files = result.value;
99
- expect(files.some((file) => file.includes('test-new-file.tmp'))).toBe(
100
- true,
97
+ expect(files.some((file) => file === 'test-new-file.tmp')).toBe(true);
98
+ expect(files.some((file) => file === 'test-modify-file.tmp')).toBe(
99
+ false,
101
100
  );
102
- expect(
103
- files.some((file) => file.includes('test-modify-file.tmp')),
104
- ).toBe(true);
105
101
  }
106
102
 
107
103
  // Reset git state
108
- await $(`git reset HEAD test-modify-file.tmp`);
104
+ await $(`git reset HEAD test-modify-file.tmp`, { silent: true });
109
105
  });
110
106
 
111
107
  test('should exclude deleted files from results', async () => {
112
108
  // This test is more complex as it requires simulating git state
113
109
  // For now, we'll test that the function executes successfully
114
- const result = await getUntrackedFiles();
110
+ const result = await getUntrackedFiles({ silent: true });
115
111
 
116
112
  expect(Result.isOk(result)).toBe(true);
117
113
  if (Result.isOk(result)) {
@@ -127,14 +123,14 @@ describe('diff', () => {
127
123
  test('should handle git command errors gracefully', async () => {
128
124
  // This test would require mocking git command failure
129
125
  // For now, we'll ensure the function returns a Result type
130
- const result = await getUntrackedFiles();
126
+ const result = await getUntrackedFiles({ silent: true });
131
127
 
132
128
  // Should always return a Result, either Ok or Err
133
129
  expect(Result.isOk(result) || Result.isErr(result)).toBe(true);
134
130
  });
135
131
 
136
132
  test('should parse git status output correctly', async () => {
137
- const result = await getUntrackedFiles();
133
+ const result = await getUntrackedFiles({ silent: true });
138
134
 
139
135
  expect(Result.isOk(result)).toBe(true);
140
136
  if (Result.isOk(result)) {
@@ -148,5 +144,22 @@ describe('diff', () => {
148
144
  });
149
145
  }
150
146
  });
147
+
148
+ test('should work with silent option', async () => {
149
+ const result = await getUntrackedFiles({ silent: true });
150
+
151
+ expect(Result.isOk(result)).toBe(true);
152
+ if (Result.isOk(result)) {
153
+ expect(Array.isArray(result.value)).toBe(true);
154
+ }
155
+ });
156
+ });
157
+
158
+ describe('getDiffFrom', () => {
159
+ test('should work with silent option', async () => {
160
+ const result = await getDiffFrom('HEAD~1', { silent: true });
161
+
162
+ expect(Result.isOk(result) || Result.isErr(result)).toBe(true);
163
+ });
151
164
  });
152
165
  });
@@ -16,7 +16,7 @@ export const $ = (
16
16
  const { silent = false, timeout = 30000 } = options;
17
17
 
18
18
  if (!silent) {
19
- console.log(`$ ${cmd}`);
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
- console.log(stdout);
28
+ echo(stdout);
29
29
  }
30
30
  if (stderr !== '') {
31
31
  console.error(stderr);
@@ -1,7 +1,5 @@
1
- import glob from 'fast-glob';
2
- import { readFile, writeFile } from 'node:fs/promises';
3
1
  import * as prettier from 'prettier';
4
- import { Result } from 'ts-data-forge';
2
+ import { Arr, Result } from 'ts-data-forge';
5
3
  import '../node-global.mjs';
6
4
  import { getDiffFrom, getUntrackedFiles } from './diff.mjs';
7
5
 
@@ -12,23 +10,30 @@ import { getDiffFrom, getUntrackedFiles } from './diff.mjs';
12
10
  */
13
11
  export const formatFilesList = async (
14
12
  files: readonly string[],
13
+ options?: Readonly<{ silent?: boolean }>,
15
14
  ): Promise<'ok' | 'err'> => {
15
+ const silent = options?.silent ?? false;
16
+
16
17
  if (files.length === 0) {
17
- echo('No files to format');
18
+ if (!silent) {
19
+ echo('No files to format');
20
+ }
18
21
  return 'ok';
19
22
  }
20
23
 
21
- echo(`Formatting ${files.length} files...`);
24
+ if (!silent) {
25
+ echo(`Formatting ${files.length} files...`);
26
+ }
22
27
 
23
28
  // Format each file
24
29
  const results = await Promise.allSettled(
25
30
  files.map(async (filePath) => {
26
31
  try {
27
32
  // Read file content
28
- const content = await readFile(filePath, 'utf8');
33
+ const content = await fs.readFile(filePath, 'utf8');
29
34
 
30
35
  // Resolve prettier config for this file
31
- const options = await prettier.resolveConfig(filePath);
36
+ const prettierOptions = await prettier.resolveConfig(filePath);
32
37
 
33
38
  // Check if file is ignored by prettier
34
39
  const fileInfo = await prettier.getFileInfo(filePath, {
@@ -36,20 +41,24 @@ export const formatFilesList = async (
36
41
  });
37
42
 
38
43
  if (fileInfo.ignored) {
39
- echo(`Skipping ignored file: ${filePath}`);
44
+ if (!silent) {
45
+ echo(`Skipping ignored file: ${filePath}`);
46
+ }
40
47
  return;
41
48
  }
42
49
 
43
50
  // Format the content
44
51
  const formatted = await prettier.format(content, {
45
- ...options,
52
+ ...prettierOptions,
46
53
  filepath: filePath,
47
54
  });
48
55
 
49
56
  // Only write if content changed
50
57
  if (formatted !== content) {
51
- await writeFile(filePath, formatted, 'utf8');
52
- echo(`Formatted: ${filePath}`);
58
+ await fs.writeFile(filePath, formatted, 'utf8');
59
+ if (!silent) {
60
+ echo(`Formatted: ${filePath}`);
61
+ }
53
62
  }
54
63
  } catch (error) {
55
64
  console.error(`Error formatting ${filePath}:`, error);
@@ -68,7 +77,12 @@ export const formatFilesList = async (
68
77
  * @param pathGlob - Glob pattern to match files
69
78
  * @returns 'ok' if successful, 'err' if any errors occurred
70
79
  */
71
- export const formatFiles = async (pathGlob: string): Promise<'ok' | 'err'> => {
80
+ export const formatFiles = async (
81
+ pathGlob: string,
82
+ options?: Readonly<{ silent?: boolean }>,
83
+ ): Promise<'ok' | 'err'> => {
84
+ const silent = options?.silent ?? false;
85
+
72
86
  try {
73
87
  // Find all files matching the glob
74
88
  const files = await glob(pathGlob, {
@@ -78,11 +92,13 @@ export const formatFiles = async (pathGlob: string): Promise<'ok' | 'err'> => {
78
92
  });
79
93
 
80
94
  if (files.length === 0) {
81
- echo('No files found matching pattern:', pathGlob);
95
+ if (!silent) {
96
+ echo('No files found matching pattern:', pathGlob);
97
+ }
82
98
  return 'ok';
83
99
  }
84
100
 
85
- return await formatFilesList(files);
101
+ return await formatFilesList(files, { silent });
86
102
  } catch (error) {
87
103
  console.error('Error in formatFiles:', error);
88
104
  return 'err';
@@ -91,11 +107,18 @@ export const formatFiles = async (pathGlob: string): Promise<'ok' | 'err'> => {
91
107
 
92
108
  /**
93
109
  * Format only files that have been changed (git status)
110
+ * @param options - Options for formatting
94
111
  * @returns 'ok' if successful, 'err' if any errors occurred
95
112
  */
96
- export const formatUntracked = async (): Promise<'ok' | 'err'> => {
113
+ export const formatUntracked = async (
114
+ options?: Readonly<{ silent?: boolean }>,
115
+ ): Promise<'ok' | 'err'> => {
116
+ const silent = options?.silent ?? false;
117
+
97
118
  try {
98
- const untrackedFilesResult = await getUntrackedFiles();
119
+ const untrackedFilesResult = await getUntrackedFiles({
120
+ silent,
121
+ });
99
122
 
100
123
  if (Result.isErr(untrackedFilesResult)) {
101
124
  console.error('Error getting changed files:', untrackedFilesResult.value);
@@ -105,20 +128,26 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
105
128
  const files = untrackedFilesResult.value;
106
129
 
107
130
  if (files.length === 0) {
108
- echo('No changed files to format');
131
+ if (!silent) {
132
+ echo('No changed files to format');
133
+ }
109
134
  return 'ok';
110
135
  }
111
136
 
112
- echo('Formatting changed files:', files);
137
+ if (!silent) {
138
+ echo('Formatting changed files:', files);
139
+ }
113
140
 
114
141
  // Filter out non-existent files before formatting
115
142
  const fileExistenceChecks = await Promise.allSettled(
116
143
  files.map(async (filePath) => {
117
144
  try {
118
- await readFile(filePath, 'utf8');
145
+ await fs.readFile(filePath, 'utf8');
119
146
  return filePath;
120
147
  } catch {
121
- echo(`Skipping non-existent file: ${filePath}`);
148
+ if (!silent) {
149
+ echo(`Skipping non-existent file: ${filePath}`);
150
+ }
122
151
  return undefined;
123
152
  }
124
153
  }),
@@ -131,7 +160,7 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
131
160
  )
132
161
  .map((result) => result.value);
133
162
 
134
- return await formatFilesList(existingFiles);
163
+ return await formatFilesList(existingFiles, { silent });
135
164
  } catch (error) {
136
165
  console.error('Error in formatUntracked:', error);
137
166
  return 'err';
@@ -143,15 +172,20 @@ export const formatUntracked = async (): Promise<'ok' | 'err'> => {
143
172
  * @param base - Base branch name or commit hash to compare against (defaults to 'main')
144
173
  * @param options - Options for formatting
145
174
  * @param options.includeUntracked - Include untracked files in addition to diff files (default is true)
175
+ * @param options.silent - Silent mode to suppress command output (default is false)
146
176
  * @returns 'ok' if successful, 'err' if any errors occurred
147
177
  */
148
178
  export const formatDiffFrom = async (
149
179
  base: string,
150
- options?: Readonly<{ includeUntracked?: boolean }>,
180
+ options?: Readonly<{ includeUntracked?: boolean; silent?: boolean }>,
151
181
  ): Promise<'ok' | 'err'> => {
182
+ const silent = options?.silent ?? false;
183
+
152
184
  try {
153
185
  // Get files that differ from base branch/commit (excluding deleted files)
154
- const diffFromBaseResult = await getDiffFrom(base);
186
+ const diffFromBaseResult = await getDiffFrom(base, {
187
+ silent,
188
+ });
155
189
 
156
190
  if (Result.isErr(diffFromBaseResult)) {
157
191
  console.error('Error getting changed files:', diffFromBaseResult.value);
@@ -159,11 +193,13 @@ export const formatDiffFrom = async (
159
193
  }
160
194
 
161
195
  const diffFiles = diffFromBaseResult.value;
162
- let allFiles = diffFiles;
196
+ let mut_allFiles = diffFiles;
163
197
 
164
198
  // If includeUntracked is true, also get untracked files
165
199
  if (options?.includeUntracked ?? true) {
166
- const untrackedFilesResult = await getUntrackedFiles();
200
+ const untrackedFilesResult = await getUntrackedFiles({
201
+ silent,
202
+ });
167
203
 
168
204
  if (Result.isErr(untrackedFilesResult)) {
169
205
  console.error(
@@ -176,23 +212,28 @@ export const formatDiffFrom = async (
176
212
  const untrackedFiles = untrackedFilesResult.value;
177
213
 
178
214
  // Combine and deduplicate files
179
- const uniqueFiles = new Set([...diffFiles, ...untrackedFiles]);
180
- allFiles = Array.from(uniqueFiles);
215
+ mut_allFiles = Arr.uniq([...diffFiles, ...untrackedFiles]);
181
216
 
182
- echo(
183
- `Formatting files that differ from ${base} and untracked files:`,
184
- allFiles,
185
- );
217
+ if (!silent) {
218
+ echo(
219
+ `Formatting files that differ from ${base} and untracked files:`,
220
+ mut_allFiles,
221
+ );
222
+ }
186
223
  } else {
187
- echo(`Formatting files that differ from ${base}:`, allFiles);
224
+ if (!silent) {
225
+ echo(`Formatting files that differ from ${base}:`, mut_allFiles);
226
+ }
188
227
  }
189
228
 
190
- if (allFiles.length === 0) {
191
- echo(`No files to format`);
229
+ if (mut_allFiles.length === 0) {
230
+ if (!silent) {
231
+ echo(`No files to format`);
232
+ }
192
233
  return 'ok';
193
234
  }
194
235
 
195
- return await formatFilesList(allFiles);
236
+ return await formatFilesList(mut_allFiles, { silent });
196
237
  } catch (error) {
197
238
  console.error('Error in formatDiffFrom:', error);
198
239
  return 'err';
@@ -1,7 +1,6 @@
1
1
  import dedent from 'dedent';
2
- import * as fs from 'node:fs/promises';
3
- import * as path from 'node:path';
4
2
  import { Result } from 'ts-data-forge';
3
+ import '../node-global.mjs';
5
4
  import { getDiffFrom, getUntrackedFiles } from './diff.mjs';
6
5
  import { formatDiffFrom, formatFiles, formatFilesList } from './format.mjs';
7
6
 
@@ -54,7 +53,7 @@ describe('formatFiles', () => {
54
53
  await createTestFile('test.md', '# Test\n\nSome spaces');
55
54
 
56
55
  // Format TypeScript files
57
- const result = await formatFiles(`${testDir}/*.ts`);
56
+ const result = await formatFiles(`${testDir}/*.ts`, { silent: true });
58
57
  expect(result).toBe('ok');
59
58
 
60
59
  // Check that files were formatted
@@ -85,7 +84,9 @@ describe('formatFiles', () => {
85
84
  });
86
85
 
87
86
  test('should return ok when no files match pattern', async () => {
88
- const result = await formatFiles('/non-existent-path/*.ts');
87
+ const result = await formatFiles('/non-existent-path/*.ts', {
88
+ silent: true,
89
+ });
89
90
  expect(result).toBe('ok');
90
91
  });
91
92
 
@@ -103,7 +104,9 @@ describe('formatFiles', () => {
103
104
  );
104
105
 
105
106
  // Format with recursive glob
106
- const result = await formatFiles(`${testDir}/**/*.ts`);
107
+ const result = await formatFiles(`${testDir}/**/*.ts`, {
108
+ silent: true,
109
+ });
107
110
  expect(result).toBe('ok');
108
111
 
109
112
  // Check that nested file was formatted
@@ -159,7 +162,9 @@ describe('formatFilesList', () => {
159
162
  );
160
163
 
161
164
  // Format the files
162
- const result = await formatFilesList([file1, file2]);
165
+ const result = await formatFilesList([file1, file2], {
166
+ silent: true,
167
+ });
163
168
  expect(result).toBe('ok');
164
169
 
165
170
  // Check formatted content
@@ -184,7 +189,9 @@ describe('formatFilesList', () => {
184
189
  });
185
190
 
186
191
  test('should return ok for empty file list', async () => {
187
- const result = await formatFilesList([]);
192
+ const result = await formatFilesList([], {
193
+ silent: true,
194
+ });
188
195
  expect(result).toBe('ok');
189
196
  });
190
197
  });
@@ -224,7 +231,7 @@ describe('formatDiffFrom', () => {
224
231
 
225
232
  vi.mocked(getUntrackedFiles).mockResolvedValue(Result.ok([]));
226
233
 
227
- const result = await formatDiffFrom('main');
234
+ const result = await formatDiffFrom('main', { silent: true });
228
235
  expect(result).toBe('ok');
229
236
 
230
237
  // Check file was formatted
@@ -236,7 +243,7 @@ describe('formatDiffFrom', () => {
236
243
  `}\n`,
237
244
  );
238
245
 
239
- expect(getDiffFrom).toHaveBeenCalledWith('main');
246
+ expect(getDiffFrom).toHaveBeenCalledWith('main', { silent: true });
240
247
  } finally {
241
248
  await fs.rm(testDir, { recursive: true, force: true });
242
249
  }
@@ -266,7 +273,10 @@ describe('formatDiffFrom', () => {
266
273
  Result.ok([untrackedFile]),
267
274
  );
268
275
 
269
- const result = await formatDiffFrom('main', { includeUntracked: true });
276
+ const result = await formatDiffFrom('main', {
277
+ includeUntracked: true,
278
+ silent: true,
279
+ });
270
280
  expect(result).toBe('ok');
271
281
 
272
282
  // Check both files were formatted
@@ -284,8 +294,8 @@ describe('formatDiffFrom', () => {
284
294
  `}\n`,
285
295
  );
286
296
 
287
- expect(getDiffFrom).toHaveBeenCalledWith('main');
288
- expect(getUntrackedFiles).toHaveBeenCalled();
297
+ expect(getDiffFrom).toHaveBeenCalledWith('main', { silent: true });
298
+ expect(getUntrackedFiles).toHaveBeenCalledWith({ silent: true });
289
299
  } finally {
290
300
  await fs.rm(testDir, { recursive: true, force: true });
291
301
  }
@@ -306,12 +316,15 @@ describe('formatDiffFrom', () => {
306
316
  vi.mocked(getDiffFrom).mockResolvedValue(Result.ok([sharedFile]));
307
317
  vi.mocked(getUntrackedFiles).mockResolvedValue(Result.ok([sharedFile]));
308
318
 
309
- const result = await formatDiffFrom('main', { includeUntracked: true });
319
+ const result = await formatDiffFrom('main', {
320
+ includeUntracked: true,
321
+ silent: true,
322
+ });
310
323
  expect(result).toBe('ok');
311
324
 
312
325
  // Verify both functions were called
313
- expect(getDiffFrom).toHaveBeenCalledWith('main');
314
- expect(getUntrackedFiles).toHaveBeenCalled();
326
+ expect(getDiffFrom).toHaveBeenCalledWith('main', { silent: true });
327
+ expect(getUntrackedFiles).toHaveBeenCalledWith({ silent: true });
315
328
 
316
329
  // Check that the file was formatted (content should change)
317
330
  const finalContent = await readTestFile(sharedFile);