Skip to content

Commit

Permalink
feat(cli): add --persist.filename cli option (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
BioPhoton authored Nov 10, 2023
1 parent a32f433 commit 296df7d
Show file tree
Hide file tree
Showing 31 changed files with 404 additions and 216 deletions.
13 changes: 12 additions & 1 deletion e2e/cli-e2e/mocks/fs.mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { mkdirSync, rmSync, writeFileSync } from 'fs';
import { join } from 'path';
import { ensureDirectoryExists } from '@code-pushup/utils';

// @TODO move into testing library
export function cleanFolder<T extends object>(
dirName = 'tmp',
content?: { [key in keyof T]: string },
Expand All @@ -13,7 +15,7 @@ export function cleanFolder<T extends object>(
}
}
}

// @TODO move into testing library
export function cleanFolderPutGitKeep<T extends object>(
dirName = 'tmp',
content?: { [key in keyof T]: string },
Expand All @@ -27,3 +29,12 @@ export function cleanFolderPutGitKeep<T extends object>(
}
}
}

export function setupFolder(dirName = 'tmp', content?: Record<string, string>) {
ensureDirectoryExists(dirName);
if (content) {
for (const fileName in content) {
writeFileSync(join(dirName, fileName), content[fileName]);
}
}
}
34 changes: 34 additions & 0 deletions e2e/cli-e2e/mocks/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// @TODO move logic into testing library
import { join } from 'path';
import {
CliArgsObject,
ProcessConfig,
executeProcess,
objectToCliArgs,
} from '@code-pushup/utils';

export const extensions = ['js', 'mjs', 'ts'] as const;
export type Extension = (typeof extensions)[number];

export const configFile = (ext: Extension = 'ts') =>
join(process.cwd(), `e2e/cli-e2e/mocks/code-pushup.config.${ext}`);

