UNPKG

@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
"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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