@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
181 lines • 18.9 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 core_1 = require("@salesforce/core");
const SfpCommand_1 = __importDefault(require("../../SfpCommand"));
const PrepareImpl_1 = __importDefault(require("../../impl/prepare/PrepareImpl"));
const SFPStatsSender_1 = __importDefault(require("../../core/stats/SFPStatsSender"));
const Stage_1 = require("../../impl/Stage");
const fs = __importStar(require("fs-extra"));
const ScratchOrgInfoFetcher_1 = __importDefault(require("../../core/scratchorg/pool/services/fetchers/ScratchOrgInfoFetcher"));
const ajv_1 = __importDefault(require("ajv"));
const path = require("path");
const PoolError_1 = require("../../core/scratchorg/pool/PoolError");
const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger"));
const GetFormattedTime_1 = __importDefault(require("../../core/utils/GetFormattedTime"));
const sfp_logger_2 = require("@flxbl-io/sfp-logger");
const SFPOrg_1 = __importDefault(require("../../core/org/SFPOrg"));
const core_2 = require("@oclif/core");
const sfdxflags_1 = require("../../flags/sfdxflags");
core_1.Messages.importMessagesDirectory(__dirname);
const messages = core_1.Messages.loadMessages('@flxbl-io/sfp', 'prepare');
class Prepare extends SfpCommand_1.default {
async execute() {
let executionStartTime = Date.now();
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`command: ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(`prepare`)}`));
//Read pool config
try {
let poolConfig = fs.readJSONSync(this.flags.poolconfig);
this.validatePoolConfig(poolConfig);
//Assign Keys to the config
if (this.flags.keys)
poolConfig.keys = this.flags.keys;
this.displayHeader(poolConfig);
//Assign npmrcPath to the config
if (this.flags.npmrcpath) {
if (poolConfig.fetchArtifacts?.npm)
poolConfig.fetchArtifacts.npm.npmrcPath = this.flags.npmrcpath;
else
sfp_logger_1.default.log((0, sfp_logger_2.COLOR_WARNING)('npmrcPath found in flag, however the configuration doesnt seem to use npm, Are you sure your schema is good?'));
}
let tags = {
stage: Stage_1.Stage.PREPARE,
poolName: poolConfig.tag,
};
await this.hubOrg.refreshAuth();
const hubConn = this.hubOrg.getConnection();
this.flags.apiversion = this.flags.apiversion || (await hubConn.retrieveMaxApiVersion());
let hubOrgAsSfPOrg = await SFPOrg_1.default.create({ connection: this.hubOrg.getConnection() });
let prepareImpl = new PrepareImpl_1.default(hubOrgAsSfPOrg, poolConfig, this.flags.loglevel);
let results = await prepareImpl.exec();
if (results.isOk()) {
let totalElapsedTime = Date.now() - executionStartTime;
sfp_logger_1.default.printHeaderLine('', sfp_logger_1.COLOR_HEADER, sfp_logger_1.LoggerLevel.INFO);
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_SUCCESS)(`Provisioned {${results.value.scratchOrgs.length}} scratchorgs out of ${results.value.to_allocate} requested with ${(0, sfp_logger_1.COLOR_ERROR)(results.value.failedToCreate)} failed in ${(0, sfp_logger_1.COLOR_TIME)((0, GetFormattedTime_1.default)(totalElapsedTime))} `));
sfp_logger_1.default.printHeaderLine('', sfp_logger_1.COLOR_HEADER, sfp_logger_1.LoggerLevel.INFO);
await this.getCurrentRemainingNumberOfOrgsInPoolAndReport(poolConfig);
SFPStatsSender_1.default.logGauge('prepare.succeededorgs', results.value.scratchOrgs.length, tags);
if (results.value.scratchOrgs.length > 0)
SFPStatsSender_1.default.logGauge('prepare.duration', Date.now() - executionStartTime, tags);
}
else if (results.isErr()) {
sfp_logger_1.default.printHeaderLine('', sfp_logger_1.COLOR_HEADER, sfp_logger_1.LoggerLevel.INFO);
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_ERROR)(results.error.message), sfp_logger_1.LoggerLevel.ERROR);
sfp_logger_1.default.printHeaderLine('', sfp_logger_1.COLOR_HEADER, sfp_logger_1.LoggerLevel.INFO);
switch (results.error.errorCode) {
case PoolError_1.PoolErrorCodes.Max_Capacity:
process.exitCode = 0;
break;
case PoolError_1.PoolErrorCodes.No_Capacity:
process.exitCode = 0;
break;
case PoolError_1.PoolErrorCodes.PrerequisiteMissing:
process.exitCode = 1;
break;
case PoolError_1.PoolErrorCodes.UnableToProvisionAny:
SFPStatsSender_1.default.logGauge('prepare.failedorgs', results.error.failed, tags);
process.exitCode = 1;
break;
}
}
}
catch (err) {
throw new Error('Unable to execute command .. ' + err);
}
}
displayHeader(poolConfig) {
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Pool Name: ${poolConfig.tag}`));
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Requested Count of Orgs: ${poolConfig.maxAllocation}`));
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Scratch Orgs to be submitted to pool in case of failures: ${poolConfig.succeedOnDeploymentErrors ? 'true' : 'false'}`));
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`All packages in the repo to be installed: ${poolConfig.installAll ? 'true' : 'false'}`));
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Enable Source Tracking: ${poolConfig.enableSourceTracking || poolConfig.enableSourceTracking === undefined ? 'true' : 'false'}`));
if (poolConfig.enableVlocity)
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Enable Vlocity Config: true`));
if (poolConfig.fetchArtifacts) {
if (poolConfig.fetchArtifacts.artifactFetchScript)
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Script provided to fetch artifacts: ${poolConfig.fetchArtifacts.artifactFetchScript}`));
if (poolConfig.fetchArtifacts.npm) {
sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`Fetch artifacts from pre-authenticated NPM registry: true`));
}
}
sfp_logger_1.default.printHeaderLine('', sfp_logger_1.COLOR_HEADER, sfp_logger_1.LoggerLevel.INFO);
}
async getCurrentRemainingNumberOfOrgsInPoolAndReport(poolConfig) {
try {
const results = await new ScratchOrgInfoFetcher_1.default(this.hubOrg).getScratchOrgsByTag(this.flags.tag, false, true);
let tags = {
stage: Stage_1.Stage.PREPARE,
poolName: poolConfig.tag,
};
let availableSo = results.records.filter((soInfo) => soInfo.Allocation_status__c === 'Available');
SFPStatsSender_1.default.logGauge('pool.available', availableSo.length, tags);
}
catch (error) {
//do nothing, we are not reporting anything if anything goes wrong here
}
}
validatePoolConfig(poolConfig) {
let ajv = new ajv_1.default({ allErrors: true });
let schema = fs.readJSONSync(path.join(__dirname, '..', '..', '..', 'resources', 'schemas', 'pooldefinition.schema.json'), { encoding: 'UTF-8' });
let validator = ajv.compile(schema);
let isSchemaValid = validator(poolConfig);
if (!isSchemaValid) {
let errorMsg = `The pool configuration is invalid, Please fix the following errors\n`;
validator.errors.forEach((error, errorNum) => {
errorMsg += `\n${errorNum + 1}: ${error.instancePath}: ${error.message} ${JSON.stringify(error.params, null, 4)}`;
});
throw new Error(errorMsg);
}
}
}
Prepare.aliases = ['orchestrator:prepare', 'prepare'];
Prepare.requiresDevhubUsername = true;
Prepare.requiresProject = true;
Prepare.flags = {
targetdevhubusername: sfdxflags_1.targetdevhubusername,
poolconfig: core_2.Flags.file({
required: false,
default: 'config/poolconfig.json',
char: 'f',
description: messages.getMessage('poolConfigFlagDescription'),
}),
npmrcpath: core_2.Flags.file({
description: messages.getMessage('npmrcPathFlagDescription'),
required: false,
}),
keys: core_2.Flags.string({
required: false,
description: messages.getMessage('keysDescription'),
}),
logsgroupsymbol: sfdxflags_1.logsgroupsymbol,
loglevel: sfdxflags_1.loglevel
};
Prepare.description = messages.getMessage('commandDescription');
Prepare.examples = [`$ sfp prepare -f config/mypoolconfig.json -v <devhub>`];
exports.default = Prepare;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcGFyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9wb29sL3ByZXBhcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE0QztBQUM1QyxrRUFBMEM7QUFDMUMsaUZBQXlEO0FBQ3pELHFGQUE2RDtBQUM3RCw0Q0FBeUM7QUFDekMsNkNBQStCO0FBQy9CLCtIQUF1RztBQUN2Ryw4Q0FBc0I7QUFDdEIsNkJBQThCO0FBQzlCLG9FQUFzRTtBQUN0RSxtRUFPOEI7QUFDOUIseUZBQWlFO0FBRWpFLHFEQUFxRDtBQUNyRCxtRUFBMkM7QUFDM0Msc0NBQW9DO0FBQ3BDLHFEQUF3RjtBQUV4RixlQUFRLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDNUMsTUFBTSxRQUFRLEdBQUcsZUFBUSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFFbkUsTUFBcUIsT0FBUSxTQUFRLG9CQUFVO0lBK0JwQyxLQUFLLENBQUMsT0FBTztRQUNoQixJQUFJLGtCQUFrQixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUVwQyxvQkFBUyxDQUFDLEdBQUcsQ0FBQyxJQUFBLHlCQUFZLEVBQUMsWUFBWSxJQUFBLDhCQUFpQixFQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXhFLGtCQUFrQjtRQUNsQixJQUFJLENBQUM7WUFDRCxJQUFJLFVBQVUsR0FBZSxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDcEUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BDLDJCQUEyQjtZQUMzQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTtnQkFBRSxVQUFVLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENB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