Skip to content

Commit

Permalink
Merge pull request #685 from Accenture/develop
Browse files Browse the repository at this point in the history
4.3.0
  • Loading branch information
JoernBerkefeld authored Jan 30, 2023
2 parents 6b9144b + 0aed3a1 commit 6ded325
Show file tree
Hide file tree
Showing 90 changed files with 5,757 additions and 1,036 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ body:
label: Version
description: What version of our software are you running? (mcdev --version)
options:
- 4.3.0
- 4.2.1
- 4.2.0
- 4.1.12
Expand Down
981 changes: 700 additions & 281 deletions docs/dist/documentation.md

Large diffs are not rendered by default.

36 changes: 21 additions & 15 deletions lib/Deployer.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,38 +238,44 @@ class Deployer {
Object.keys(this.metadata)
);
}
const foundDeployTypes = Object.keys(this.metadata).map((item) =>
item === 'asset' && Util.includesStartsWith(typeArr, item)
? typeArr[Util.includesStartsWithIndex(typeArr, item)]
: item
);
const foundDeployTypes = Object.keys(this.metadata)
.map((type) =>
type === 'asset' && Util.includesStartsWith(typeArr, type)
? typeArr[Util.includesStartsWithIndex(typeArr, type)]
: type
)
// remove empty types
.filter((type) => Object.keys(this.metadata[type]).length);
if (!foundDeployTypes.length) {
throw new Error('No metadata found for deployment');
}
const deployOrder = Util.getMetadataHierachy(foundDeployTypes);
// build cache, including all metadata types which will be deployed (Avoids retrieve later)
for (const metadataType of deployOrder) {
const [type, subType] = metadataType.split('-');
for (const metadataType in deployOrder) {
const type = metadataType;
const subTypeArr = deployOrder[metadataType];
// add metadata & client to metadata process class instead of passing cache/mapping every time
MetadataTypeInfo[type].client = auth.getSDK(this.buObject);
MetadataTypeInfo[type].properties = this.properties;
MetadataTypeInfo[type].buObject = this.buObject;
Util.logger.info('Caching dependent Metadata: ' + metadataType);
const result = await MetadataTypeInfo[type].retrieveForCache(this.buObject, subType);
Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
Util.logSubtypes(subTypeArr);
const result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr);
cache.setMetadata(type, result.metadata);
}
/** @type {TYPE.MultiMetadataTypeMap} */
const multiMetadataTypeMap = {};
// deploy metadata files, extending cache once deploys
for (const metadataType of deployOrder) {
// TODO rewrite to allow deploying only a specific sub-type
// const [type, subType] = metadataType.split('-');
const type = metadataType.split('-')[0];
for (const metadataType in deployOrder) {
// TODO rewrite to allow deploying only a specific sub-type; currently, subtypes are ignored when executing deploy
const type = metadataType;
if (this.metadata[type]) {
Util.logger.info('Deploying: ' + metadataType);

const result = await MetadataTypeInfo[type].deploy(
this.metadata[type],
this.deployDir,
this.retrieveDir,
this.buObject
this.retrieveDir
);
multiMetadataTypeMap[type] = result;
cache.mergeMetadata(type, result);
Expand Down
42 changes: 23 additions & 19 deletions lib/Retriever.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,12 @@ class Retriever {
// assuming TypeKeyCombo was provided
typeKeyMap = namesOrKeys;
}
// defined colors for optionally printing the keys we filtered by
const color = {
reset: '\x1B[0m',
dim: '\x1B[2m',
};
// ensure we know which real dependencies we have to ensure we cache those completely
const dependencies = this._getTypeDependencies(metadataTypes);

for (const metadataType of Util.getMetadataHierachy(metadataTypes)) {
const [type, subType] = metadataType.split('-');
const deployOrder = Util.getMetadataHierachy(metadataTypes);
for (const metadataType in deployOrder) {
const type = metadataType;
const subTypeArr = deployOrder[metadataType];
// if types were added by getMetadataHierachy() for caching, make sure the key-list is set to [null] for them which will retrieve all
typeKeyMap[metadataType] = typeKeyMap[metadataType] || [null];
// add client to metadata process class instead of passing every time
Expand All @@ -78,26 +74,36 @@ class Retriever {
try {
let result;
if (!metadataTypes.includes(type) && !metadataTypes.includes(metadataType)) {
// type not in list of types to retrieve, but is a dependency of one of them
if (changelogOnly && type !== 'folder') {
// no extra caching needed for list view except for folders
continue;
}
Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
result = await MetadataTypeInfo[type].retrieveForCache(this.buObject, subType);
Util.logSubtypes(subTypeArr);
result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr);
} else if (templateVariables) {
// type is in list of types to retrieve and we have template variables
Util.logger.info(`Retrieving as Template: ${metadataType}`);

if (subTypeArr?.length > 1) {
Util.logger.warn(
`retrieveAsTemplate only works with one subtype, ignoring all but first subtype from your list: ${subTypeArr.join(
', '
)}`
);
}
result = await Promise.all(
typeKeyMap[metadataType].map((name) =>
MetadataTypeInfo[type].retrieveAsTemplate(
this.templateDir,
name,
templateVariables,
subType
subTypeArr?.[0]
)
)
);
} else {
// type is in list of types to retrieve and we don't have template variables
let cacheResult = null;
if (
(typeKeyMap[metadataType].length > 1 ||
Expand All @@ -106,28 +112,26 @@ class Retriever {
) {
// if we have a key-list and the type is a dependency, we need to cache the whole type
Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
Util.logSubtypes(subTypeArr);
cacheResult = await MetadataTypeInfo[type].retrieveForCache(
this.buObject,
subType
null,
subTypeArr
);
}
Util.logger.info(
`Retrieving: ${metadataType}` +
(typeKeyMap[metadataType][0] === null
? ''
: ` ${color.dim}(Keys: ${typeKeyMap[metadataType].join(', ')})${
color.reset
}`)
: Util.getKeysString(typeKeyMap[metadataType]))
);
result = await (changelogOnly
? MetadataTypeInfo[type].retrieveChangelog(this.buObject, null, subType)
? MetadataTypeInfo[type].retrieveChangelog(null, subTypeArr)
: Promise.all(
typeKeyMap[metadataType].map((key) =>
MetadataTypeInfo[type].retrieve(
this.savePath,
null,
this.buObject,
subType,
subTypeArr,
key
)
)
Expand Down
42 changes: 36 additions & 6 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ yargs
Mcdev.initProject(argv.credentialsName);
},
})
.command({
command: 'join',
desc: `clones an existing project from git`,
handler: (argv) => {
Mcdev.setSkipInteraction(argv.skipInteraction);
Mcdev.setLoggingLevel(argv);
Mcdev.joinProject();
},
})
.command({
command: 'reloadBUs [credentialsName]',
aliases: ['rb'],
Expand Down Expand Up @@ -221,9 +230,7 @@ yargs
handler: (argv) => {
Mcdev.setSkipInteraction(argv.skipInteraction);
Mcdev.setLoggingLevel(argv);
const keyArr = csvToArray(argv.KEY);

Mcdev.buildTemplate(argv.BU, argv.TYPE, keyArr, argv.MARKET);
Mcdev.buildTemplate(argv.BU, argv.TYPE, csvToArray(argv.KEY), argv.MARKET);
},
})
.command({
Expand Down Expand Up @@ -345,9 +352,32 @@ yargs
handler: (argv) => {
Mcdev.setSkipInteraction(argv.skipInteraction);
Mcdev.setLoggingLevel(argv);
const keyArr = csvToArray(argv.KEY);

Mcdev.getFilesToCommit(argv.BU, argv.TYPE, keyArr);
Mcdev.getFilesToCommit(argv.BU, argv.TYPE, csvToArray(argv.KEY));
},
})
.command({
command: 'refresh <BU> [TYPE] [KEY]',
aliases: ['re'],
desc: 'ensures that updates are properly published',
builder: (yargs) => {
yargs
.positional('BU', {
type: 'string',
describe: 'the business unit to execute the refresh on',
})
.positional('TYPE', {
type: 'string',
describe: 'metadata type',
})
.positional('KEY', {
type: 'string',
describe: 'key(s) of the metadata component(s)',
});
},
handler: (argv) => {
Mcdev.setSkipInteraction(argv.skipInteraction);
Mcdev.setLoggingLevel(argv);
Mcdev.refresh(argv.BU, argv.TYPE, csvToArray(argv.KEY));
},
})
.command({
Expand Down
66 changes: 56 additions & 10 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class Mcdev {
if (
properties.credentials &&
(!properties.credentials[cred] ||
(bu !== '*' && properties.credentials[cred].businessUnits[bu]))
(bu !== '*' && !properties.credentials[cred].businessUnits[bu]))
) {
const buObject = await Cli.getCredentialObject(
properties,
Expand Down Expand Up @@ -220,7 +220,7 @@ class Mcdev {
for (const selectedType of Array.isArray(selectedTypesArr)
? selectedTypesArr
: Object.keys(selectedTypesArr)) {
const [type, subType] = selectedType ? selectedType.split('-') : [];
const [type, subType] = Util.getTypeAndSubType(selectedType);
const removePathArr = [properties.directories.retrieve, cred, bu, type];
if (
type &&
Expand Down Expand Up @@ -293,6 +293,15 @@ class Mcdev {
const properties = await config.getProperties(!!credentialsName, true);
await Init.initProject(properties, credentialsName);
}
/**
* Clones an existing project from git repository and installs it
*
* @returns {Promise.<void>} -
*/
static async joinProject() {
Util.logger.info('mcdev:: Joining an existing project');
await Init.joinProject();
}

/**
* Refreshes BU names and ID's from MC instance
Expand Down Expand Up @@ -338,7 +347,8 @@ class Mcdev {
);
if (buObject !== null) {
MetadataTypeInfo[type].properties = properties;
MetadataTypeInfo[type].document(buObject);
MetadataTypeInfo[type].buObject = buObject;
MetadataTypeInfo[type].document();
}
} catch (ex) {
Util.logger.error('mcdev.document ' + ex.message);
Expand All @@ -350,36 +360,72 @@ class Mcdev {
}

/**
* Creates docs for supported metadata types in Markdown and/or HTML format
* deletes metadata from MC instance by key
*
* @param {string} businessUnit references credentials from properties.json
* @param {string} type supported metadata type
* @param {string} customerKey Identifier of data extension
* @param {string} customerKey Identifier of metadata
* @returns {Promise.<void>} -
*/
static async deleteByKey(businessUnit, type, customerKey) {
Util.logger.info('mcdev:: delete');
if (!Util._isValidType(type)) {
return;
}
const properties = await config.getProperties();
if (!(await config.checkProperties(properties))) {
return null;
}
const buObject = await Cli.getCredentialObject(properties, businessUnit);
if (buObject !== null) {
if ('string' !== typeof type) {
Util.logger.error('mcdev.delete failed: Bad metadata type passed in');
try {
MetadataTypeInfo[type].client = auth.getSDK(buObject);
} catch (ex) {
Util.logger.error(ex.message);
return;
}
try {
MetadataTypeInfo[type].properties = properties;
MetadataTypeInfo[type].buObject = buObject;
await MetadataTypeInfo[type].deleteByKey(customerKey);
} catch (ex) {
Util.logger.errorStack(ex, ` - Deleting ${type} failed`);
}
}
}
/**
* ensures triggered sends are restarted to ensure they pick up on changes of the underlying emails
*
* @param {string} businessUnit references credentials from properties.json
* @param {string} type references credentials from properties.json
* @param {string[]} [keyArr] metadata keys
* @returns {Promise.<void>} -
*/
static async refresh(businessUnit, type, keyArr) {
Util.logger.info('mcdev:: refresh');
if (!type || !Util._isValidType(type, true)) {
type = 'triggeredSendDefinition';
Util.logger.info(' - setting type to ' + type);
}
const properties = await config.getProperties();
if (!(await config.checkProperties(properties))) {
return null;
}
const buObject = await Cli.getCredentialObject(properties, businessUnit);
if (buObject !== null) {
try {
MetadataTypeInfo[type].client = auth.getSDK(buObject);
} catch (ex) {
Util.logger.error(ex.message);
return;
}
try {
cache.initCache(buObject);
MetadataTypeInfo[type].properties = properties;
MetadataTypeInfo[type].deleteByKey(buObject, customerKey);
MetadataTypeInfo[type].buObject = buObject;
await MetadataTypeInfo[type].refresh(keyArr);
} catch (ex) {
Util.logger.error('mcdev.delete ' + ex.message);
Util.logger.errorStack(ex, 'mcdev.refresh ' + ex.message);
}
}
}
Expand Down Expand Up @@ -472,7 +518,7 @@ class Mcdev {
if (!Util._isValidType(selectedType)) {
return;
}
const [type, subType] = selectedType ? selectedType.split('-') : [];
const [type, subType] = Util.getTypeAndSubType(selectedType);

let retrieveTypesArr;
if (
Expand Down
Loading

0 comments on commit 6ded325

Please sign in to comment.