Skip to content
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ describe('executor command', () => {
`${project}:code-pushup`,
'collect',
'--persist.filename=terminal-report',
'--verbose',
],
cwd,
});
Expand Down
9 changes: 5 additions & 4 deletions e2e/nx-plugin-e2e/tests/plugin-create-nodes.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,14 @@ describe('nx-plugin', () => {
});

const cleanStdout = removeColorCodes(stdout);

// Nx command
expect(cleanStdout).toContain('nx run my-lib:code-pushup');
expect(cleanStdout).toContain('nx run my-lib:code-pushup --dryRun');
// Run CLI executor
expect(cleanStdout).toContain('Command:');
expect(cleanStdout).toContain('DryRun execution of:');
expect(cleanStdout).toContain('npx @code-pushup/cli');
expect(cleanStdout).toContain('--verbose');
expect(cleanStdout).toContain('--dryRun ');
expect(cleanStdout).not.toContain('--verbose');
expect(cleanStdout).toContain('CP_VERBOSE="true"');
});

it('should consider plugin option bin in executor target', async () => {
Expand Down
11 changes: 11 additions & 0 deletions packages/nx-plugin/src/executors/cli/executor.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ describe('runAutorunExecutor', () => {
});

it('should normalize context, parse CLI options and execute command', async () => {
expect(process.env).toStrictEqual(
expect.not.objectContaining({
CP_VERBOSE: 'true',
}),
);
const output = await runAutorunExecutor(
{ verbose: true },
executorContext('utils'),
Expand All @@ -48,5 +53,11 @@ describe('runAutorunExecutor', () => {
args: expect.arrayContaining(['@code-pushup/cli']),
cwd: process.cwd(),
});

expect(process.env).toStrictEqual(
expect.objectContaining({
CP_VERBOSE: 'true',
}),
);
});
});
31 changes: 15 additions & 16 deletions packages/nx-plugin/src/executors/cli/executor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ExecutorContext, logger } from '@nx/devkit';
import type { ExecutorContext } from '@nx/devkit';
import { executeProcess } from '../../internal/execute-process.js';
import { normalizeContext } from '../internal/context.js';
import type { AutorunCommandExecutorOptions } from './schema.js';
Expand All @@ -15,44 +15,43 @@ export default async function runAutorunExecutor(
terminalAndExecutorOptions: AutorunCommandExecutorOptions,
context: ExecutorContext,
): Promise<ExecutorOutput> {
const { objectToCliArgs, formatCommandStatus } = await import(
'@code-pushup/utils'
);
const { objectToCliArgs, formatCommandStatus, logger, stringifyError } =
await import('@code-pushup/utils');
const normalizedContext = normalizeContext(context);
const cliArgumentObject = parseAutorunExecutorOptions(
terminalAndExecutorOptions,
normalizedContext,
);
const {
dryRun,
verbose,
command: cliCommand,
bin,
} = terminalAndExecutorOptions;
const { command: cliCommand } = terminalAndExecutorOptions;
const { verbose = false, dryRun, bin, ...restArgs } = cliArgumentObject;
logger.setVerbose(verbose);

const command = bin ? `node` : 'npx';
const positionals = [
bin ?? '@code-pushup/cli',
...(cliCommand ? [cliCommand] : []),
];
const args = [...positionals, ...objectToCliArgs(cliArgumentObject)];
const args = [...positionals, ...objectToCliArgs(restArgs)];
const executorEnvVariables = {
...(verbose && { CP_VERBOSE: 'true' }),
};
const commandString = formatCommandStatus([command, ...args].join(' '), {
cwd: context.cwd,
env: executorEnvVariables,
});
if (verbose) {
logger.info(`Run CLI executor ${command ?? ''}`);
logger.info(`Command: ${commandString}`);
}

if (dryRun) {
logger.warn(`DryRun execution of: ${commandString}`);
} else {
try {
logger.debug(`With env vars: ${executorEnvVariables}`);
await executeProcess({
command,
args,
...(context.cwd ? { cwd: context.cwd } : {}),
});
} catch (error) {
logger.error(error);
logger.error(stringifyError(error));
return {
success: false,
command: commandString,
Expand Down
59 changes: 41 additions & 18 deletions packages/nx-plugin/src/executors/cli/executor.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { logger } from '@nx/devkit';
import { afterAll, afterEach, beforeEach, expect, vi } from 'vitest';
import { executorContext } from '@code-pushup/test-nx-utils';
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
Expand All @@ -9,9 +8,8 @@ describe('runAutorunExecutor', () => {
const processEnvCP = Object.fromEntries(
Object.entries(process.env).filter(([k]) => k.startsWith('CP_')),
);
const loggerInfoSpy = vi.spyOn(logger, 'info');
const loggerWarnSpy = vi.spyOn(logger, 'warn');
const executeProcessSpy = vi.spyOn(executeProcessModule, 'executeProcess');
let logger: import('@code-pushup/utils').Logger;

beforeAll(() => {
Object.entries(process.env)
Expand All @@ -25,7 +23,9 @@ describe('runAutorunExecutor', () => {
);
});

beforeEach(() => {
beforeEach(async () => {
const utils = await import('@code-pushup/utils');
logger = utils.logger;
vi.unstubAllEnvs();
executeProcessSpy.mockResolvedValue({
bin: 'npx ...',
Expand All @@ -37,8 +37,6 @@ describe('runAutorunExecutor', () => {
});

afterEach(() => {
loggerWarnSpy.mockReset();
loggerInfoSpy.mockReset();
executeProcessSpy.mockReset();
});

Expand Down Expand Up @@ -108,30 +106,55 @@ describe('runAutorunExecutor', () => {
expect(output.command).toMatch('--upload.project="CLI"');
});

it('should log information if verbose is set', async () => {
it('should set env var information if verbose is set', async () => {
const output = await runAutorunExecutor(
{ verbose: true },
{
verbose: true,
},
{ ...executorContext('github-action'), cwd: '<CWD>' },
);

expect(executeProcessSpy).toHaveBeenCalledTimes(1);
expect(executeProcessSpy).toHaveBeenCalledWith({
command: 'npx',
args: expect.arrayContaining(['@code-pushup/cli']),
cwd: '<CWD>',
});

expect(output.command).toMatch('--verbose');
expect(loggerWarnSpy).toHaveBeenCalledTimes(0);
expect(loggerInfoSpy).toHaveBeenCalledTimes(2);
expect(loggerInfoSpy).toHaveBeenCalledWith(
expect.stringContaining(`Run CLI executor`),
expect(process.env).toStrictEqual(
expect.objectContaining({
CP_VERBOSE: 'true',
}),
);
expect(loggerInfoSpy).toHaveBeenCalledWith(
expect.stringContaining('Command:'),

expect(output.command).not.toContain('--verbose');
expect(logger.warn).toHaveBeenCalledTimes(0);
});

it('should log env var in dryRun information if verbose is set', async () => {
const output = await runAutorunExecutor(
{
dryRun: true,
verbose: true,
},
{ ...executorContext('github-action'), cwd: '<CWD>' },
);

expect(executeProcessSpy).toHaveBeenCalledTimes(0);

expect(output.command).not.toContain('--verbose');
expect(logger.warn).toHaveBeenCalledTimes(1);
expect(logger.warn).toHaveBeenCalledWith(
expect.stringContaining('CP_VERBOSE="true"'),
);
});

it('should log command if dryRun is set', async () => {
await runAutorunExecutor({ dryRun: true }, executorContext('utils'));

expect(loggerInfoSpy).toHaveBeenCalledTimes(0);
expect(loggerWarnSpy).toHaveBeenCalledTimes(1);
expect(loggerWarnSpy).toHaveBeenCalledWith(
expect(logger.command).toHaveBeenCalledTimes(0);
expect(logger.warn).toHaveBeenCalledTimes(1);
expect(logger.warn).toHaveBeenCalledWith(
expect.stringContaining('DryRun execution of'),
);
});
Expand Down
Loading