Skip to content

Commit 12804d3

Browse files
authored
Merge pull request #2037 from contentstack/feat/DX-3288
feat: Integrated CLIProgressManager and SummaryManager in export
2 parents 2d37cbd + cc738c5 commit 12804d3

File tree

26 files changed

+1553
-587
lines changed

26 files changed

+1553
-587
lines changed

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fileignoreconfig:
22
- filename: pnpm-lock.yaml
3-
checksum: 8f1591ae8c7da0f3415c0132c1585491b481dab49e1dda2a95ff29c014590c61
3+
checksum: 0bfb05bb772a26be604bab6c93a58f93bcdc564b26547a1e8365222a679ae23d
44
- filename: packages/contentstack-import/test/integration/auth-token-modules/environments.test.js
55
checksum: bc6f06b75d082aaf99e2f2f4b932b143765e2f14086967fb8973fe1b2ca6c03e
66
- filename: packages/contentstack-import/test/integration/environments.test.js

packages/contentstack-config/src/commands/config/get/log.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@ export default class LogGetCommand extends Command {
1111
const currentLoggingConfig = configHandler.get('log') || {};
1212
const logLevel = currentLoggingConfig?.level;
1313
const logPath = currentLoggingConfig?.path;
14+
const showConsoleLogs = currentLoggingConfig?.showConsoleLogs;
1415

1516
if (logLevel || logPath) {
1617
const logConfigList = [
1718
{
1819
'Log Level': logLevel || 'Not set',
1920
'Log Path': logPath || 'Not set',
21+
'Show Console Logs': showConsoleLogs !== undefined ? String(showConsoleLogs) : 'Not set',
2022
},
2123
];
2224

2325
const headers: TableHeader[] = [
2426
{ value: 'Log Level' },
2527
{ value: 'Log Path' },
28+
{ value: 'Show Console Logs' },
2629
];
2730

2831
cliux.table(headers, logConfigList);

packages/contentstack-config/src/commands/config/set/log.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ export default class LogSetCommand extends Command {
3434
let logLevel: string = flags['level'];
3535
let logPath: string = flags['path'];
3636
const showConsoleLogs: boolean = flags['show-console-logs'];
37-
37+
const currentLoggingConfig = configHandler.get('log') || {};
38+
logLevel = logLevel || currentLoggingConfig?.level;
39+
logPath = logPath || currentLoggingConfig?.path;
3840
// Interactive prompts if not passed via flags
3941
if (!logLevel) {
4042
logLevel = await interactive.askLogLevel();
@@ -44,10 +46,9 @@ export default class LogSetCommand extends Command {
4446
logPath = await interactive.askLogPath();
4547
}
4648

47-
const currentLoggingConfig = configHandler.get('log') || {};
4849
if (logLevel) currentLoggingConfig.level = logLevel;
4950
if (logPath) currentLoggingConfig.path = logPath;
50-
currentLoggingConfig['show-console-logs'] = showConsoleLogs;
51+
currentLoggingConfig.showConsoleLogs = showConsoleLogs;
5152

5253
configHandler.set('log', currentLoggingConfig);
5354

packages/contentstack-config/test/unit/commands/log.test.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('Log Commands', () => {
4545
setStub.calledWith('log', {
4646
level: 'debug',
4747
path: './logs/app.log',
48-
'show-console-logs': false,
48+
showConsoleLogs: false,
4949
}),
5050
).to.be.true;
5151

@@ -74,7 +74,7 @@ describe('Log Commands', () => {
7474
setStub.calledWith('log', {
7575
level: 'info',
7676
path: './custom/logs/app.log',
77-
'show-console-logs': false,
77+
showConsoleLogs: false,
7878
}),
7979
).to.be.true;
8080

@@ -103,7 +103,7 @@ describe('Log Commands', () => {
103103
setStub.calledWith('log', {
104104
level: 'warn',
105105
path: './existing/logs/app.log',
106-
'show-console-logs': false,
106+
showConsoleLogs: false,
107107
}),
108108
).to.be.true;
109109

@@ -132,7 +132,7 @@ describe('Log Commands', () => {
132132
setStub.calledWith('log', {
133133
level: 'error',
134134
path: './new/logs/app.log',
135-
'show-console-logs': false,
135+
showConsoleLogs: false,
136136
}),
137137
).to.be.true;
138138

@@ -159,7 +159,7 @@ describe('Log Commands', () => {
159159
setStub.calledWith('log', {
160160
level: 'info',
161161
path: './logs/app.log',
162-
'show-console-logs': true,
162+
showConsoleLogs: true,
163163
}),
164164
).to.be.true;
165165

@@ -184,7 +184,7 @@ describe('Log Commands', () => {
184184
setStub.calledWith('log', {
185185
level: 'info',
186186
path: './logs/app.log',
187-
'show-console-logs': false,
187+
showConsoleLogs: false,
188188
}),
189189
).to.be.true;
190190

@@ -210,7 +210,7 @@ describe('Log Commands', () => {
210210
setStub.calledWith('log', {
211211
level: 'warn',
212212
path: './logs/warnings.log',
213-
'show-console-logs': true,
213+
showConsoleLogs: true,
214214
}),
215215
).to.be.true;
216216

@@ -241,7 +241,7 @@ describe('Log Commands', () => {
241241
setStub.calledWith('log', {
242242
level: 'info',
243243
path: './logs/app.log',
244-
'show-console-logs': false,
244+
showConsoleLogs: false,
245245
}),
246246
).to.be.true;
247247

@@ -290,11 +290,12 @@ describe('Log Commands', () => {
290290
await cmd.run();
291291

292292
expect(tableMessage).to.have.length(1);
293-
expect(tableMessage[0].headers).to.deep.equal([{ value: 'Log Level' }, { value: 'Log Path' }]);
293+
expect(tableMessage[0].headers).to.deep.equal([{ value: 'Log Level' }, { value: 'Log Path' }, { value: 'Show Console Logs' }]);
294294
expect(tableMessage[0].data).to.deep.equal([
295295
{
296296
'Log Level': 'debug',
297297
'Log Path': './logs/app.log',
298+
'Show Console Logs': 'Not set',
298299
},
299300
]);
300301
});
@@ -306,11 +307,12 @@ describe('Log Commands', () => {
306307
await cmd.run();
307308

308309
expect(tableMessage).to.have.length(1);
309-
expect(tableMessage[0].headers).to.deep.equal([{ value: 'Log Level' }, { value: 'Log Path' }]);
310+
expect(tableMessage[0].headers).to.deep.equal([{ value: 'Log Level' }, { value: 'Log Path' }, { value: 'Show Console Logs' }]);
310311
expect(tableMessage[0].data).to.deep.equal([
311312
{
312313
'Log Level': 'info',
313314
'Log Path': 'Not set',
315+
'Show Console Logs': 'Not set',
314316
},
315317
]);
316318
});
@@ -322,11 +324,12 @@ describe('Log Commands', () => {
322324
await cmd.run();
323325

324326
expect(tableMessage).to.have.length(1);
325-
expect(tableMessage[0].headers).to.deep.equal([{ value: 'Log Level' }, { value: 'Log Path' }]);
327+
expect(tableMessage[0].headers).to.deep.equal([{ value: 'Log Level' }, { value: 'Log Path' }, { value: 'Show Console Logs' }]);
326328
expect(tableMessage[0].data).to.deep.equal([
327329
{
328330
'Log Level': 'Not set',
329331
'Log Path': './custom/logs/app.log',
332+
'Show Console Logs': 'Not set',
330333
},
331334
]);
332335
});

packages/contentstack-export/messages/index.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ASSET_EXPORT_COMPLETE": "Asset export process completed successfully",
3-
"ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully",
3+
"ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully with %s folder(s)",
44
"ASSET_METADATA_EXPORT_COMPLETE": "Asset metadata exported successfully",
55
"ASSET_VERSIONED_METADATA_EXPORT_COMPLETE": "Versioned asset metadata exported successfully",
66
"ASSET_DOWNLOAD_COMPLETE": "Asset download completed successfully",
@@ -65,5 +65,7 @@
6565
"BRANCH_EXPORT_FAILED": "Failed to export contents from branch (UID: %s)",
6666

6767
"ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack",
68-
"ROLES_EXPORTING_ROLE": "Exporting role '%s'"
68+
"ROLES_EXPORTING_ROLE": "Exporting role '%s'",
69+
70+
"GLOBAL_FIELDS_NOT_FOUND": "No global fields found in the current stack"
6971
}

packages/contentstack-export/src/commands/cm/stacks/export.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
log,
1414
handleAndLogError,
1515
getLogPath,
16+
CLIProgressManager,
1617
} from '@contentstack/cli-utilities';
1718

1819
import { ModuleExporter } from '../../../export';
@@ -136,9 +137,18 @@ export default class ExportCommand extends Command {
136137
);
137138
log.info(`The exported content has been stored at '${exportDir}'`, exportConfig.context);
138139
log.success(`The log has been stored at '${getLogPath()}'`, exportConfig.context);
140+
141+
// Print comprehensive summary at the end
142+
if (!exportConfig.branches) CLIProgressManager.printGlobalSummary();
143+
if (!configHandler.get('log')?.showConsoleLogs) {
144+
cliux.print(`The log has been stored at '${getLogPath()}'`, { color: 'green' });
145+
}
139146
} catch (error) {
140147
handleAndLogError(error);
141-
log.info(`The log has been stored at '${getLogPath()}'`)
148+
if (!configHandler.get('log')?.showConsoleLogs) {
149+
cliux.print(`Error: ${error}`, { color: 'red' });
150+
cliux.print(`The log has been stored at '${getLogPath()}'`, { color: 'green' });
151+
}
142152
}
143153
}
144154

packages/contentstack-export/src/export/module-exporter.ts

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import * as path from 'path';
2-
import { ContentstackClient, handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities';
2+
import {
3+
ContentstackClient,
4+
handleAndLogError,
5+
messageHandler,
6+
log,
7+
CLIProgressManager,
8+
} from '@contentstack/cli-utilities';
39
import { setupBranches, setupExportDir, writeExportMetaFile } from '../utils';
410
import startModuleExport from './modules';
511
import startJSModuleExport from './modules-js';
@@ -28,23 +34,35 @@ class ModuleExporter {
2834
this.exportConfig.branchEnabled = true;
2935
return this.exportByBranches();
3036
}
37+
// If branches disabled then initialize the global summary
38+
CLIProgressManager.initializeGlobalSummary('EXPORT', this.exportConfig.branchName);
3139
return this.export();
3240
}
3341

3442
async exportByBranches(): Promise<void> {
3543
// loop through the branches and export it parallel
36-
for (const branch of this.exportConfig.branches) {
44+
for (const [index, branch] of this.exportConfig.branches.entries()) {
3745
try {
3846
this.exportConfig.branchName = branch.uid;
3947
this.stackAPIClient.stackHeaders.branch = branch.uid;
4048
this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, branch.uid);
49+
50+
// Reset progress manager for each branch (except the first one which was initialized in export command)
51+
if (index >= 0) {
52+
CLIProgressManager.clearGlobalSummary();
53+
CLIProgressManager.initializeGlobalSummary(`EXPORT-${branch.uid}`, branch.uid);
54+
}
55+
4156
log.info(`Exporting content from branch ${branch.uid}`, this.exportConfig.context);
4257
writeExportMetaFile(this.exportConfig, this.exportConfig.branchDir);
4358
await this.export();
44-
log.success(
45-
`The content of branch ${branch.uid} has been exported successfully!`,
46-
this.exportConfig.context,
47-
);
59+
60+
// Print branch-specific summary
61+
if (index <= this.exportConfig.branches.length - 1) {
62+
CLIProgressManager.printGlobalSummary();
63+
}
64+
65+
log.success(`The content of branch ${branch.uid} has been exported successfully!`, this.exportConfig.context);
4866
} catch (error) {
4967
handleAndLogError(
5068
error,
@@ -57,10 +75,7 @@ class ModuleExporter {
5775
}
5876

5977
async export() {
60-
log.info(
61-
`Started to export content, version is ${this.exportConfig.contentVersion}`,
62-
this.exportConfig.context,
63-
);
78+
log.info(`Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context);
6479
// checks for single module or all modules
6580
if (this.exportConfig.singleModuleExport) {
6681
return this.exportSingleModule(this.exportConfig.moduleName);
@@ -72,28 +87,22 @@ class ModuleExporter {
7287
log.info(`Exporting module: ${moduleName}`, this.exportConfig.context);
7388
// export the modules by name
7489
// calls the module runner which inturn calls the module itself
75-
let exportedModuleResponse;
7690
if (this.exportConfig.contentVersion === 2) {
77-
exportedModuleResponse = await startModuleExport({
91+
await startModuleExport({
7892
stackAPIClient: this.stackAPIClient,
7993
exportConfig: this.exportConfig,
8094
moduleName,
8195
});
8296
} else {
8397
//NOTE - new modules support only ts
8498
if (this.exportConfig.onlyTSModules.indexOf(moduleName) === -1) {
85-
exportedModuleResponse = await startJSModuleExport({
99+
await startJSModuleExport({
86100
stackAPIClient: this.stackAPIClient,
87101
exportConfig: this.exportConfig,
88102
moduleName,
89103
});
90104
}
91105
}
92-
93-
// set master locale to config
94-
if (moduleName === 'stack' && exportedModuleResponse?.code) {
95-
this.exportConfig.master_locale = { code: exportedModuleResponse.code };
96-
}
97106
}
98107

99108
async exportSingleModule(moduleName: Modules): Promise<void> {

0 commit comments

Comments
 (0)