export const execCli = (
command: string,
argObj: Partial<CliArgsObject>,
processOptions?: Omit<ProcessConfig, 'args' | 'command' | 'observer'>,
) =>
executeProcess({
command: 'npx',
args: [
'./dist/packages/cli',
command,
...objectToCliArgs({
verbose: true,
progress: false,
config: configFile(),
...argObj,
}),
],
...processOptions,
});
1 change: 1 addition & 0 deletions e2e/cli-e2e/tests/__snapshots__/help.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Options:
--config Path the the config file, e.g. code-pushup.config.j
s [string] [default: \\"code-pushup.config.js\\"]
--persist.outputDir Directory for the produced reports [string]
--persist.filename Filename for the produced reports. [string]
--persist.format Format of the report output. e.g. \`md\`, \`json\`, \`st
dout\` [array]
--upload.organization Organization slug from portal [string]
Expand Down
44 changes: 13 additions & 31 deletions e2e/cli-e2e/tests/print-config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,21 @@
import { join } from 'path';
import { expect } from 'vitest';
import {
CliArgsObject,
executeProcess,
objectToCliArgs,
} from '@code-pushup/utils';
import { CliArgsObject } from '@code-pushup/utils';
import { configFile, execCli, extensions } from '../mocks/utils';

const extensions = ['js', 'mjs', 'ts'] as const;
type Extension = (typeof extensions)[number];

const configFile = (ext: Extension) =>
join(process.cwd(), `e2e/cli-e2e/mocks/code-pushup.config.${ext}`);

const execCli = (argObj: Partial<CliArgsObject>) =>
executeProcess({
command: 'npx',
args: [
'./dist/packages/cli',
'print-config',
...objectToCliArgs({
verbose: true,
...argObj,
}),
],
});
const execCliPrintConfig = (argObj: Partial<CliArgsObject>) =>
execCli('print-config', argObj);

describe('print-config', () => {
it.each(extensions)('should load .%s config file', async ext => {
const { code, stderr, stdout } = await execCli({ config: configFile(ext) });
const { code, stderr, stdout } = await execCliPrintConfig({
config: configFile(ext),
});
expect(code).toBe(0);
expect(stderr).toBe('');
const args = JSON.parse(stdout);
expect(args).toEqual({
progress: true,
progress: false,
verbose: true,
config: expect.stringContaining(`code-pushup.config.${ext}`),
upload: {
Expand All @@ -51,14 +34,14 @@ describe('print-config', () => {
});

it('should load .ts config file and merge cli arguments', async () => {
const { code, stderr, stdout } = await execCli({
config: configFile('ts'),
const { code, stderr, stdout } = await execCliPrintConfig({
'persist.filename': 'my-report',
});
expect(code).toBe(0);
expect(stderr).toBe('');
const args = JSON.parse(stdout);
expect(args).toEqual({
progress: true,
progress: false,
verbose: true,
config: expect.stringContaining(`code-pushup.config.ts`),
upload: {
Expand All @@ -69,16 +52,15 @@ describe('print-config', () => {
},
persist: {
outputDir: join('tmp', 'ts'),
filename: 'report',
filename: 'my-report',
},
plugins: expect.any(Array),
categories: expect.any(Array),
});
});

it('should parse persist.format from arguments', async () => {
const { code, stderr, stdout } = await execCli({
config: configFile('ts'),
const { code, stderr, stdout } = await execCliPrintConfig({
'persist.format': ['md', 'json', 'stdout'],
});
expect(code).toBe(0);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lib/autorun/command-object.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ vi.mock('@code-pushup/portal-client', async () => {
),
};
});

const baseArgs = [
'autorun',
...objectToCliArgs({
Expand Down Expand Up @@ -70,6 +69,7 @@ describe('autorun-command-object', () => {
...baseArgs,
...objectToCliArgs({
'persist.format': 'md',
'persist.filename': 'my-report',
'upload.apiKey': 'some-other-api-key',
'upload.server': 'https://other-example.com/api',
}),
Expand Down
12 changes: 5 additions & 7 deletions packages/cli/src/lib/collect/command-object.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import { CollectAndPersistReportsOptions } from '@code-pushup/core';
import { objectToCliArgs } from '@code-pushup/utils';
import {
cleanFolderPutGitKeep,
mockConsole,
unmockConsole,
} from '../../../test';
import { mockConsole, unmockConsole } from '../../../test';
import { DEFAULT_CLI_CONFIGURATION } from '../../../test/constants';
import { yargsCli } from '../yargs-cli';
import { yargsCollectCommandObject } from './command-object';

const getFilename = () => 'report';
const baseArgs = [
...objectToCliArgs({
progress: false,
Expand All @@ -36,21 +33,22 @@ describe('collect-command-object', () => {

beforeEach(() => {
logs = [];
cleanFolderPutGitKeep();
mockConsole((...args: unknown[]) => {
logs.push(...args);
});
});
afterEach(() => {
cleanFolderPutGitKeep();
logs = [];
unmockConsole();
});

it('should override config with CLI arguments', async () => {
const filename = getFilename();
const args = [
...baseArgs,
...objectToCliArgs({
'persist.format': 'md',
'persist.filename': filename,
}),
];
const parsedArgv = (await cli(
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/lib/implementation/core-config-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function yargsCoreConfigOptionsDefinition(): Record<ArgNames, Options> {
describe: 'Directory for the produced reports',
type: 'string',
},
'persist.filename': {
describe: 'Filename for the produced reports.',
type: 'string',
},
'persist.format': {
describe: 'Format of the report output. e.g. `md`, `json`, `stdout`',
type: 'array',
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/lib/implementation/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type GeneralCliOptions = GlobalOptions;

export type CoreConfigCliOptions = {
'persist.outputDir': string;
'persist.filename': string;
'persist.format': Format | string;
'upload.organization': string;
'upload.project': string;
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/lib/print-config/command-object.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('print-config-command-object', () => {
it('should print existing config', async () => {
const parsedArgv = await cli(baseArgs).parseAsync();
expect(parsedArgv.persist.outputDir).toBe('tmp');
expect(parsedArgv.persist.filename).toBe('report');
expect(parsedArgv.persist.format).toBeUndefined();
expect(parsedArgv.upload?.organization).toBe('code-pushup');
expect(parsedArgv.upload?.project).toBe('cli');
Expand All @@ -43,6 +44,7 @@ describe('print-config-command-object', () => {
const overrides = {
'persist.outputDir': 'custom/output/dir',
'persist.format': ['md'],
'persist.filename': 'custom-report-filename',
'upload.organization': 'custom-org',
'upload.project': 'custom-project',
'upload.apiKey': 'custom-api-key',
Expand All @@ -52,6 +54,7 @@ describe('print-config-command-object', () => {

const parsedArgv = await cli(args).parseAsync();
expect(parsedArgv.persist.outputDir).toBe(overrides['persist.outputDir']);
expect(parsedArgv.persist.filename).toBe('custom-report-filename');
expect(parsedArgv.persist.format).toEqual(overrides['persist.format']);
expect(parsedArgv.upload?.organization).toEqual(
overrides['upload.organization'],
Expand Down
29 changes: 17 additions & 12 deletions packages/cli/src/lib/upload/command-object.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { UploadOptions } from '@code-pushup/core';
import { report } from '@code-pushup/models/testing';
import { CliArgsObject, objectToCliArgs } from '@code-pushup/utils';
import { cleanFolderPutGitKeep } from '../../../test';
import { setupFolder } from '../../../test';
import { DEFAULT_CLI_CONFIGURATION } from '../../../test/constants';
import { yargsCli } from '../yargs-cli';
import { yargsUploadCommandObject } from './command-object';
Expand All @@ -26,7 +26,9 @@ vi.mock('@code-pushup/portal-client', async () => {
),
};
});
const dummyReport = report();

// @TODO move into test library
const baseArgs = [
'upload',
...objectToCliArgs({
Expand All @@ -47,22 +49,15 @@ const cli = (args: string[]) =>
commands: [yargsUploadCommandObject()],
});

const reportFile = (format: 'json' | 'md' = 'json') => 'report.' + format;
const dummyReport = report();

describe('upload-command-object', () => {
beforeEach(async () => {
vi.clearAllMocks();
cleanFolderPutGitKeep('tmp', {
[reportFile()]: JSON.stringify(dummyReport),
});
});

afterEach(async () => {
cleanFolderPutGitKeep('tmp');
});

it('should override config with CLI arguments', async () => {
setupFolder('tmp', {
['report.json']: JSON.stringify(dummyReport),
});
const args = [
...baseArgs,
...objectToCliArgs<CliArgsObject>({
Expand All @@ -82,7 +77,17 @@ describe('upload-command-object', () => {
});

it('should call portal-client function with correct parameters', async () => {
await cli(baseArgs).parseAsync();
const reportFileName = 'my-report';
setupFolder('tmp', {
[reportFileName + '.json']: JSON.stringify(dummyReport),
});
const args = [
...baseArgs,
...objectToCliArgs<CliArgsObject>({
'persist.filename': reportFileName,
}),
];
await cli(args).parseAsync();
expect(uploadToPortal).toHaveBeenCalledWith({
apiKey: 'dummy-api-key',
server: 'https://example.com/api',
Expand Down
22 changes: 4 additions & 18 deletions packages/cli/test/fs.mock.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
import { mkdirSync, rmSync, writeFileSync } from 'fs';
import { writeFileSync } from 'fs';
import { join } from 'path';
import { ensureDirectoryExists } from '@code-pushup/utils';

export function cleanFolder<T extends object>(
export async function setupFolder<T extends object>(
dirName = 'tmp',
content?: { [key in keyof T]: string },
) {
rmSync(dirName, { recursive: true, force: true });
mkdirSync(dirName, { recursive: true });
if (content) {
for (const fileName in content) {
writeFileSync(join(dirName, fileName), content[fileName]);
}
}
}

export function cleanFolderPutGitKeep<T extends object>(
dirName = 'tmp',
content?: { [key in keyof T]: string },
) {
rmSync(dirName, { recursive: true, force: true });
mkdirSync(dirName, { recursive: true });
writeFileSync(join(dirName, '.gitkeep'), '');
await ensureDirectoryExists(dirName);
if (content) {
for (const fileName in content) {
writeFileSync(join(dirName, fileName), content[fileName]);
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export {
logPersistedResults,
persistReport,
PersistError,
PersistDirError,
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/lib/collect-and-persist.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ vi.mock('@code-pushup/portal-client', async () => {
});

const outputDir = 'tmp';
const reportPath = (path = outputDir, format: 'json' | 'md' = 'json') =>
join(path, 'report.' + format);
const reportPath = (format: 'json' | 'md' = 'json') =>
join(outputDir, `report.${format}`);

describe('collectAndPersistReports', () => {
beforeEach(async () => {
Expand All @@ -34,9 +34,10 @@ describe('collectAndPersistReports', () => {
});

it('should work', async () => {
const cfg = minimalConfig(outputDir);
await collectAndPersistReports({
...DEFAULT_TESTING_CLI_OPTIONS,
...minimalConfig(outputDir),
...cfg,
});
const result = JSON.parse(readFileSync(reportPath()).toString()) as Report;
expect(result.plugins[0]?.audits[0]?.slug).toBe('audit-1');
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/lib/implementation/persist.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
FOOTER_PREFIX,
README_LINK,
} from '@code-pushup/utils';
import { mockConsole, unmockConsole } from '../../../test/console.mock';
import { mockConsole, unmockConsole } from '../../../test';
import { logPersistedResults, persistReport } from './persist';

// Mock file system API's
Expand Down
Loading

0 comments on commit 296df7d

Please sign in to comment.