UNPKG

@flxbl-io/sfp

Version:

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

165 lines 16.7 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 path = require('path'); const fs = __importStar(require("fs-extra")); const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const core_1 = require("@salesforce/core"); const SFPOrg_1 = __importDefault(require("../../org/SFPOrg")); const source_tracking_1 = require("@salesforce/source-tracking"); const ProjectConfig_1 = __importDefault(require("../../project/ProjectConfig")); const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve"); const os_1 = require("os"); const SfpPackage_1 = require("../../package/SfpPackage"); const Git_1 = __importDefault(require("../../git/Git")); const tmp = require('tmp'); class ClientSourceTracking { constructor() { } static async create(conn, logger) { const clientSourceTracking = new ClientSourceTracking(); clientSourceTracking.conn = conn; clientSourceTracking.org = await SFPOrg_1.default.create({ connection: clientSourceTracking.conn }); clientSourceTracking.logger = logger; clientSourceTracking.sfdxOrgIdDir = `.sf/orgs/${clientSourceTracking.org.getOrgId()}`; return clientSourceTracking; } async creatSourceTrackingFiles() { await this.createRemoteSourceTracking(); await this.createLocalSourceTracking(); } async createRemoteSourceTracking() { const project = await core_1.SfProject.resolve(); const tracking = await source_tracking_1.SourceTracking.create({ org: this.org, project: project, }); await tracking.resetRemoteTracking(); await tracking.ensureLocalTracking(); } /** * Create local source tracking from sfp artifacts installed in scratch org */ async createLocalSourceTracking() { let git; try { git = await Git_1.default.initiateRepoAtTempLocation(this.logger); const sfpArtifacts = await this.org.getInstalledArtifacts(); if (sfpArtifacts.length == 0) { throw new Error(`Unable to find any artifacts in the org`); } //clean up MPD to just one package, so that source tracking lib //does do a full scan and break this.cleanupSFDXProjectJsonTonOnePackage(git.getRepositoryPath(), sfpArtifacts[0].Name); const project = await core_1.SfProject.resolve(git.getRepositoryPath()); // Create local source tracking files in temp repo const tracking = await source_tracking_1.SourceTracking.create({ org: this.org, project: project, }); sfp_logger_1.default.log(`Total Artifacts to Analyze: ${sfpArtifacts.length}`, sfp_logger_1.LoggerLevel.INFO, this.logger); let count = 1; for (const artifact of sfpArtifacts) { sfp_logger_1.default.log(os_1.EOL, sfp_logger_1.LoggerLevel.INFO, this.logger); sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Package ${count} of ${sfpArtifacts.length}`), sfp_logger_1.LoggerLevel.INFO, this.logger); sfp_logger_1.default.log(`Analyzing package ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(artifact.Name)}`, sfp_logger_1.LoggerLevel.INFO, this.logger); // Checkout version of source code from which artifact was created await git.checkout(artifact.CommitId__c, true); sfp_logger_1.default.log(`Version pushed while preparing this org is ${artifact.Version__c} with SHA ${artifact.CommitId__c}`, sfp_logger_1.LoggerLevel.INFO, this.logger); //clean up MPD to per package, to speed up this.cleanupSFDXProjectJsonTonOnePackage(git.getRepositoryPath(), artifact.Name); const projectConfig = ProjectConfig_1.default.getSFDXProjectConfig(git.getRepositoryPath()); try { const packageType = ProjectConfig_1.default.getPackageType(projectConfig, artifact.Name); if (packageType === SfpPackage_1.PackageType.Unlocked || packageType === SfpPackage_1.PackageType.Source) { let componentSet = source_deploy_retrieve_1.ComponentSet.fromSource(path.join(git.getRepositoryPath(), ProjectConfig_1.default.getPackageDescriptorFromConfig(artifact.Name, projectConfig).path)); let components = componentSet.getSourceComponents(); //Get all components in the directory //Count for logging purposes. dont have to waste processing convering //a lazy collection to array once again let componentCount = 1; let componentPaths = []; for (const component of components) { componentCount++; componentPaths.push(component.xml); if (component.content) componentPaths.push(component.content); } await tracking.updateLocalTracking({ files: componentPaths, }); sfp_logger_1.default.log(`Updated source tracking for package: ${artifact.Name} with ${componentCount} items`, sfp_logger_1.LoggerLevel.INFO, this.logger); } else sfp_logger_1.default.log(`Encountered data package... skipping`, sfp_logger_1.LoggerLevel.INFO, this.logger); } catch (error) { if (error.message.includes) { sfp_logger_1.default.log(` sfp is unable to sync the package ${artifact.Name}${os_1.EOL}, as it not able to find the find equivalent git references`, sfp_logger_1.LoggerLevel.ERROR, this.logger); } else sfp_logger_1.default.log(`Unable to update local source tracking due to ${error.message}`, sfp_logger_1.LoggerLevel.INFO, this.logger); sfp_logger_1.default.log(`Skipping package.. ${artifact.Name}`, sfp_logger_1.LoggerLevel.WARN, this.logger); } count++; } sfp_logger_1.default.log(os_1.EOL, sfp_logger_1.LoggerLevel.INFO, this.logger); sfp_logger_1.default.log(`Copying the temporary repository over to original location`, sfp_logger_1.LoggerLevel.INFO, this.logger); // Copy source tracking files from temp repo to actual repo fs.mkdirpSync(path.join(this.sfdxOrgIdDir, 'localSourceTracking')); fs.copySync(path.join(git.getRepositoryPath(), this.sfdxOrgIdDir, 'localSourceTracking'), path.join(this.sfdxOrgIdDir, 'localSourceTracking')); } catch (error) { if (error.message.includes(`reference is not a tree`)) { sfp_logger_1.default.log(`sfp is unable to sync this repository, as it not able to find the matching git references${os_1.EOL} Are you sure this pool was created from the same repository?`, sfp_logger_1.LoggerLevel.ERROR, this.logger); } else sfp_logger_1.default.log(`Unable to update local source tracking due to ${error}`, sfp_logger_1.LoggerLevel.ERROR, this.logger); } finally { if (git) { git.deleteTempoRepoIfAny(); } } } cleanupSFDXProjectJsonTonOnePackage(projectDir, packageName) { try { let cleanedUpProjectManifest = ProjectConfig_1.default.cleanupMPDFromProjectDirectory(projectDir, packageName); fs.writeJSONSync(path.join(projectDir, 'sfdx-project.json'), cleanedUpProjectManifest, { spaces: 4, }); } catch (error) { sfp_logger_1.default.log(`sfdx-project.json not found/unable to write, skipping..` + error.message, sfp_logger_1.LoggerLevel.DEBUG, this.logger); } } } exports.default = ClientSourceTracking; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2xpZW50U291cmNlVHJhY2tpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9zY3JhdGNob3JnL3Bvb2wvQ2xpZW50U291cmNlVHJhY2tpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM3Qiw2Q0FBK0I7QUFDL0IsbUVBQXVHO0FBQ3ZHLDJDQUF5RDtBQUN6RCw4REFBc0M7QUFDdEMsaUVBQTZEO0FBQzdELGdGQUF3RDtBQUN4RCwrRUFBa0U7QUFDbEUsMkJBQXlCO0FBQ3pCLHlEQUF1RDtBQUN2RCx3REFBZ0M7QUFFaEMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBRTNCLE1BQXFCLG9CQUFvQjtJQU9yQyxnQkFBdUIsQ0FBQztJQUV4QixNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFnQixFQUFFLE1BQWM7UUFDaEQsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUM7UUFFeEQsb0JBQW9CLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUVqQyxvQkFBb0IsQ0FBQyxHQUFHLEdBQUcsTUFBTSxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFVBQVUsRUFBRSxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFGLG9CQUFvQixDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFFckMsb0JBQW9CLENBQUMsWUFBWSxHQUFHLFlBQVksb0JBQW9CLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7UUFFdEYsT0FBTyxvQkFBb0IsQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSyxDQUFDLHdCQUF3QjtRQUMxQixNQUFNLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ3hDLE1BQU0s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