Skip to content

Commit

Permalink
Merge pull request #1038 from contentstack/feat/CS-41075
Browse files Browse the repository at this point in the history
Feat: [CS-41075] cm:stacks:audit command for Content type
  • Loading branch information
antonyagustine authored Sep 14, 2023
2 parents 15cedcc + d0de43d commit a1a828d
Show file tree
Hide file tree
Showing 14 changed files with 583 additions and 16 deletions.
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/contentstack-audit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"-v"
],
"topics": {
"cm:audit": {
"cm:stacks:audit": {
"description": "Audit and find possible refrence errors in the exported data"
}
},
Expand Down
9 changes: 7 additions & 2 deletions packages/contentstack-audit/src/base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ export abstract class BaseCommand<T extends typeof Command> extends Command {
public log!: LogFn;
public logger!: Logger;
public readonly $t = $t;
protected sharedConfig: ConfigType = config;
protected sharedConfig: ConfigType = {
...config,
basePath: process.cwd(),
};
readonly messages: typeof messages = messages;

protected args!: Args<T>;
Expand All @@ -28,7 +31,7 @@ export abstract class BaseCommand<T extends typeof Command> extends Command {
}),
'data-dir': Flags.string({
char: 'd',
description: commonMsg.CURRENT_WORKING_DIR,
description: commonMsg.DATA_DIR,
}),
};

Expand All @@ -47,6 +50,8 @@ export abstract class BaseCommand<T extends typeof Command> extends Command {
this.flags = flags as Flags<T>;
this.args = args as Args<T>;

this.sharedConfig = Object.assign(this.sharedConfig, { flags: this.flags });

ux.registerSearchPlugin();
this.registerConfig();

Expand Down
101 changes: 98 additions & 3 deletions packages/contentstack-audit/src/commands/cm/stacks/audit/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,108 @@
import { resolve } from 'path';
import chalk from 'chalk';
import { FlagInput, Flags, cliux, ux } from '@contentstack/cli-utilities';

import config from '../../../../config';
import { auditMsg } from '../../../../messages';
import { BaseCommand } from '../../../../base-command';
import ContentType from '../../../../modules/content-types';

export default class Audit extends BaseCommand<typeof Audit> {
static aliases: string[] = ['cm:stacks:audit'];

static description = 'Audit and find possible errors in the exported data';

static examples = ['$ <%= config.bin %> <%= command.id %>'];
static examples = [
'$ <%= config.bin %> <%= command.id %>',
'$ <%= config.bin %> <%= command.id %> --report-path=<path>',
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --csv',
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --filter="name=<filter-value>"',
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --modules=content-types --filter="name="<filter-value>"',
];

static flags: FlagInput = {
'report-path': Flags.string({
description: auditMsg.REPORT_PATH,
}),
'reference-only': Flags.boolean({
description: auditMsg.REFERENCE_ONLY,
}),
modules: Flags.string({
multiple: true,
options: config.modules,
description: auditMsg.MODULES,
}),
...ux.table.flags({
only: ['columns', 'sort', 'filter', 'csv', 'no-truncate'],
}),
};

async run(): Promise<void> {
try {
const { flags } = await this.parse(Audit);

await this.promptQueue();
const reportPath = this.flags['report-path'] || process.cwd();
this.sharedConfig.reportPath = resolve(reportPath, 'audit-report');

static flags = {};
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
switch (module) {
case 'content-types':
const ctErrors = await new ContentType({ config: this.sharedConfig, log: this.log }).run();
ux.table(
Object.values(ctErrors).flat(),
{
name: {
minWidth: 7,
header: 'Content Type name',
},
display_name: {
minWidth: 7,
header: 'Field name',
},
data_type: {
minWidth: 7,
header: 'Field type',
},
missingRefs: {
minWidth: 7,
header: 'Missing references',
get: (row) => {
return chalk.red(row.missingRefs);
},
},
treeStr: {
minWidth: 7,
header: 'Path',
},
},
{
...flags,
},
);
this.log(''); // NOTE add new line in terminal
this.log(''); // NOTE add new line in terminal
break;
case 'entries':
break;
case 'global-fields':
break;
}
}
} catch (error) {
this.log(error instanceof Error ? error.message : error, 'error');
this.exit(1);
}
}

async run(): Promise<void> {}
async promptQueue() {
// NOTE get content path if data-dir flag is missing
this.sharedConfig.basePath =
this.flags['data-dir'] ||
(await cliux.inquire<string>({
type: 'input',
name: 'data-dir',
message: this.messages.DATA_DIR,
}));
}
}
9 changes: 8 additions & 1 deletion packages/contentstack-audit/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const config = {
modues: []
modules: ['content-types', 'entries', 'global-fields'],
skipRefs: ['sys_assets'],
moduleConfig: {
'content-types': {
dirName: 'content_types',
fileName: 'content_types.json',
},
},
};

export default config;
15 changes: 13 additions & 2 deletions packages/contentstack-audit/src/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,22 @@ const errors = {
const commonMsg = {
CONFIG: 'Path of the external config',
CURRENT_WORKING_DIR: 'Current working directory.',
DATA_DIR: 'Path and location where data is stored',
};

const messages: typeof errors & typeof commonMsg = {
const auditMsg = {
REPORT_PATH: 'Path to store the audit reports',
MODULES: 'Provide list of modules to be audited',
REFERENCE_ONLY: 'Checks only for missing references',
NOT_VALID_PATH: "Provided path: '{path}' is not valid",
SCAN_CT_SUCCESS_MSG: "The scanning of content type '{title}' has been successfully finished.",
FINAL_REPORT_PATH: "Writing reports completed. You can find reports at '{path}'",
};

const messages: typeof errors & typeof commonMsg & typeof auditMsg = {
...errors,
...commonMsg,
...auditMsg,
};

/**
Expand All @@ -32,4 +43,4 @@ function $t(msg: string, args: Record<string, string>): string {
}

export default messages;
export { $t, errors, commonMsg };
export { $t, errors, commonMsg, auditMsg };
Loading

0 comments on commit a1a828d

Please sign in to comment.