@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
380 lines • 35.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const xml2js = __importStar(require("xml2js"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs-extra"));
const rimraf = __importStar(require("rimraf"));
const _ = __importStar(require("lodash"));
const simple_git_1 = __importDefault(require("simple-git"));
const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger"));
const ProjectConfig_1 = __importDefault(require("../../project/ProjectConfig"));
const MetadataFiles_1 = __importDefault(require("../../metadata/MetadataFiles"));
const MetadataInfo_1 = require("../../metadata/MetadataInfo");
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
const GitDiffUtil_1 = __importDefault(require("../../git/GitDiffUtil"));
const deleteNotSupported = ['RecordType'];
const git = (0, simple_git_1.default)();
let sfdxManifest;
class PackageComponentDiff {
constructor(logger, sfdxPackage, revisionFrom, revisionTo, isDestructive) {
this.logger = logger;
this.sfdxPackage = sfdxPackage;
this.revisionFrom = revisionFrom;
this.revisionTo = revisionTo;
this.isDestructive = isDestructive;
if (this.revisionTo == null || this.revisionTo.trim() === '') {
this.revisionTo = 'HEAD';
}
if (this.revisionFrom == null) {
this.revisionFrom = '';
}
this.destructivePackageObjPost = [];
this.destructivePackageObjPre = [];
this.resultOutput = [];
sfdxManifest = ProjectConfig_1.default.getSFDXProjectConfig(null);
this.gitDiffUtils = new GitDiffUtil_1.default();
}
async build(outputFolder) {
rimraf.sync(outputFolder);
const sepRegex = /\n|\r/;
let data = '';
//check if same commit
const commitFrom = await git.raw(['rev-list', '-n', '1', this.revisionFrom]);
const commitTo = await git.raw(['rev-list', '-n', '1', this.revisionTo]);
if (commitFrom === commitTo) {
throw new Error(`Unable to compute diff, as both commits are same`);
}
//Make it relative to make the command works from a project created as a subfolder in a repository
data = await git.diff([
'--raw',
this.revisionFrom,
this.revisionTo,
'--relative',
ProjectConfig_1.default.getPackageDescriptorFromConfig(this.sfdxPackage, sfdxManifest).path,
]);
let content = data.split(sepRegex);
let diffFile = await this.parseContent(content);
await this.gitDiffUtils.fetchFileListRevisionTo(this.revisionTo, this.logger);
let filesToCopy = diffFile.addedEdited;
let deletedFiles = diffFile.deleted;
deletedFiles = deletedFiles.filter((deleted) => {
let found = false;
let deletedMetadata = MetadataFiles_1.default.getFullApiNameWithExtension(deleted.path);
for (let i = 0; i < filesToCopy.length; i++) {
let addedOrEdited = MetadataFiles_1.default.getFullApiNameWithExtension(filesToCopy[i].path);
if (deletedMetadata === addedOrEdited) {
found = true;
break;
}
}
return !found;
});
if (fs.existsSync(outputFolder) == false) {
fs.mkdirSync(outputFolder);
}
const resolver = new source_deploy_retrieve_1.MetadataResolver();
if (filesToCopy && filesToCopy.length > 0) {
for (let i = 0; i < filesToCopy.length; i++) {
try {
let filePath = filesToCopy[i].path;
let sourceComponents = resolver.getComponentsFromPath(filePath);
for (const sourceComponent of sourceComponents) {
if (sourceComponent.type.strategies?.adapter == AdapterId.MatchingContentFile) {
await this.gitDiffUtils.copyFile(sourceComponent.xml, outputFolder, this.logger);
await this.gitDiffUtils.copyFile(sourceComponent.content, outputFolder, this.logger);
}
else if (sourceComponent.type.strategies?.adapter == AdapterId.MixedContent) {
await this.gitDiffUtils.copyFile(sourceComponent.xml, outputFolder, this.logger);
if (path.extname(sourceComponent.content))
await this.gitDiffUtils.copyFile(sourceComponent.content, outputFolder, this.logger);
else
await this.gitDiffUtils.copyFolder(sourceComponent.content, outputFolder, this.logger);
}
else if (sourceComponent.type.strategies?.adapter == AdapterId.Decomposed) {
await this.gitDiffUtils.copyFile(sourceComponent.xml, outputFolder, this.logger);
}
else if (sourceComponent.type.strategies?.adapter == AdapterId.Bundle) {
await this.gitDiffUtils.copyFolder(sourceComponent.content, outputFolder, this.logger);
}
else {
await this.gitDiffUtils.copyFile(sourceComponent.xml, outputFolder, this.logger);
}
}
}
catch (error) {
if (error.message.includes(`Unable to find the required file`))
throw error;
//Metadata resolver is not respecting forceignores at this stage
// So it fails on diff packages with post deploy, so lets ignore and move on
sfp_logger_1.default.log(`Error while inferencing type of ${filesToCopy[i].path} to ${outputFolder} : ${error.message}`, sfp_logger_1.LoggerLevel.TRACE, this.logger);
}
}
}
if (this.isDestructive) {
sfp_logger_1.default.log('Creating Destructive Manifest..', sfp_logger_1.LoggerLevel.TRACE, this.logger);
await this.createDestructiveChanges(deletedFiles, outputFolder);
}
//Folder is empty after all this operations, return without copying additional files
if (fs.readdirSync(outputFolder).length === 0) {
rimraf.sync(outputFolder);
return null;
}
sfp_logger_1.default.log(`Generating output summary`, sfp_logger_1.LoggerLevel.TRACE, this.logger);
return this.resultOutput;
}
//TODO: Refactor using proper ignore
checkForIngore(pathToIgnore, filePath) {
pathToIgnore = pathToIgnore || [];
if (pathToIgnore.length === 0) {
return true;
}
let returnVal = true;
pathToIgnore.forEach((ignore) => {
if (path.resolve(ignore) === path.resolve(filePath) ||
path.resolve(filePath).includes(path.resolve(ignore))) {
returnVal = false;
}
});
return returnVal;
}
async createDestructiveChanges(filePaths, outputFolder) {
if (_.isNil(this.destructivePackageObjPost)) {
this.destructivePackageObjPost = [];
}
else {
this.destructivePackageObjPost = this.destructivePackageObjPost.filter((metaType) => {
return !_.isNil(metaType.members) && metaType.members.length > 0;
});
}
this.destructivePackageObjPre = [];
//returns root, dir, base and name
for (let i = 0; i < filePaths.length; i++) {
let filePath = filePaths[i].path;
try {
let matcher = filePath.match(MetadataInfo_1.SOURCE_EXTENSION_REGEX);
let extension = '';
if (matcher) {
extension = matcher[0];
}
else {
extension = path.parse(filePath).ext;
}
let name = MetadataInfo_1.MetadataInfo.getMetadataName(filePath);
if (name) {
if (!MetadataFiles_1.default.isCustomMetadata(filePath, name)) {
// avoid to generate destructive for Standard Components
//Support on Custom Fields and Custom Objects for now
this.resultOutput.push({
action: 'Skip',
componentName: MetadataFiles_1.default.getMemberNameFromFilepath(filePath, name),
metadataType: 'StandardField/CustomMetadata',
message: '',
path: '--',
});
continue;
}
let member = MetadataFiles_1.default.getMemberNameFromFilepath(filePath, name);
if (name === MetadataInfo_1.METADATA_INFO.CustomField.xmlName) {
let isFormular = await this.gitDiffUtils.isFileIncludesContent(filePaths[i], '<formula>');
if (isFormular) {
this.destructivePackageObjPre = this.buildDestructiveTypeObj(this.destructivePackageObjPre, name, member);
sfp_logger_1.default.log(`${filePath} ${MetadataFiles_1.default.isCustomMetadata(filePath, name)}`, sfp_logger_1.LoggerLevel.DEBUG, this.logger);
this.resultOutput.push({
action: 'Delete',
componentName: member,
metadataType: name,
message: '',
path: 'Manual Intervention Required',
});
}
else {
this.destructivePackageObjPost = this.buildDestructiveTypeObj(this.destructivePackageObjPost, name, member);
}
sfp_logger_1.default.log(`${filePath} ${MetadataFiles_1.default.isCustomMetadata(filePath, name)}`, sfp_logger_1.LoggerLevel.DEBUG, this.logger);
this.resultOutput.push({
action: 'Delete',
componentName: member,
metadataType: name,
message: '',
path: 'destructiveChanges.xml',
});
}
else {
if (!deleteNotSupported.includes(name)) {
this.destructivePackageObjPost = this.buildDestructiveTypeObj(this.destructivePackageObjPost, name, member);
this.resultOutput.push({
action: 'Delete',
componentName: member,
metadataType: name,
message: '',
path: 'destructiveChanges.xml',
});
}
else {
//add the component in the manual action list
// TODO
}
}
}
}
catch (ex) {
this.resultOutput.push({
action: 'ERROR',
componentName: '',
metadataType: '',
message: ex.message,
path: filePath,
});
}
}
this.writeDestructivechanges(this.destructivePackageObjPost, outputFolder, 'destructiveChanges.xml');
}
writeDestructivechanges(destrucObj, outputFolder, fileName) {
//ensure unique component per type
for (let i = 0; i < destrucObj.length; i++) {
destrucObj[i].members = _.uniq(destrucObj[i].members);
}
destrucObj = destrucObj.filter((metaType) => {
return metaType.members && metaType.members.length > 0;
});
if (destrucObj.length > 0) {
let dest = {
Package: {
$: {
xmlns: 'http://soap.sforce.com/2006/04/metadata',
},
types: destrucObj,
},
};
let destructivePackageName = fileName;
let filepath = path.join(outputFolder, destructivePackageName);
let builder = new xml2js.Builder();
let xml = builder.buildObject(dest);
fs.writeFileSync(filepath, xml);
}
}
buildDestructiveTypeObj(destructiveObj, name, member) {
let typeIsPresent = false;
for (let i = 0; i < destructiveObj.length; i++) {
if (destructiveObj[i].name === name) {
typeIsPresent = true;
destructiveObj[i].members.push(member);
break;
}
}
let typeNode;
if (typeIsPresent === false) {
typeNode = {
name: name,
members: [member],
};
destructiveObj.push(typeNode);
}
return destructiveObj;
}
async parseContent(fileContents) {
const statusRegEx = /\sA\t|\sM\t|\sD\t/;
const renamedRegEx = /\sR[0-9]{3}\t|\sC[0-9]{3}\t/;
const tabRegEx = /\t/;
const deletedFileRegEx = new RegExp(/\sD\t/);
const lineBreakRegEx = /\r?\n|\r|( $)/;
let metadataFiles = new MetadataFiles_1.default();
let diffFile = {
deleted: [],
addedEdited: [],
};
for (let i = 0; i < fileContents.length; i++) {
if (statusRegEx.test(fileContents[i])) {
let lineParts = fileContents[i].split(statusRegEx);
let finalPath = path.join('.', lineParts[1].replace(lineBreakRegEx, ''));
finalPath = finalPath.trim();
finalPath = finalPath.replace('\\303\\251', 'é');
if (!(await metadataFiles.isInModuleFolder(finalPath))) {
continue;
}
if (!metadataFiles.accepts(finalPath)) {
continue;
}
let revisionPart = lineParts[0].split(/\t|\s/);
if (deletedFileRegEx.test(fileContents[i])) {
//Deleted
diffFile.deleted.push({
revisionFrom: revisionPart[2].substring(0, 9),
revisionTo: revisionPart[3].substring(0, 9),
path: finalPath,
});
}
else {
// Added or edited
diffFile.addedEdited.push({
revisionFrom: revisionPart[2].substring(0, 9),
revisionTo: revisionPart[3].substring(0, 9),
path: finalPath,
});
}
}
else if (renamedRegEx.test(fileContents[i])) {
let lineParts = fileContents[i].split(renamedRegEx);
let paths = lineParts[1].trim().split(tabRegEx);
let finalPath = path.join('.', paths[1].trim());
finalPath = finalPath.replace('\\303\\251', 'é');
let revisionPart = lineParts[0].split(/\t|\s/);
if (!(await metadataFiles.isInModuleFolder(finalPath))) {
continue;
}
if (!metadataFiles.accepts(paths[0].trim())) {
continue;
}
diffFile.addedEdited.push({
revisionFrom: '0000000',
revisionTo: revisionPart[3],
renamedPath: path.join('.', paths[0].trim()),
path: finalPath,
});
//allow deletion of renamed components
diffFile.deleted.push({
revisionFrom: revisionPart[2],
revisionTo: '0000000',
path: paths[0].trim(),
});
}
}
return diffFile;
}
}
exports.default = PackageComponentDiff;
var AdapterId;
(function (AdapterId) {
AdapterId["Bundle"] = "bundle";
AdapterId["Decomposed"] = "decomposed";
AdapterId["Default"] = "default";
AdapterId["MatchingContentFile"] = "matchingContentFile";
AdapterId["MixedContent"] = "mixedContent";
})(AdapterId || (AdapterId = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFja2FnZUNvbXBvbmVudERpZmYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9wYWNrYWdlL2RpZmYvUGFja2FnZUNvbXBvbmVudERpZmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQywyQ0FBNkI7QUFDN0IsNkNBQStCO0FBQy9CLCtDQUFpQztBQUNqQywwQ0FBNEI7QUFDNUIsNERBQW1DO0FBQ25DLG1FQUFzRTtBQUN0RSxnRkFBd0Q7QUFDeEQsaUZBQXlEO0FBQ3pELDhEQUFrRztBQUNsRywrRUFBc0U7QUFDdEUsd0VBQStFO0FBRS9FLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUMxQyxNQUFNLEdBQUcsR0FBRyxJQUFBLG9CQUFTLEdBQUUsQ0FBQztBQUN4QixJQUFJLFlBQVksQ0FBQztBQUVqQixNQUFxQixvQkFBb0I7SUFZckMsWUFDWSxNQUFjLEVBQ2QsV0FBbUIsRUFDbkIsWUFBcUIsRUFDckIsVUFBbUIsRUFDbkIsYUFBdUI7UUFKdkIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1FBQ25CLGlCQUFZLEdBQVosWUFBWSxDQUFTO1FBQ3JCLGVBQVUsR0FBVixVQUFVLENBQVM7UUFDbkIsa0JBQWEsR0FBYixhQUFhLENBQVU7UUFFL0IsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQzNELElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUNELElBQUks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