Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
fileignoreconfig:
- filename: package-lock.json
checksum: 5e64367e6f00c41d8fec66e335f66202d97a0e75006c9ecd331ce8f5856e296a
checksum: 40f1c53aad40a1f8d711c5ccdde7d1c147d371618c237e1fec2d313af51edb97
- filename: pnpm-lock.yaml
checksum: aa6177859aaa87caf2892e8034657fd485c3abe7c13a833fd28449a1d33fa950
- filename: packages/contentstack-import-setup/test/unit/backup-handler.test.ts
Expand Down Expand Up @@ -102,13 +102,13 @@ fileignoreconfig:
- filename: packages/contentstack-audit/src/modules/workflows.ts
checksum: 20d1f1985ea2657d3f9fc41b565a44000cbda47e2a60a576fee2aaff06f49352
- filename: packages/contentstack-audit/src/modules/field_rules.ts
checksum: 3eaca968126c9e0e12115491f7942341124c9962d5285dd1cfb355d9e60c6106
checksum: f3ec8f44f8dd73601aa8da1207a72335faf0a12d52e792c1da90ba1bdeef38a7
- filename: packages/contentstack-audit/src/modules/entries.ts
checksum: 305af34194771343fee4e1d4bef60d065f1b8d1d8c1059a332f5d6c52e637ff1
checksum: d8b6aa896aef2a9846f4dbde066d74d5b1e7b5cdbb8b548989616f9af7a8d26b
- filename: packages/contentstack-audit/test/unit/base-command.test.ts
checksum: b0fa8088fcbb17510fa275bd0dde3f6f4246f2525741c30426f07dd62fe497b0
- filename: packages/contentstack-audit/src/modules/content-types.ts
checksum: ddf7b08e6a80af09c6a7019a637c26089fb76572c7c3d079a8af244b02985f16
checksum: e325a50db567abc5d0de758767037dbc10bb76501aadda32999bc96e17595d1b
- filename: packages/contentstack-import/test/unit/commands/cm/stacks/import.test.ts
checksum: b11e57f1b824d405f86438e9e7c59183f8c59b66b42d8d16dbeaf76195a30548
- filename: packages/contentstack-import/test/unit/utils/asset-helper.test.ts
Expand Down
2,554 changes: 1,204 additions & 1,350 deletions package-lock.json

Large diffs are not rendered by default.

27 changes: 13 additions & 14 deletions packages/contentstack-audit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit
$ csdx COMMAND
running command...
$ csdx (--version|-v)
@contentstack/cli-audit/1.14.2 darwin-arm64 node-v22.14.0
@contentstack/cli-audit/2.0.0-beta.0 darwin-arm64 node-v22.14.0
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down Expand Up @@ -273,7 +273,7 @@ USAGE
$ csdx help [COMMAND...] [-n]

ARGUMENTS
COMMAND... Command to show help for.
[COMMAND...] Command to show help for.

FLAGS
-n, --nested-commands Include all nested commands in the output.
Expand All @@ -282,8 +282,7 @@ DESCRIPTION
Display help for csdx.
```

_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.33/src/commands/help.ts)_
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.33/src/commands/help.ts)_
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.36/src/commands/help.ts)_

## `csdx plugins`

Expand All @@ -306,7 +305,7 @@ EXAMPLES
$ csdx plugins
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/index.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/index.ts)_

## `csdx plugins:add PLUGIN`

Expand Down Expand Up @@ -380,7 +379,7 @@ EXAMPLES
$ csdx plugins:inspect myplugin
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/inspect.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/inspect.ts)_

## `csdx plugins:install PLUGIN`

Expand Down Expand Up @@ -429,7 +428,7 @@ EXAMPLES
$ csdx plugins:install someuser/someplugin
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/install.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/install.ts)_

## `csdx plugins:link PATH`

Expand Down Expand Up @@ -460,7 +459,7 @@ EXAMPLES
$ csdx plugins:link myplugin
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/link.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/link.ts)_

## `csdx plugins:remove [PLUGIN]`

Expand All @@ -471,7 +470,7 @@ USAGE
$ csdx plugins:remove [PLUGIN...] [-h] [-v]

ARGUMENTS
PLUGIN... plugin to uninstall
[PLUGIN...] plugin to uninstall

FLAGS
-h, --help Show CLI help.
Expand Down Expand Up @@ -501,7 +500,7 @@ FLAGS
--reinstall Reinstall all plugins after uninstalling.
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/reset.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/reset.ts)_

## `csdx plugins:uninstall [PLUGIN]`

Expand All @@ -512,7 +511,7 @@ USAGE
$ csdx plugins:uninstall [PLUGIN...] [-h] [-v]

ARGUMENTS
PLUGIN... plugin to uninstall
[PLUGIN...] plugin to uninstall

FLAGS
-h, --help Show CLI help.
Expand All @@ -529,7 +528,7 @@ EXAMPLES
$ csdx plugins:uninstall myplugin
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/uninstall.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/uninstall.ts)_

## `csdx plugins:unlink [PLUGIN]`

Expand All @@ -540,7 +539,7 @@ USAGE
$ csdx plugins:unlink [PLUGIN...] [-h] [-v]

ARGUMENTS
PLUGIN... plugin to uninstall
[PLUGIN...] plugin to uninstall

FLAGS
-h, --help Show CLI help.
Expand Down Expand Up @@ -573,5 +572,5 @@ DESCRIPTION
Update installed plugins.
```

