UNPKG

@flxbl-io/sfp

Version:

sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model

225 lines 23.8 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 sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const SFPStatsSender_1 = __importDefault(require("../../stats/SFPStatsSender")); const PackageEmptyChecker_1 = __importDefault(require("../validators/PackageEmptyChecker")); const SfpPackage_1 = require("../SfpPackage"); const SFPOrg_1 = __importDefault(require("../../org/SFPOrg")); const CreateSourcePackageImpl_1 = __importDefault(require("./CreateSourcePackageImpl")); const PackageToComponent_1 = __importDefault(require("../components/PackageToComponent")); const path_1 = __importDefault(require("path")); const fs = __importStar(require("fs-extra")); const ImpactedApexTestClassFetcher_1 = __importDefault(require("../../apextest/ImpactedApexTestClassFetcher")); const SourceToMDAPIConvertor_1 = __importDefault(require("../packageFormatConvertors/SourceToMDAPIConvertor")); const PackageManifest_1 = __importDefault(require("../components/PackageManifest")); const MetadataCount_1 = __importDefault(require("../components/MetadataCount")); const rimraf = __importStar(require("rimraf")); const PackageComponentDiff_1 = __importDefault(require("../diff/PackageComponentDiff")); class CreateDiffPackageImp extends CreateSourcePackageImpl_1.default { constructor(projectDirectory, sfpPackage, packageCreationParams, logger, params) { super(projectDirectory, sfpPackage, packageCreationParams, logger, params); this.projectDirectory = projectDirectory; this.sfpPackage = sfpPackage; this.packageCreationParams = packageCreationParams; this.logger = logger; this.params = params; } getTypeOfPackage() { return SfpPackage_1.PackageType.Diff; } printAdditionalPackageSpecificHeaders() { } isEmptyPackage(projectDirectory, packageDirectory) { return PackageEmptyChecker_1.default.isEmptyFolder(projectDirectory, packageDirectory); } async preCreatePackage(sfpPackage) { const devhubOrg = await SFPOrg_1.default.create({ aliasOrUsername: this.packageCreationParams.devHub }); //Fetch Baseline commit from DevHub or the provided org for validation let commitsOfPackagesInstalled = {}; commitsOfPackagesInstalled = await this.getCommitsOfPackagesInstalledInOrg(devhubOrg); if (this.packageCreationParams.revisionFrom) { this.sfpPackage.commitSHAFrom = this.packageCreationParams.revisionFrom; } else if (commitsOfPackagesInstalled[this.sfpPackage.packageName]) { this.sfpPackage.commitSHAFrom = commitsOfPackagesInstalled[this.sfpPackage.packageName]; } else { this.sfpPackage.commitSHAFrom = this.sfpPackage.sourceVersion; } if (this.packageCreationParams.revisionTo) { this.sfpPackage.commitSHATo = this.packageCreationParams.revisionTo; } else { this.sfpPackage.commitSHATo = this.sfpPackage.sourceVersion; } } async getCommitsOfPackagesInstalledInOrg(diffTargetSfpOrg) { let installedArtifacts = await diffTargetSfpOrg.getInstalledArtifacts(); let packagesInstalledInOrgMappedToCommits = await this.mapInstalledArtifactstoPkgAndCommits(installedArtifacts); return packagesInstalledInOrgMappedToCommits; } async createPackage(sfpPackage) { //Unresolved SHAs can be same if the package is not installed in the org or is the same if (this.sfpPackage.commitSHAFrom != this.sfpPackage.commitSHATo) { try { let packageComponentDiffer = new PackageComponentDiff_1.default(this.logger, this.sfpPackage.packageName, this.sfpPackage.commitSHAFrom, this.sfpPackage.commitSHATo, true); await packageComponentDiffer.build(path_1.default.join(sfpPackage.workingDirectory, 'diff')); } catch (error) { //if both are same after git resolution.. just do nothing, treat is a normal source package if (error.message.includes('Unable to compute diff, as both commits are same')) { sfp_logger_1.default.log(`Both commits are same, treating it as an empty package`, sfp_logger_1.LoggerLevel.WARN, this.logger); //Create an empty diff directory to force skip of packages const diffSrcDir = path_1.default.join(sfpPackage.workingDirectory, `diff/${sfpPackage.packageDirectory}`); fs.mkdirpSync(diffSrcDir); } else throw error; } await this.introspectDiffPackageCreated(sfpPackage, this.params, this.logger); await this.replaceSourceWithDiff(sfpPackage.workingDirectory, sfpPackage.packageDirectory, `diff/${sfpPackage.packageDirectory}`); SFPStatsSender_1.default.logGauge('package.metadatacount', sfpPackage.metadataCount, { package: sfpPackage.packageName, type: sfpPackage.packageType, }); } } postCreatePackage(sfpPackage) { } async replaceSourceWithDiff(workingDirectory, packageDirectory, diffPackageDirectory) { const srcDir = path_1.default.join(workingDirectory, packageDirectory); const diffSrcDir = path_1.default.join(workingDirectory, diffPackageDirectory); // Check if src directories exist, if so remove them if (fs.pathExistsSync(srcDir)) await fs.remove(srcDir); // Rename diff/src directory to src if (fs.pathExistsSync(diffSrcDir)) await fs.move(diffSrcDir, srcDir); else { // Ensure package directory exists await fs.mkdirpSync(diffSrcDir); await fs.move(diffSrcDir, srcDir); } //check if destructiveChanges.xml exist in diff directory const destructiveChangesPath = path_1.default.join(workingDirectory, 'diff', 'destructiveChanges.xml'); if (fs.existsSync(destructiveChangesPath)) { //Move destructiveChanges.xml to diff directory await fs.move(destructiveChangesPath, path_1.default.join(workingDirectory, 'destructiveChanges.xml')); } //remove diffSrcDir if (fs.pathExistsSync(path_1.default.join(workingDirectory, 'diff'))) fs.removeSync(path_1.default.join(workingDirectory, 'diff')); } async mapInstalledArtifactstoPkgAndCommits(installedArtifacts) { let packagesMappedToLastKnownCommitId = {}; packagesMappedToLastKnownCommitId = await getPackagesToCommits(installedArtifacts); return packagesMappedToLastKnownCommitId; async function getPackagesToCommits(installedArtifacts) { const packagesToCommits = {}; let jsonOverrides = {}; // Add an option to override diff package from during debugging // Also useful for when the record is yet to be baselined try { const jsonData = await fs.readFile('diffPackageOverrides.json', 'utf8'); jsonOverrides = JSON.parse(jsonData); } catch (error) { console.log('No JSON override file found or there is an error reading it'); } // Merge the installedArtifacts data with the JSON overrides if (installedArtifacts) { installedArtifacts.forEach((artifact) => { packagesToCommits[artifact.Name] = artifact.CommitId__c; }); } // Add additional packages from the JSON overrides that are not in installedArtifacts Object.keys(jsonOverrides).forEach((pkgName) => { if (!packagesToCommits.hasOwnProperty(pkgName)) { packagesToCommits[pkgName] = jsonOverrides[pkgName]; } }); if (process.env.VALIDATE_REMOVE_PKG) delete packagesToCommits[process.env.VALIDATE_REMOVE_PKG]; return packagesToCommits; } } async introspectDiffPackageCreated(sfpPackage, packageParams, logger) { let workingDirectory = path_1.default.join(sfpPackage.workingDirectory, 'diff'); if (fs.existsSync(path_1.default.join(workingDirectory, sfpPackage.packageDirectory))) { let changedComponents = new PackageToComponent_1.default(sfpPackage.packageName, path_1.default.join(workingDirectory, sfpPackage.packageDirectory)).generateComponents(); let impactedApexTestClassFetcher = new ImpactedApexTestClassFetcher_1.default(sfpPackage, changedComponents, logger); let impactedTestClasses = await impactedApexTestClassFetcher.getImpactedTestClasses(); //Convert again for finding the values in the diff package let sourceToMdapiConvertor = new SourceToMDAPIConvertor_1.default(workingDirectory, sfpPackage.packageDescriptor.path, sfpPackage.apiVersion, logger); let mdapiDirPath = (await sourceToMdapiConvertor.convert()).packagePath; const packageManifest = await PackageManifest_1.default.create(mdapiDirPath); sfpPackage.payload = packageManifest.manifestJson; sfpPackage.apexTestClassses = impactedTestClasses; sfpPackage.apexClassWithOutTestClasses = getOnlyChangedClassesFromPackage(changedComponents, sfpPackage.apexClassesSortedByTypes); sfpPackage.isApexFound = packageManifest.isApexInPackage(); sfpPackage.isProfilesFound = packageManifest.isProfilesInPackage(); sfpPackage.isPermissionSetGroupFound = packageManifest.isPermissionSetGroupsFoundInPackage(); sfpPackage.isPayLoadContainTypesSupportedByProfiles = packageManifest.isPayLoadContainTypesSupportedByProfiles(); sfpPackage.metadataCount = await MetadataCount_1.default.getMetadataCount(workingDirectory, sfpPackage.packageDescriptor.path); rimraf.sync(mdapiDirPath); } else { //Souce Diff Directory is empty sfpPackage.payload = {}; sfpPackage.apexTestClassses = []; sfpPackage.apexClassWithOutTestClasses = []; sfpPackage.isApexFound = false; sfpPackage.isProfilesFound = false; sfpPackage.isPermissionSetGroupFound = false; sfpPackage.isPayLoadContainTypesSupportedByProfiles = false; sfpPackage.metadataCount = 0; } function getOnlyChangedClassesFromPackage(changedComponents, apexClassesSortedByTypes) { // Check if the parameters are not empty or undefined if (!changedComponents || !apexClassesSortedByTypes) { return undefined; } // Check if the 'class' property exists in apexClassesSortedByTypes if (!apexClassesSortedByTypes.class) { return undefined; } // Get the names of all classes in the ApexSortedByType let apexClassNames = apexClassesSortedByTypes.class.map((cls) => cls.name); let interfaces = apexClassesSortedByTypes.interface.map((cls) => cls.name); const apexTestClassNames = apexClassesSortedByTypes.testClass.map((cls) => cls.name); apexClassNames = apexClassNames.filter((name) => !apexTestClassNames.includes(name)); apexClassNames = apexClassNames.filter((name) => !interfaces.includes(name)); // Filter changedComponents based on class names in ApexSortedByType and type === 'ApexClass' const filteredComponents = changedComponents.filter((component) => apexClassNames.includes(component.fullName) && component.type === 'ApexClass'); // Extract the fullName property from the filtered components const filteredChangedClasses = filteredComponents.map((component) => component.fullName); return filteredChangedClasses; } } } exports.default = CreateDiffPackageImp; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ3JlYXRlRGlmZlBhY2thZ2VJbXBsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvcmUvcGFja2FnZS9wYWNrYWdlQ3JlYXRvcnMvQ3JlYXRlRGlmZlBhY2thZ2VJbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtRUFBc0U7QUFFdEUsZ0ZBQXdEO0FBQ3hELDRGQUFvRTtBQUNwRSw4Q0FBK0Y7QUFFL0YsOERBQXNDO0FBQ3RDLHdGQUFnRTtBQUNoRSwwRkFBa0U7QUFDbEUsZ0RBQXdCO0FBQ3hCLDZDQUErQjtBQUMvQiwrR0FBdUY7QUFDdkYsK0dBQXVGO0FBQ3ZGLG9GQUE0RDtBQUM1RCxnRkFBd0Q7QUFDeEQsK0NBQWlDO0FBRWpDLHdGQUFnRTtBQUVoRSxNQUFxQixvQkFBcUIsU0FBUSxpQ0FBdUI7SUFDckUsWUFDYyxnQkFBd0IsRUFDeEIsVUFBc0IsRUFDdEIscUJBQTRDLEVBQzVDLE1BQWUsRUFDZixNQUF5QjtRQUVuQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLHFCQUFxQixFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQU5qRSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQVE7UUFDeEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QiwwQkFBcUIsR0FBckIscUJBQXFCLENBQXVCO1FBQzVDLFdBQU0sR0FBTixNQUFNLENBQVM7UUFDZixXQUFNLEdBQU4sTUFBTSxDQUFtQjtJQUd2QyxDQUFDO0lBRUQsZ0JBQWdCO1FBQ1osT0FBTyx3QkFBVyxDQUFDLElBQUksQ0FBQztJQUM1QixDQUFDO0lBRUQscUNBQXFDLEtBQUksQ0FBQztJQUUxQyxjQUFjLENBQUMsZ0JBQXdCLEVBQUUsZ0JBQXdCO1FBQzdELE9BQU8sNkJBQW1CLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFDakYsQ0FBQztJ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