@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
JavaScript
;
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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