_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.49/src/commands/plugins/update.ts)_
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/update.ts)_
<!-- commandsstop -->
2 changes: 1 addition & 1 deletion packages/contentstack-audit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/cli-audit",
"version": "1.16.0",
"version": "2.0.0-beta.0",
"description": "Contentstack audit plugin",
"author": "Contentstack CLI",
"homepage": "https://github.com/contentstack/cli",
Expand Down
95 changes: 66 additions & 29 deletions packages/contentstack-audit/src/audit-base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { v4 as uuid } from 'uuid';
import isEmpty from 'lodash/isEmpty';
import { join, resolve } from 'path';
import cloneDeep from 'lodash/cloneDeep';
import { cliux, sanitizePath, TableFlags, TableHeader, log, configHandler } from '@contentstack/cli-utilities';
import { cliux, sanitizePath, TableFlags, TableHeader, log, configHandler, CLIProgressManager, clearProgressModuleSetting } from '@contentstack/cli-utilities';
import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
import config from './config';
import { print } from './util/log';
Expand Down Expand Up @@ -71,11 +71,23 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
*/
async start(command: CommandNames): Promise<boolean> {
this.currentCommand = command;

// Set progress supported module and console logs setting BEFORE any log calls
// This ensures the logger respects the setting when it's initialized
const logConfig = configHandler.get('log') || {};
// Default to false so progress bars are shown instead of console logs
if (logConfig.showConsoleLogs === undefined) {
configHandler.set('log.showConsoleLogs', false);
}
configHandler.set('log.progressSupportedModule', 'audit');

// Initialize audit context
this.auditContext = this.createAuditContext();
log.debug(`Starting audit command: ${command}`, this.auditContext);
log.info(`Starting audit command: ${command}`, this.auditContext);


// Initialize global summary for progress tracking
CLIProgressManager.initializeGlobalSummary('AUDIT', '', 'Auditing content...');

await this.promptQueue();
await this.createBackUp();
Expand Down Expand Up @@ -163,6 +175,12 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
}
}

// Print comprehensive summary at the end
CLIProgressManager.printGlobalSummary();

// Clear progress module setting now that audit is complete
clearProgressModuleSetting();

