@contentstack/cli-cm-branches 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +226 -0
- package/lib/branch/diff-handler.js +115 -0
- package/lib/branch/index.js +13 -0
- package/lib/branch/merge-handler.js +227 -0
- package/lib/commands/cm/branches/create.js +44 -0
- package/lib/commands/cm/branches/delete.js +47 -0
- package/lib/commands/cm/branches/diff.js +65 -0
- package/lib/commands/cm/branches/index.js +81 -0
- package/lib/commands/cm/branches/merge.js +94 -0
- package/lib/config/index.js +7 -0
- package/lib/interfaces/index.js +2 -0
- package/lib/utils/branch-diff-utility.js +503 -0
- package/lib/utils/create-branch.js +37 -0
- package/lib/utils/create-merge-scripts.js +67 -0
- package/lib/utils/delete-branch.js +35 -0
- package/lib/utils/entry-create-script.js +73 -0
- package/lib/utils/entry-update-script.js +126 -0
- package/lib/utils/index.js +98 -0
- package/lib/utils/interactive.js +244 -0
- package/lib/utils/merge-helper.js +138 -0
- package/messages/index.json +12 -0
- package/oclif.manifest.json +289 -0
- package/package.json +92 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.entryCreateScript = void 0;
|
|
4
|
+
function entryCreateScript(contentType) {
|
|
5
|
+
return `
|
|
6
|
+
module.exports = async ({ migration, stackSDKInstance, managementAPIClient, config, branch, apiKey }) => {
|
|
7
|
+
const keysToRemove = [
|
|
8
|
+
'content_type_uid',
|
|
9
|
+
'created_at',
|
|
10
|
+
'updated_at',
|
|
11
|
+
'created_by',
|
|
12
|
+
'updated_by',
|
|
13
|
+
'ACL',
|
|
14
|
+
'stackHeaders',
|
|
15
|
+
'urlPath',
|
|
16
|
+
'_version',
|
|
17
|
+
'_in_progress',
|
|
18
|
+
'update',
|
|
19
|
+
'delete',
|
|
20
|
+
'fetch',
|
|
21
|
+
'publish',
|
|
22
|
+
'unpublish',
|
|
23
|
+
'publishRequest',
|
|
24
|
+
'setWorkflowStage',
|
|
25
|
+
'import',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
let compareBranch = config['compare-branch'];
|
|
29
|
+
|
|
30
|
+
const createEntryTask = () => {
|
|
31
|
+
return {
|
|
32
|
+
title: 'Create Entries',
|
|
33
|
+
successTitle: 'Entries Created Successfully',
|
|
34
|
+
failedTitle: 'Failed to create entries',
|
|
35
|
+
task: async () => {
|
|
36
|
+
const compareBranchEntries = await managementAPIClient
|
|
37
|
+
.stack({ api_key: stackSDKInstance.api_key, branch_uid: compareBranch }) //
|
|
38
|
+
.contentType('${contentType}')
|
|
39
|
+
.entry()
|
|
40
|
+
.query()
|
|
41
|
+
.find();
|
|
42
|
+
const compareFilteredProperties = compareBranchEntries.items.map((entry) => {
|
|
43
|
+
keysToRemove.map((key) => delete entry[key]);
|
|
44
|
+
return entry;
|
|
45
|
+
});
|
|
46
|
+
try {
|
|
47
|
+
compareFilteredProperties.length !== 0 &&
|
|
48
|
+
compareFilteredProperties.forEach(async (entryDetails) => {
|
|
49
|
+
await stackSDKInstance.contentType('${contentType}').entry().create({ entry: entryDetails });
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
if (compareBranch && branch.length !== 0 && apiKey.length !== 0) {
|
|
58
|
+
migration.addTask(createEntryTask());
|
|
59
|
+
} else {
|
|
60
|
+
if (apiKey.length === 0) {
|
|
61
|
+
console.error('Please provide api key using --stack-api-key flag');
|
|
62
|
+
}
|
|
63
|
+
if (!compareBranch) {
|
|
64
|
+
console.error('Please provide compare branch through --config compare-branch:<value> flag');
|
|
65
|
+
}
|
|
66
|
+
if (branch.length === 0) {
|
|
67
|
+
console.error('Please provide branch name through --branch flag');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
exports.entryCreateScript = entryCreateScript;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.entryUpdateScript = void 0;
|
|
4
|
+
function entryUpdateScript(contentType) {
|
|
5
|
+
return `
|
|
6
|
+
module.exports = async ({ migration, stackSDKInstance, managementAPIClient, config, branch, apiKey }) => {
|
|
7
|
+
const keysToRemove = [
|
|
8
|
+
'content_type_uid',
|
|
9
|
+
'created_at',
|
|
10
|
+
'updated_at',
|
|
11
|
+
'created_by',
|
|
12
|
+
'updated_by',
|
|
13
|
+
'ACL',
|
|
14
|
+
'stackHeaders',
|
|
15
|
+
'urlPath',
|
|
16
|
+
'_version',
|
|
17
|
+
'_in_progress',
|
|
18
|
+
'update',
|
|
19
|
+
'delete',
|
|
20
|
+
'fetch',
|
|
21
|
+
'publish',
|
|
22
|
+
'unpublish',
|
|
23
|
+
'publishRequest',
|
|
24
|
+
'setWorkflowStage',
|
|
25
|
+
'import',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
let compareBranch = config['compare-branch'];
|
|
29
|
+
|
|
30
|
+
function converter(data) {
|
|
31
|
+
let arr = [];
|
|
32
|
+
for (const elm of data.entries()) {
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
arr.push([elm[1].title, elm[1]]);
|
|
35
|
+
}
|
|
36
|
+
return arr;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function deleteUnwantedKeysFromObject(obj, keysToRemove) {
|
|
40
|
+
if(obj){
|
|
41
|
+
keysToRemove.map((key) => delete obj[key]);
|
|
42
|
+
return obj;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function uniquelyConcatenateArrays(compareArr, baseArr) {
|
|
47
|
+
let uniqueArray = compareArr.concat(baseArr.filter((item) => compareArr.indexOf(item) < 0));
|
|
48
|
+
return uniqueArray;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const updateEntryTask = () => {
|
|
52
|
+
return {
|
|
53
|
+
title: 'Update Entries',
|
|
54
|
+
successMessage: 'Entries Updated Successfully',
|
|
55
|
+
failedMessage: 'Failed to update entries',
|
|
56
|
+
task: async () => {
|
|
57
|
+
let compareBranchEntries = await managementAPIClient
|
|
58
|
+
.stack({ api_key: stackSDKInstance.api_key, branch_uid: compareBranch })
|
|
59
|
+
.contentType('${contentType}')
|
|
60
|
+
.entry()
|
|
61
|
+
.query()
|
|
62
|
+
.find();
|
|
63
|
+
|
|
64
|
+
let baseBranchEntries = await stackSDKInstance.contentType('${contentType}').entry().query().find();
|
|
65
|
+
|
|
66
|
+
let contentType = await managementAPIClient
|
|
67
|
+
.stack({ api_key: stackSDKInstance.api_key, branch_uid: compareBranch })
|
|
68
|
+
.contentType('${contentType}')
|
|
69
|
+
.fetch();
|
|
70
|
+
try {
|
|
71
|
+
if (contentType.options.singleton) {
|
|
72
|
+
compareBranchEntries.items.map(async (el) => {
|
|
73
|
+
let entryDetails = deleteUnwantedKeysFromObject(el, keysToRemove);
|
|
74
|
+
|
|
75
|
+
if (baseBranchEntries.items.length) {
|
|
76
|
+
let baseEntryUid = baseBranchEntries.items[0].uid;
|
|
77
|
+
let entry = await stackSDKInstance.contentType('${contentType}').entry(baseEntryUid);
|
|
78
|
+
Object.assign(entry, { ...entryDetails });
|
|
79
|
+
entry.update();
|
|
80
|
+
} else {
|
|
81
|
+
await stackSDKInstance.contentType('${contentType}').entry().create({ entry: entryDetails });
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
let compareMap = new Map(converter(compareBranchEntries.items));
|
|
86
|
+
let baseMap = new Map(converter(baseBranchEntries.items));
|
|
87
|
+
|
|
88
|
+
let arr = uniquelyConcatenateArrays(Array.from(compareMap.keys()), Array.from(baseMap.keys()));
|
|
89
|
+
|
|
90
|
+
arr.map(async (el) => {
|
|
91
|
+
let entryDetails = deleteUnwantedKeysFromObject(compareMap.get(el), keysToRemove);
|
|
92
|
+
|
|
93
|
+
if (compareMap.get(el) && !baseMap.get(el)) {
|
|
94
|
+
await stackSDKInstance.contentType('${contentType}').entry().create({ entry: entryDetails });
|
|
95
|
+
} else if (compareMap.get(el) && baseMap.get(el)) {
|
|
96
|
+
let baseEntry = baseMap.get(el);
|
|
97
|
+
|
|
98
|
+
let entry = await stackSDKInstance.contentType('${contentType}').entry(baseEntry.uid);
|
|
99
|
+
Object.assign(entry, { ...entryDetails });
|
|
100
|
+
entry.update();
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (compareBranch && branch.length !== 0 && apiKey.length !== 0) {
|
|
112
|
+
migration.addTask(updateEntryTask());
|
|
113
|
+
} else {
|
|
114
|
+
if (apiKey.length === 0) {
|
|
115
|
+
console.error('Please provide api key using --stack-api-key flag');
|
|
116
|
+
}
|
|
117
|
+
if (!compareBranch) {
|
|
118
|
+
console.error('Please provide compare branch through --config compare-branch:<value> flag');
|
|
119
|
+
}
|
|
120
|
+
if (branch.length === 0) {
|
|
121
|
+
console.error('Please provide branch name through --branch flag');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};`;
|
|
125
|
+
}
|
|
126
|
+
exports.entryUpdateScript = entryUpdateScript;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteBranchUtility = exports.branchDiffUtility = exports.interactive = exports.handleErrorMsg = exports.executeMergeRequest = exports.getMergeQueueStatus = exports.writeFile = exports.refreshbranchConfig = exports.getbranchConfig = exports.getbranchesList = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
/**
|
|
6
|
+
* Command specific utilities can be written here
|
|
7
|
+
*/
|
|
8
|
+
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
9
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
10
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
11
|
+
const getbranchesList = (branchResult, baseBranch) => {
|
|
12
|
+
const branches = [];
|
|
13
|
+
branchResult.map((item) => {
|
|
14
|
+
branches.push({
|
|
15
|
+
Branch: item.uid,
|
|
16
|
+
Source: item.source,
|
|
17
|
+
Aliases: item.alias,
|
|
18
|
+
Created: new Date(item.created_at).toLocaleDateString(),
|
|
19
|
+
Updated: new Date(item.updated_at).toLocaleDateString(),
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
const currentBranch = branches.filter((branch) => branch.Branch === baseBranch);
|
|
23
|
+
const otherBranches = branches.filter((branch) => branch.Branch !== baseBranch);
|
|
24
|
+
return { currentBranch, otherBranches, branches };
|
|
25
|
+
};
|
|
26
|
+
exports.getbranchesList = getbranchesList;
|
|
27
|
+
const getbranchConfig = (stackApiKey) => {
|
|
28
|
+
return cli_utilities_1.configHandler.get(`baseBranch.${stackApiKey}`);
|
|
29
|
+
};
|
|
30
|
+
exports.getbranchConfig = getbranchConfig;
|
|
31
|
+
const refreshbranchConfig = async (apiKey, branchUid) => {
|
|
32
|
+
const branchConfig = cli_utilities_1.configHandler.get(`baseBranch.${apiKey}`);
|
|
33
|
+
if (branchConfig === branchUid) {
|
|
34
|
+
await cli_utilities_1.configHandler.set(`baseBranch.${apiKey}`, 'main');
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
exports.refreshbranchConfig = refreshbranchConfig;
|
|
38
|
+
const writeFile = (filePath, data) => {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
data = typeof data === 'object' ? JSON.stringify(data, null, 2) : data || '{}';
|
|
41
|
+
fs_1.default.writeFile(path_1.default.resolve(filePath), data, (error) => {
|
|
42
|
+
if (error) {
|
|
43
|
+
return reject(error);
|
|
44
|
+
}
|
|
45
|
+
resolve('done');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
exports.writeFile = writeFile;
|
|
50
|
+
async function getMergeQueueStatus(stackAPIClient, payload) {
|
|
51
|
+
const mergeJobUID = payload.uid;
|
|
52
|
+
return await stackAPIClient
|
|
53
|
+
.branch()
|
|
54
|
+
.mergeQueue(mergeJobUID)
|
|
55
|
+
.fetch()
|
|
56
|
+
.then((data) => data)
|
|
57
|
+
.catch((err) => handleErrorMsg(err));
|
|
58
|
+
}
|
|
59
|
+
exports.getMergeQueueStatus = getMergeQueueStatus;
|
|
60
|
+
async function executeMergeRequest(stackAPIClient, payload) {
|
|
61
|
+
const { host, apiKey, params: { base_branch, compare_branch, default_merge_strategy, item_merge_strategies, merge_comment, no_revert }, } = payload;
|
|
62
|
+
const queryParams = {
|
|
63
|
+
base_branch,
|
|
64
|
+
compare_branch,
|
|
65
|
+
default_merge_strategy,
|
|
66
|
+
merge_comment,
|
|
67
|
+
no_revert,
|
|
68
|
+
};
|
|
69
|
+
const itemMergeStrategies = default_merge_strategy === 'ignore' ? { item_merge_strategies } : {};
|
|
70
|
+
return await stackAPIClient
|
|
71
|
+
.branch()
|
|
72
|
+
.merge(itemMergeStrategies, queryParams)
|
|
73
|
+
.then((data) => data)
|
|
74
|
+
.catch((err) => handleErrorMsg(err));
|
|
75
|
+
}
|
|
76
|
+
exports.executeMergeRequest = executeMergeRequest;
|
|
77
|
+
function handleErrorMsg(err) {
|
|
78
|
+
if (err === null || err === void 0 ? void 0 : err.errorMessage) {
|
|
79
|
+
cli_utilities_1.cliux.print(`Error: ${err.errorMessage}`, { color: 'red' });
|
|
80
|
+
}
|
|
81
|
+
else if (err === null || err === void 0 ? void 0 : err.message) {
|
|
82
|
+
cli_utilities_1.cliux.print(`Error: ${err.message}`, { color: 'red' });
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.log(err);
|
|
86
|
+
cli_utilities_1.cliux.print(`Error: ${cli_utilities_1.messageHandler.parse('CLI_BRANCH_API_FAILED')}`, { color: 'red' });
|
|
87
|
+
}
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
exports.handleErrorMsg = handleErrorMsg;
|
|
91
|
+
tslib_1.__exportStar(require("./interactive"), exports);
|
|
92
|
+
tslib_1.__exportStar(require("./merge-helper"), exports);
|
|
93
|
+
tslib_1.__exportStar(require("./create-merge-scripts"), exports);
|
|
94
|
+
tslib_1.__exportStar(require("./entry-update-script"), exports);
|
|
95
|
+
tslib_1.__exportStar(require("./entry-create-script"), exports);
|
|
96
|
+
exports.interactive = tslib_1.__importStar(require("./interactive"));
|
|
97
|
+
exports.branchDiffUtility = tslib_1.__importStar(require("./branch-diff-utility"));
|
|
98
|
+
exports.deleteBranchUtility = tslib_1.__importStar(require("./delete-branch"));
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.askBranchNameConfirmation = exports.selectCustomPreferences = exports.askMergeComment = exports.askExportMergeSummaryPath = exports.selectMergeExecution = exports.selectMergeStrategySubOptions = exports.selectMergeStrategy = exports.inquireRequireFieldValidation = exports.askConfirmation = exports.askBranchUid = exports.askSourceBranch = exports.askBaseBranch = exports.askStackAPIKey = exports.askCompareBranch = exports.selectModule = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
6
|
+
const startCase_1 = tslib_1.__importDefault(require("lodash/startCase"));
|
|
7
|
+
const camelCase_1 = tslib_1.__importDefault(require("lodash/camelCase"));
|
|
8
|
+
const forEach_1 = tslib_1.__importDefault(require("lodash/forEach"));
|
|
9
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
10
|
+
async function selectModule() {
|
|
11
|
+
return await cli_utilities_1.cliux.inquire({
|
|
12
|
+
type: 'list',
|
|
13
|
+
name: 'module',
|
|
14
|
+
message: 'CLI_BRANCH_MODULE',
|
|
15
|
+
choices: [
|
|
16
|
+
{ name: 'Content Types', value: 'content-types' },
|
|
17
|
+
{ name: 'Global Fields', value: 'global-fields' },
|
|
18
|
+
{ name: 'All', value: 'all' },
|
|
19
|
+
],
|
|
20
|
+
validate: inquireRequireFieldValidation,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
exports.selectModule = selectModule;
|
|
24
|
+
async function askCompareBranch() {
|
|
25
|
+
return await cli_utilities_1.cliux.inquire({
|
|
26
|
+
type: 'input',
|
|
27
|
+
message: 'CLI_BRANCH_COMPARE_BRANCH',
|
|
28
|
+
name: 'compare_branch',
|
|
29
|
+
validate: inquireRequireFieldValidation,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
exports.askCompareBranch = askCompareBranch;
|
|
33
|
+
async function askStackAPIKey() {
|
|
34
|
+
return await cli_utilities_1.cliux.inquire({
|
|
35
|
+
type: 'input',
|
|
36
|
+
message: 'CLI_BRANCH_STACK_API_KEY',
|
|
37
|
+
name: 'api_key',
|
|
38
|
+
validate: inquireRequireFieldValidation,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
exports.askStackAPIKey = askStackAPIKey;
|
|
42
|
+
async function askBaseBranch() {
|
|
43
|
+
return await cli_utilities_1.cliux.inquire({
|
|
44
|
+
type: 'input',
|
|
45
|
+
message: 'CLI_BRANCH_BASE_BRANCH',
|
|
46
|
+
name: 'branch_branch',
|
|
47
|
+
validate: inquireRequireFieldValidation,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
exports.askBaseBranch = askBaseBranch;
|
|
51
|
+
async function askSourceBranch() {
|
|
52
|
+
return await cli_utilities_1.cliux.inquire({
|
|
53
|
+
type: 'input',
|
|
54
|
+
message: 'CLI_BRANCH_SOURCE_BRANCH',
|
|
55
|
+
name: 'source_branch',
|
|
56
|
+
validate: inquireRequireFieldValidation,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
exports.askSourceBranch = askSourceBranch;
|
|
60
|
+
async function askBranchUid() {
|
|
61
|
+
return await cli_utilities_1.cliux.inquire({
|
|
62
|
+
type: 'input',
|
|
63
|
+
message: 'CLI_BRANCH_BRANCH_UID',
|
|
64
|
+
name: 'branch_uid',
|
|
65
|
+
validate: inquireRequireFieldValidation,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
exports.askBranchUid = askBranchUid;
|
|
69
|
+
async function askConfirmation() {
|
|
70
|
+
const resp = await cli_utilities_1.cliux.inquire({
|
|
71
|
+
type: 'confirm',
|
|
72
|
+
message: 'Are you sure you want to delete this branch?',
|
|
73
|
+
name: 'confirm',
|
|
74
|
+
});
|
|
75
|
+
return resp;
|
|
76
|
+
}
|
|
77
|
+
exports.askConfirmation = askConfirmation;
|
|
78
|
+
function inquireRequireFieldValidation(input) {
|
|
79
|
+
if ((0, isEmpty_1.default)(input)) {
|
|
80
|
+
return cli_utilities_1.messageHandler.parse('CLI_BRANCH_REQUIRED_FIELD');
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
exports.inquireRequireFieldValidation = inquireRequireFieldValidation;
|
|
85
|
+
async function selectMergeStrategy() {
|
|
86
|
+
const strategy = await cli_utilities_1.cliux
|
|
87
|
+
.inquire({
|
|
88
|
+
type: 'list',
|
|
89
|
+
name: 'module',
|
|
90
|
+
choices: [
|
|
91
|
+
{ name: 'Merge, Prefer Base', value: 'merge_prefer_base' },
|
|
92
|
+
{ name: 'Merge, Prefer Compare', value: 'merge_prefer_compare' },
|
|
93
|
+
{ name: 'Merge, Ask for Preference', value: 'custom_preferences' },
|
|
94
|
+
{ name: 'Overwrite with Compare', value: 'overwrite_with_compare' },
|
|
95
|
+
],
|
|
96
|
+
message: 'What merge strategy would you like to choose? <doc link>',
|
|
97
|
+
})
|
|
98
|
+
.then((name) => name)
|
|
99
|
+
.catch((err) => {
|
|
100
|
+
cli_utilities_1.cliux.error('Failed to collect the merge strategy');
|
|
101
|
+
process.exit(1);
|
|
102
|
+
});
|
|
103
|
+
return strategy;
|
|
104
|
+
}
|
|
105
|
+
exports.selectMergeStrategy = selectMergeStrategy;
|
|
106
|
+
async function selectMergeStrategySubOptions() {
|
|
107
|
+
const strategy = await cli_utilities_1.cliux
|
|
108
|
+
.inquire({
|
|
109
|
+
type: 'list',
|
|
110
|
+
name: 'module',
|
|
111
|
+
choices: [
|
|
112
|
+
{ name: 'New in Compare Only', value: 'new' },
|
|
113
|
+
{ name: 'Modified Only', value: 'modified' },
|
|
114
|
+
{ name: 'Both', value: 'both' },
|
|
115
|
+
{ name: 'Go Back', value: 'previous' },
|
|
116
|
+
{ name: 'Start Over', value: 'restart' },
|
|
117
|
+
],
|
|
118
|
+
message: 'What do you want to merge?',
|
|
119
|
+
})
|
|
120
|
+
.then((name) => name)
|
|
121
|
+
.catch((err) => {
|
|
122
|
+
cli_utilities_1.cliux.error('Failed to collect the merge strategy');
|
|
123
|
+
process.exit(1);
|
|
124
|
+
});
|
|
125
|
+
return strategy;
|
|
126
|
+
}
|
|
127
|
+
exports.selectMergeStrategySubOptions = selectMergeStrategySubOptions;
|
|
128
|
+
async function selectMergeExecution() {
|
|
129
|
+
const strategy = await cli_utilities_1.cliux
|
|
130
|
+
.inquire({
|
|
131
|
+
type: 'list',
|
|
132
|
+
name: 'module',
|
|
133
|
+
choices: [
|
|
134
|
+
{ name: 'Execute Merge', value: 'both' },
|
|
135
|
+
{ name: 'Export Merge Summary', value: 'export' },
|
|
136
|
+
{ name: 'Go Back', value: 'previous' },
|
|
137
|
+
{ name: 'Start Over', value: 'restart' },
|
|
138
|
+
],
|
|
139
|
+
message: 'What would you like to do?',
|
|
140
|
+
})
|
|
141
|
+
.then((name) => name)
|
|
142
|
+
.catch((err) => {
|
|
143
|
+
cli_utilities_1.cliux.error('Exiting the merge process...');
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
|
146
|
+
return strategy;
|
|
147
|
+
}
|
|
148
|
+
exports.selectMergeExecution = selectMergeExecution;
|
|
149
|
+
async function askExportMergeSummaryPath() {
|
|
150
|
+
return await cli_utilities_1.cliux.inquire({
|
|
151
|
+
type: 'input',
|
|
152
|
+
message: 'Enter the file path to export the summary',
|
|
153
|
+
name: 'filePath',
|
|
154
|
+
validate: inquireRequireFieldValidation,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
exports.askExportMergeSummaryPath = askExportMergeSummaryPath;
|
|
158
|
+
async function askMergeComment() {
|
|
159
|
+
return await cli_utilities_1.cliux.inquire({
|
|
160
|
+
type: 'input',
|
|
161
|
+
message: 'Enter a comment for merge',
|
|
162
|
+
name: 'comment',
|
|
163
|
+
validate: inquireRequireFieldValidation,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
exports.askMergeComment = askMergeComment;
|
|
167
|
+
async function selectCustomPreferences(module, payload) {
|
|
168
|
+
// cliux.print(`\n Select from ${startCase(camelCase(module))}`, { color: 'yellow' });
|
|
169
|
+
var _a, _b, _c;
|
|
170
|
+
// parse rows
|
|
171
|
+
const tableRows = [];
|
|
172
|
+
if (((_a = payload.modified) === null || _a === void 0 ? void 0 : _a.length) || ((_b = payload.added) === null || _b === void 0 ? void 0 : _b.length) || ((_c = payload.deleted) === null || _c === void 0 ? void 0 : _c.length)) {
|
|
173
|
+
(0, forEach_1.default)(payload.added, (item) => {
|
|
174
|
+
const row = {};
|
|
175
|
+
row.name = `+ ${item.title}`;
|
|
176
|
+
row.status = 'added';
|
|
177
|
+
row.value = item;
|
|
178
|
+
tableRows.push(row);
|
|
179
|
+
});
|
|
180
|
+
(0, forEach_1.default)(payload.modified, (item) => {
|
|
181
|
+
const row = {};
|
|
182
|
+
row.name = `± ${item.title}`;
|
|
183
|
+
row.status = 'modified';
|
|
184
|
+
row.value = item;
|
|
185
|
+
tableRows.push(row);
|
|
186
|
+
});
|
|
187
|
+
(0, forEach_1.default)(payload.deleted, (item) => {
|
|
188
|
+
const row = {};
|
|
189
|
+
row.name = `- ${item.title}`;
|
|
190
|
+
row.status = 'deleted';
|
|
191
|
+
row.value = item;
|
|
192
|
+
tableRows.push(row);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const selectedStrategies = await cli_utilities_1.cliux.inquire({
|
|
199
|
+
type: 'table',
|
|
200
|
+
message: `Select the ${(0, startCase_1.default)((0, camelCase_1.default)(module))} changes for merge`,
|
|
201
|
+
name: 'mergeContentTypePreferences',
|
|
202
|
+
selectAll: true,
|
|
203
|
+
pageSize: 10,
|
|
204
|
+
columns: [
|
|
205
|
+
{
|
|
206
|
+
name: 'Merge Prefer Base',
|
|
207
|
+
value: 'merge_prefer_base',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'Merge Prefer Compare',
|
|
211
|
+
value: 'merge_prefer_compare',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: 'Overwrite(Use Compare)',
|
|
215
|
+
value: 'overwrite_with_compare',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'Ignore(Use Base)',
|
|
219
|
+
value: 'ignore',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
rows: tableRows,
|
|
223
|
+
});
|
|
224
|
+
let updatedArray = [];
|
|
225
|
+
(0, forEach_1.default)(selectedStrategies, (strategy, index) => {
|
|
226
|
+
const selectedItem = tableRows[index];
|
|
227
|
+
if (strategy && selectedItem) {
|
|
228
|
+
delete selectedItem.value.status;
|
|
229
|
+
selectedItem.value.merge_strategy = strategy;
|
|
230
|
+
updatedArray.push(selectedItem);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
return updatedArray; // selected items
|
|
234
|
+
}
|
|
235
|
+
exports.selectCustomPreferences = selectCustomPreferences;
|
|
236
|
+
async function askBranchNameConfirmation() {
|
|
237
|
+
return await cli_utilities_1.cliux.inquire({
|
|
238
|
+
type: 'input',
|
|
239
|
+
message: 'CLI_BRANCH_NAME_CONFIRMATION',
|
|
240
|
+
name: 'branch_name',
|
|
241
|
+
validate: inquireRequireFieldValidation,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
exports.askBranchNameConfirmation = askBranchNameConfirmation;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchMergeStatus = exports.executeMerge = exports.displayMergeSummary = exports.displayBranchStatus = exports.setupMergeInputs = exports.prepareMergeRequestPayload = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const startCase_1 = tslib_1.__importDefault(require("lodash/startCase"));
|
|
6
|
+
const camelCase_1 = tslib_1.__importDefault(require("lodash/camelCase"));
|
|
7
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
8
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
9
|
+
const _1 = require("./");
|
|
10
|
+
const prepareMergeRequestPayload = (options) => {
|
|
11
|
+
return {
|
|
12
|
+
base_branch: options.baseBranch,
|
|
13
|
+
compare_branch: options.compareBranch,
|
|
14
|
+
default_merge_strategy: options.strategy,
|
|
15
|
+
item_merge_strategies: options.itemMergeStrategies,
|
|
16
|
+
merge_comment: options.mergeComment,
|
|
17
|
+
no_revert: options.noRevert,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
exports.prepareMergeRequestPayload = prepareMergeRequestPayload;
|
|
21
|
+
const setupMergeInputs = async (mergeFlags) => {
|
|
22
|
+
if (!mergeFlags['stack-api-key']) {
|
|
23
|
+
mergeFlags['stack-api-key'] = await (0, _1.askStackAPIKey)();
|
|
24
|
+
}
|
|
25
|
+
if (!mergeFlags['compare-branch']) {
|
|
26
|
+
mergeFlags['compare-branch'] = await (0, _1.askCompareBranch)();
|
|
27
|
+
}
|
|
28
|
+
if (!mergeFlags['base-branch']) {
|
|
29
|
+
mergeFlags['base-branch'] = (0, _1.getbranchConfig)(mergeFlags['stack-api-key']);
|
|
30
|
+
if (!mergeFlags['base-branch']) {
|
|
31
|
+
mergeFlags['base-branch'] = await (0, _1.askBaseBranch)();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
cli_utilities_1.cliux.print(`\nBase branch: ${mergeFlags['base-branch']}\n`, { color: 'grey' });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return mergeFlags;
|
|
38
|
+
};
|
|
39
|
+
exports.setupMergeInputs = setupMergeInputs;
|
|
40
|
+
const displayBranchStatus = async (options) => {
|
|
41
|
+
const spinner = cli_utilities_1.cliux.loaderV2('Loading branch differences...');
|
|
42
|
+
let payload = {
|
|
43
|
+
module: '',
|
|
44
|
+
apiKey: options.stackAPIKey,
|
|
45
|
+
baseBranch: options.baseBranch,
|
|
46
|
+
compareBranch: options.compareBranch,
|
|
47
|
+
host: options.host,
|
|
48
|
+
};
|
|
49
|
+
payload.spinner = spinner;
|
|
50
|
+
const branchDiffData = await _1.branchDiffUtility.fetchBranchesDiff(payload);
|
|
51
|
+
const diffData = _1.branchDiffUtility.filterBranchDiffDataByModule(branchDiffData);
|
|
52
|
+
cli_utilities_1.cliux.loaderV2('', spinner);
|
|
53
|
+
let parsedResponse = {};
|
|
54
|
+
for (let module in diffData) {
|
|
55
|
+
const branchModuleData = diffData[module];
|
|
56
|
+
payload.module = module;
|
|
57
|
+
cli_utilities_1.cliux.print(' ');
|
|
58
|
+
cli_utilities_1.cliux.print(`${(0, startCase_1.default)((0, camelCase_1.default)(module))} Summary:`, { color: 'yellow' });
|
|
59
|
+
const diffSummary = _1.branchDiffUtility.parseSummary(branchModuleData, options.baseBranch, options.compareBranch);
|
|
60
|
+
_1.branchDiffUtility.printSummary(diffSummary);
|
|
61
|
+
const spinner1 = cli_utilities_1.cliux.loaderV2('Loading branch differences...');
|
|
62
|
+
if (options.format === 'compact-text') {
|
|
63
|
+
const branchTextRes = _1.branchDiffUtility.parseCompactText(branchModuleData);
|
|
64
|
+
cli_utilities_1.cliux.loaderV2('', spinner1);
|
|
65
|
+
_1.branchDiffUtility.printCompactTextView(branchTextRes);
|
|
66
|
+
parsedResponse[module] = branchTextRes;
|
|
67
|
+
}
|
|
68
|
+
else if (options.format === 'detailed-text') {
|
|
69
|
+
const verboseRes = await _1.branchDiffUtility.parseVerbose(branchModuleData, payload);
|
|
70
|
+
cli_utilities_1.cliux.loaderV2('', spinner1);
|
|
71
|
+
_1.branchDiffUtility.printVerboseTextView(verboseRes);
|
|
72
|
+
parsedResponse[module] = verboseRes;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return parsedResponse;
|
|
76
|
+
};
|
|
77
|
+
exports.displayBranchStatus = displayBranchStatus;
|
|
78
|
+
const displayMergeSummary = (options) => {
|
|
79
|
+
cli_utilities_1.cliux.print(' ');
|
|
80
|
+
cli_utilities_1.cliux.print(`Merge Summary:`, { color: 'yellow' });
|
|
81
|
+
for (let module in options.compareData) {
|
|
82
|
+
if (options.format === 'compact-text') {
|
|
83
|
+
_1.branchDiffUtility.printCompactTextView(options.compareData[module]);
|
|
84
|
+
}
|
|
85
|
+
else if (options.format === 'detailed-text') {
|
|
86
|
+
_1.branchDiffUtility.printVerboseTextView(options.compareData[module]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
cli_utilities_1.cliux.print(' ');
|
|
90
|
+
};
|
|
91
|
+
exports.displayMergeSummary = displayMergeSummary;
|
|
92
|
+
const executeMerge = async (apiKey, mergePayload, host) => {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
const stackAPIClient = await (await (0, cli_utilities_1.managementSDKClient)({ host })).stack({ api_key: apiKey });
|
|
95
|
+
const mergeResponse = await (0, _1.executeMergeRequest)(stackAPIClient, { params: mergePayload });
|
|
96
|
+
if (((_a = mergeResponse.merge_details) === null || _a === void 0 ? void 0 : _a.status) === 'in_progress') {
|
|
97
|
+
// TBD call the queue with the id
|
|
98
|
+
return await (0, exports.fetchMergeStatus)(stackAPIClient, { uid: mergeResponse.uid });
|
|
99
|
+
}
|
|
100
|
+
else if (((_b = mergeResponse.merge_details) === null || _b === void 0 ? void 0 : _b.status) === 'complete') {
|
|
101
|
+
// return the merge id success
|
|
102
|
+
return mergeResponse;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
exports.executeMerge = executeMerge;
|
|
106
|
+
const fetchMergeStatus = async (stackAPIClient, mergePayload) => {
|
|
107
|
+
return new Promise(async (resolve, reject) => {
|
|
108
|
+
var _a, _b, _c;
|
|
109
|
+
const mergeStatusResponse = await (0, _1.getMergeQueueStatus)(stackAPIClient, { uid: mergePayload.uid });
|
|
110
|
+
if (((_a = mergeStatusResponse === null || mergeStatusResponse === void 0 ? void 0 : mergeStatusResponse.queue) === null || _a === void 0 ? void 0 : _a.length) >= 1) {
|
|
111
|
+
const mergeRequestStatusResponse = mergeStatusResponse.queue[0];
|
|
112
|
+
const mergeStatus = (_b = mergeRequestStatusResponse.merge_details) === null || _b === void 0 ? void 0 : _b.status;
|
|
113
|
+
if (mergeStatus === 'complete') {
|
|
114
|
+
resolve(mergeRequestStatusResponse);
|
|
115
|
+
}
|
|
116
|
+
else if (mergeStatus === 'in-progress' || mergeStatus === 'in_progress') {
|
|
117
|
+
setTimeout(async () => {
|
|
118
|
+
await (0, exports.fetchMergeStatus)(stackAPIClient, mergePayload).then(resolve).catch(reject);
|
|
119
|
+
}, 5000);
|
|
120
|
+
}
|
|
121
|
+
else if (mergeStatus === 'failed') {
|
|
122
|
+
if (((_c = mergeRequestStatusResponse === null || mergeRequestStatusResponse === void 0 ? void 0 : mergeRequestStatusResponse.errors) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
123
|
+
const errorPath = path_1.default.join(process.cwd(), 'merge-error.log');
|
|
124
|
+
await (0, _1.writeFile)(errorPath, mergeRequestStatusResponse.errors);
|
|
125
|
+
cli_utilities_1.cliux.print(`\nComplete error log can be found in ${path_1.default.resolve(errorPath)}`, { color: 'grey' });
|
|
126
|
+
}
|
|
127
|
+
return reject(`merge uid: ${mergePayload.uid}`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return reject(`Invalid merge status found with merge ID ${mergePayload.uid}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return reject(`No queue found with merge ID ${mergePayload.uid}`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
exports.fetchMergeStatus = fetchMergeStatus;
|