Skip to content

Commit e646270

Browse files
author
John Doe
committed
refactor: move commandLog
1 parent f1e3746 commit e646270

File tree

5 files changed

+60
-69
lines changed

5 files changed

+60
-69
lines changed

packages/nx-plugin/src/executors/cli/executor.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ export default async function runAutorunExecutor(
1515
terminalAndExecutorOptions: AutorunCommandExecutorOptions,
1616
context: ExecutorContext,
1717
): Promise<ExecutorOutput> {
18-
const { objectToCliArgs, formatCommand } = await import('@code-pushup/utils');
18+
const { objectToCliArgs, formatCommandStatus } = await import(
19+
'@code-pushup/utils'
20+
);
1921
const normalizedContext = normalizeContext(context);
2022
const cliArgumentObject = parseAutorunExecutorOptions(
2123
terminalAndExecutorOptions,
@@ -33,7 +35,7 @@ export default async function runAutorunExecutor(
3335
...(cliCommand ? [cliCommand] : []),
3436
];
3537
const args = [...positionals, ...objectToCliArgs(cliArgumentObject)];
36-
const commandString = formatCommand([command, ...args].join(' '), {
38+
const commandString = formatCommandStatus([command, ...args].join(' '), {
3739
cwd: context.cwd,
3840
});
3941
if (verbose) {

packages/utils/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ export {
8888
} from './lib/guards.js';
8989
export { interpolate } from './lib/interpolate.js';
9090
export { logMultipleResults } from './lib/log-results.js';
91-
export { Logger, logger, formatCommand } from './lib/logger.js';
91+
export { Logger, logger } from './lib/logger.js';
92+
export { formatCommandStatus } from './lib/command.js';
9293
export { mergeConfigs } from './lib/merge-configs.js';
9394
export {
9495
addIndex,

packages/utils/src/lib/command.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import ansis from 'ansis';
2+
import path from 'node:path';
3+
4+
/**
5+
* Formats a command string for display with status indicator.
6+
*
7+
* @param bin Command string with arguments.
8+
* @param options Command options (cwd, env).
9+
* @param status Command status ('pending' | 'success' | 'failure').
10+
* @returns Formatted command string with colored status indicator.
11+
*/
12+
export function formatCommandStatus(
13+
bin: string,
14+
options?: {
15+
env?: Record<string, string | number | boolean>;
16+
cwd?: string;
17+
},
18+
status: 'pending' | 'success' | 'failure' = 'pending',
19+
): string {
20+
const cwd = options?.cwd && path.relative(process.cwd(), options.cwd);
21+
const cwdPrefix = cwd ? ansis.blue(cwd) : '';
22+
const envString =
23+
options?.env && Object.keys(options.env).length > 0
24+
? Object.entries(options.env).map(([key, value]) =>
25+
ansis.gray(`${key}="${value}"`),
26+
)
27+
: [];
28+
const statusColor =
29+
status === 'pending'
30+
? ansis.blue('$')
31+
: status === 'success'
32+
? ansis.green('$')
33+
: ansis.red('$');
34+
35+
return [
36+
...(cwdPrefix ? [cwdPrefix] : []),
37+
statusColor,
38+
...envString,
39+
bin,
40+
].join(' ');
41+
}

packages/utils/src/lib/logger.unit.test.ts renamed to packages/utils/src/lib/command.unit.test.ts

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import ansis from 'ansis';
22
import path from 'node:path';
3+
import process from 'node:process';
34
import { afterEach, describe, expect, it, vi } from 'vitest';
4-
import { formatCommand } from './logger.js';
5+
import { formatCommandStatus } from './command.js';
56

67
describe('formatCommand', () => {
7-
const originalCwd = process.cwd();
8-
9-
afterEach(() => {
10-
vi.restoreAllMocks();
11-
});
12-
138
it('should format complex command with cwd, env, and status', () => {
14-
vi.spyOn(path, 'relative').mockReturnValue('<CWD>');
159
expect(
16-
formatCommand(
10+
formatCommandStatus(
1711
'npx eslint . --format=json',
1812
{
1913
cwd: '<CWD>',
@@ -32,29 +26,20 @@ describe('formatCommand', () => {
3226
['success' as const, ansis.green],
3327
['failure' as const, ansis.red],
3428
])(`should format command status %s explicitly`, (status, color) => {
35-
expect(formatCommand('npx eslint . --format=json', {}, status)).toContain(
36-
`${color('$')}`,
37-
);
38-
});
39-
40-
it('should include cwd prefix when cwd is provided and different from process.cwd()', () => {
41-
const mockCwd = path.join(originalCwd, 'src');
42-
vi.spyOn(path, 'relative').mockReturnValue('src');
43-
44-
expect(formatCommand('npx -v', { cwd: mockCwd })).toStartWith(
45-
`${ansis.blue('src')} `,
46-
);
29+
expect(
30+
formatCommandStatus('npx eslint . --format=json', {}, status),
31+
).toContain(`${color('$')}`);
4732
});
4833

4934
it('should not include cwd prefix when cwd is same as process.cwd()', () => {
5035
vi.spyOn(path, 'relative').mockReturnValue('');
51-
expect(formatCommand('npx -v', { cwd: originalCwd })).toStartWith(
36+
expect(formatCommandStatus('npx -v', { cwd: process.cwd() })).toStartWith(
5237
`${ansis.blue('$')}`,
5338
);
5439
});
5540

5641
it('should format command with multiple environment variables', () => {
57-
const result = formatCommand('npx eslint .', {
42+
const result = formatCommandStatus('npx eslint .', {
5843
env: { NODE_ENV: 'test', NODE_OPTIONS: '--import tsx' },
5944
});
6045
expect(result).toStartWith(
@@ -63,7 +48,7 @@ describe('formatCommand', () => {
6348
});
6449

6550
it('should format command with environment variable containing spaces', () => {
66-
const result = formatCommand('node packages/cli/src/index.ts', {
51+
const result = formatCommandStatus('node packages/cli/src/index.ts', {
6752
env: { NODE_OPTIONS: '--import tsx' },
6853
});
6954
expect(result).toBe(

packages/utils/src/lib/logger.ts

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ansis, { type AnsiColors } from 'ansis';
33
import os from 'node:os';
44
import path from 'node:path';
55
import ora, { type Ora } from 'ora';
6+
import { formatCommandStatus } from './command.js';
67
import { dateToUnixTimestamp } from './dates.js';
78
import { isEnvVarEnabled } from './env.js';
89
import { stringifyError } from './errors.js';
@@ -245,9 +246,9 @@ export class Logger {
245246
},
246247
): Promise<T> {
247248
return this.#spinner(worker, {
248-
pending: formatCommand(bin, options, 'pending'),
249-
success: () => formatCommand(bin, options, 'success'),
250-
failure: () => formatCommand(bin, options, 'failure'),
249+
pending: formatCommandStatus(bin, options, 'pending'),
250+
success: () => formatCommandStatus(bin, options, 'success'),
251+
failure: () => formatCommandStatus(bin, options, 'failure'),
251252
});
252253
}
253254

@@ -532,42 +533,3 @@ export class Logger {
532533
* logger.info('Made with ❤️ by Code PushUp');
533534
*/
534535
export const logger = new Logger();
535-
536-
/**
537-
* Formats a command string for display with status indicator.
538-
*
539-
* @param bin Command string with arguments.
540-
* @param options Command options (cwd, env).
541-
* @param status Command status ('pending' | 'success' | 'failure').
542-
* @returns Formatted command string with colored status indicator.
543-
*/
544-
export function formatCommand(
545-
bin: string,
546-
options?: {
547-
env?: Record<string, string | number | boolean>;
548-
cwd?: string;
549-
},
550-
status: 'pending' | 'success' | 'failure' = 'pending',
551-
): string {
552-
const cwd = options?.cwd && path.relative(process.cwd(), options.cwd);
553-
const cwdPrefix = cwd ? ansis.blue(cwd) : '';
554-
const envString =
555-
options?.env && Object.keys(options.env).length > 0
556-
? Object.entries(options.env).map(([key, value]) =>
557-
ansis.gray(`${key}="${value}"`),
558-
)
559-
: [];
560-
const statusColor =
561-
status === 'pending'
562-
? ansis.blue('$')
563-
: status === 'success'
564-
? ansis.green('$')
565-
: ansis.red('$');
566-
567-
return [
568-
...(cwdPrefix ? [cwdPrefix] : []),
569-
statusColor,
570-
...envString,
571-
bin,
572-
].join(' ');
573-
}

0 commit comments

Comments
 (0)