return (
!isEmpty(missingCtRefs) ||
!isEmpty(missingGfRefs) ||
Expand Down Expand Up @@ -222,47 +240,59 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma

let dataModuleWise: Record<string, any> = await new ModuleDataReader(cloneDeep(constructorParam)).run();
log.debug(`Data module wise: ${JSON.stringify(dataModuleWise)}`, this.auditContext);

// Extract logConfig and showConsoleLogs once before the loop to reuse throughout
const logConfig = configHandler.get('log') || {};
const showConsoleLogs = logConfig.showConsoleLogs ?? true;

for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
// Update audit context with current module
this.auditContext = this.createAuditContext(module);
log.debug(`Starting audit for module: ${module}`, this.auditContext);
log.info(`Starting audit for module: ${module}`, this.auditContext);

print([
{
bold: true,
color: 'whiteBright',
message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
},
]);
// Only show spinner message if console logs are enabled (compatible with line-by-line logs)
if (showConsoleLogs) {
print([
{
bold: true,
color: 'whiteBright',
message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
},
]);
}

constructorParam['moduleName'] = module;

switch (module) {
case 'assets':
log.info('Executing assets audit', this.auditContext);
missingEnvLocalesInAssets = await new Assets(cloneDeep(constructorParam)).run();
const assetsTotalCount = dataModuleWise['assets']?.Total || 0;
missingEnvLocalesInAssets = await new Assets(cloneDeep(constructorParam)).run(false, assetsTotalCount);
await this.prepareReport(module, missingEnvLocalesInAssets);
this.getAffectedData('assets', dataModuleWise['assets'], missingEnvLocalesInAssets);
log.success(`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`, this.auditContext);
break;
case 'content-types':
log.info('Executing content-types audit', this.auditContext);
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run();
const contentTypesTotalCount = dataModuleWise['content-types']?.Total || 0;
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run(false, contentTypesTotalCount);
await this.prepareReport(module, missingCtRefs);
this.getAffectedData('content-types', dataModuleWise['content-types'], missingCtRefs);
log.success(`Content-types audit completed. Found ${Object.keys(missingCtRefs || {}).length} issues`, this.auditContext);
break;
case 'global-fields':
log.info('Executing global-fields audit', this.auditContext);
missingGfRefs = await new GlobalField(cloneDeep(constructorParam)).run();
const globalFieldsTotalCount = dataModuleWise['global-fields']?.Total || 0;
missingGfRefs = await new GlobalField(cloneDeep(constructorParam)).run(false, globalFieldsTotalCount);
await this.prepareReport(module, missingGfRefs);
this.getAffectedData('global-fields', dataModuleWise['global-fields'], missingGfRefs);
log.success(`Global-fields audit completed. Found ${Object.keys(missingGfRefs || {}).length} issues`, this.auditContext);
break;
case 'entries':
log.info('Executing entries audit', this.auditContext);
missingEntry = await new Entries(cloneDeep(constructorParam)).run();
const entriesTotalCount = dataModuleWise['entries']?.Total || 0;
missingEntry = await new Entries(cloneDeep(constructorParam)).run(entriesTotalCount);
missingEntryRefs = missingEntry.missingEntryRefs ?? {};
missingSelectFeild = missingEntry.missingSelectFeild ?? {};
missingMandatoryFields = missingEntry.missingMandatoryFields ?? {};
Expand All @@ -286,27 +316,30 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
break;
case 'workflows':
log.info('Executing workflows audit', this.auditContext);
const workflowsTotalCount = dataModuleWise['workflows']?.Total || 0;
missingCtRefsInWorkflow = await new Workflows({
ctSchema,
moduleName: module,
config: this.sharedConfig,
fix: this.currentCommand === 'cm:stacks:audit:fix',
}).run();
}).run(workflowsTotalCount);
await this.prepareReport(module, missingCtRefsInWorkflow);
this.getAffectedData('workflows', dataModuleWise['workflows'], missingCtRefsInWorkflow);
log.success(`Workflows audit completed. Found ${Object.keys(missingCtRefsInWorkflow || {}).length} issues`, this.auditContext);

break;
case 'extensions':
log.info('Executing extensions audit', this.auditContext);
missingCtRefsInExtensions = await new Extensions(cloneDeep(constructorParam)).run();
const extensionsTotalCount = dataModuleWise['extensions']?.Total || 0;
missingCtRefsInExtensions = await new Extensions(cloneDeep(constructorParam)).run(extensionsTotalCount);
await this.prepareReport(module, missingCtRefsInExtensions);
this.getAffectedData('extensions', dataModuleWise['extensions'], missingCtRefsInExtensions);
log.success(`Extensions audit completed. Found ${Object.keys(missingCtRefsInExtensions || {}).length} issues`, this.auditContext);
break;
case 'custom-roles':
log.info('Executing custom-roles audit', this.auditContext);
missingRefInCustomRoles = await new CustomRoles(cloneDeep(constructorParam)).run();
const customRolesTotalCount = dataModuleWise['custom-roles']?.Total || 0;
missingRefInCustomRoles = await new CustomRoles(cloneDeep(constructorParam)).run(customRolesTotalCount);
await this.prepareReport(module, missingRefInCustomRoles);
this.getAffectedData('custom-roles', dataModuleWise['custom-roles'], missingRefInCustomRoles);
log.success(`Custom-roles audit completed. Found ${Object.keys(missingRefInCustomRoles || {}).length} issues`, this.auditContext);
Expand All @@ -318,25 +351,29 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
const data = this.getCtAndGfSchema();
constructorParam.ctSchema = data.ctSchema;
constructorParam.gfSchema = data.gfSchema;
missingFieldRules = await new FieldRule(cloneDeep(constructorParam)).run();
const fieldRulesTotalCount = dataModuleWise['content-types']?.Total || 0;
missingFieldRules = await new FieldRule(cloneDeep(constructorParam)).run(fieldRulesTotalCount);
await this.prepareReport(module, missingFieldRules);
this.getAffectedData('field-rules', dataModuleWise['content-types'], missingFieldRules);
log.success(`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`, this.auditContext);
break;
}

print([
{
bold: true,
color: 'whiteBright',
message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
},
{
bold: true,
message: ' done',
color: 'whiteBright',
},
]);
// Only show completion message if console logs are enabled
if (showConsoleLogs) {
print([
{
bold: true,
color: 'whiteBright',
message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
},
{
bold: true,
message: ' done',
color: 'whiteBright',
},
]);
}
}

log.debug('Scan and fix process completed', this.auditContext);
Expand Down
Loading
Loading