Skip to content

Commit 338c14d

Browse files
committed
feat(cli): Comparing non changeable attributes and showing all changes
1 parent f9a9c9a commit 338c14d

File tree

2 files changed

+48
-38
lines changed

2 files changed

+48
-38
lines changed

templates/cli/lib/commands/push.js.twig

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ const POLL_MAX_DEBOUNCE = 30; // Times
4949

5050
let pollMaxDebounces = 30;
5151

52+
const changeableKeys = ['status', 'required', 'xdefault', 'elements', 'min', 'max', 'default', 'error'];
53+
5254
const awaitPools = {
5355
wipeAttributes: async (databaseId, collectionId, iteration = 1) => {
5456
if (iteration > pollMaxDebounces) {
@@ -695,63 +697,71 @@ const deepSimilar = (remote, local, collection) => {
695697
return undefined;
696698
}
697699

698-
const key = `${chalk.yellow(local.key)} in ${collection.name} (${collection['$id']})`;
700+
const keyName = `${chalk.yellow(local.key)} in ${collection.name} (${collection['$id']})`;
701+
const action = chalk.cyan('recreating');
702+
let reason = '';
703+
for (let key of Object.keys(remote)) {
704+
if (changeableKeys.includes(key)) {
705+
continue;
706+
}
699707

700-
if (remote.type !== local.type) {
701-
return { key, attribute: remote, reason: `type changed from ${chalk.red(remote.type)} to ${chalk.green(local.type)}` };
708+
if (remote[key] !== local[key]) {
709+
const bol = reason === '' ? '' : '\n';
710+
reason += `${bol}${key} changed from ${chalk.red(remote[key])} to ${chalk.green(local[key])}`;
711+
}
702712
}
703713

704-
if (remote.array !== local.array) {
705-
return { key, attribute: remote, reason: `array changed from ${chalk.red(remote.array)} to ${chalk.green(local.array)}` };
706-
}
714+
return reason === '' ? undefined : { key: keyName, attribute: remote, reason, action };
715+
}
707716

708-
if (remote.size !== local.size) {
709-
return { key, attribute: remote, reason: `size changed from ${chalk.red(remote.size)} to ${chalk.green(local.size)}` };
710-
}
717+
const findMatch = (attribute, attributes) => attributes.find((attr) => attr.key === attribute.key);
711718

712-
if (remote.relatedCollectionId !== local.relatedCollectionId) {
713-
return { key, attribute: remote, reason: `relationships collection id changed from ${chalk.red(remote.relatedCollectionId)} to ${chalk.green(local.relatedCollectionId)}` };
714-
}
719+
const mapChangeAttribute = (attribute, collection, isAdding) => {
720+
return {
721+
key: `${chalk.yellow(attribute.key)} in ${collection.name} (${collection['$id']})`,
722+
attribute,
723+
reason: isAdding ? 'Field doesn\'t exist on the remote server' : 'Field doesn\'t exist in appwrite.json file',
724+
action: isAdding ? chalk.green('adding') : chalk.red('deleting')
725+
};
715726

716-
if (remote.twoWay !== local.twoWay) {
717-
return { key, attribute: remote, reason: `relationships twoWay changed from ${chalk.red(remote.twoWay)} to ${chalk.green(local.twoWay)}` };
718-
}
727+
};
719728

720-
if (remote.twoWayKey !== local.twoWayKey) {
721-
return { key, attribute: remote, reason: `relationships twoWayKey changed from ${chalk.red(remote.twoWayKey)} to ${chalk.green(local.twoWayKey)}` };
722-
}
729+
const updatedList = async (remoteAttributes, localAttributes, collection) => {
730+
const deleting = remoteAttributes.filter((attribute) => !findMatch(attribute, localAttributes)).map((attr) => mapChangeAttribute(attr, collection, false));
731+
const adding = localAttributes.filter((attribute) => !findMatch(attribute, remoteAttributes)).map((attr) => mapChangeAttribute(attr, collection, true));
732+
const conflicts = remoteAttributes.map((attribute) => deepSimilar(attribute, findMatch(attribute, localAttributes), collection)).filter(attribute => attribute !== undefined);
733+
let changedAttributes = [];
723734

724-
return undefined;
725-
}
735+
const changing = [...deleting, ...adding, ...conflicts]
726736

727-
const findMatch = (attribute, attributes) => attributes.find((attr) => attr.key === attribute.key);
737+
if (changing.length === 0) {
738+
return changedAttributes;
739+
}
740+
log('There are pending changes in your collection deployment');
728741

729-
const updatedList = async (remoteAttributes, localAttributes, collection) => {
730-
const deleting = remoteAttributes.filter((attribute) => !findMatch(attribute, localAttributes));
731-
const changes = remoteAttributes.map((attribute) => deepSimilar(attribute, findMatch(attribute, localAttributes), collection)).filter(attribute => attribute !== undefined);
732-
let changedAttributes = [];
742+
drawTable(changing.map((change) => {
743+
return { Key: change.key, Action: change.action, Reason: change.reason, };
744+
}));
733745

734-
if (changes.length > 0) {
735-
log('There is a conflict in your collection deployment');
736-
drawTable(changes.map((change) => {
737-
return { Key: change.key, Reason: change.reason };
738-
}));
739-
const answers = await inquirer.prompt(questionsPushCollections[1]);
746+
const answers = await inquirer.prompt(questionsPushCollections[1]);
740747

741-
if (answers.changes.toLowerCase() !== 'yes') {
742-
return [];
743-
}
748+
if (answers.changes.toLowerCase() !== 'yes') {
749+
return changedAttributes;
750+
}
744751

745-
changedAttributes = changes.map((change) => change.attribute);
752+
if (conflicts.length > 0) {
753+
changedAttributes = conflicts.map((change) => change.attribute);
746754

747755
await Promise.all(changedAttributes.map((changed) => deleteAttribute(collection, changed)));
748756

749757
remoteAttributes = remoteAttributes.filter((attribute) => !findMatch(attribute, changedAttributes))
750758
}
751759

752-
await Promise.all(deleting.map((attribute) => deleteAttribute(collection, attribute)));
760+
const deletingAttributes = deleting.map((change) => change.attribute);
761+
762+
await Promise.all(deletingAttributes.map((attribute) => deleteAttribute(collection, attribute)));
753763

754-
const attributeKeys = [...remoteAttributes.map(attribute => attribute.key), ...deleting.map(attribute => attribute.key)]
764+
const attributeKeys = [...remoteAttributes.map(attribute => attribute.key), ...deletingAttributes.map(attribute => attribute.key)]
755765

756766
if (attributeKeys.length) {
757767
const deleteAttributesPoolStatus = await awaitPools.deleteAttributes(collection['databaseId'], collection['$id'], attributeKeys);

templates/cli/lib/questions.js.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ const questionsPushCollections = [
370370
{
371371
type: "input",
372372
name: "changes",
373-
message: `These are the pending destructive changes. To create the new fields, all data in the old ones will be ${chalk.red('deleted')}. Type "YES" to confirm`
373+
message: `Changes above will cause recreation of an attribute. All existing documents will lose data in those attributes. Type "YES" to confirm`
374374
}
375375
]
376376

0 commit comments

Comments
 (0)