@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
241 lines • 21.7 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 lodash = require("lodash");
const Git_1 = __importDefault(require("../../git/Git"));
const GitTags_1 = __importDefault(require("../../git/GitTags"));
const Package2VersionFetcher_1 = __importDefault(require("../version/Package2VersionFetcher"));
const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger"));
/**
* Resolves package dependency versions to their exact versions
*/
class PackageDependencyResolver {
constructor(conn, projectConfig, packagesToBeSkipped, packagesToBeResolved, resolveExternalDepenciesOnly) {
this.conn = conn;
this.projectConfig = projectConfig;
this.packagesToBeSkipped = packagesToBeSkipped;
this.packagesToBeResolved = packagesToBeResolved;
this.resolveExternalDepenciesOnly = resolveExternalDepenciesOnly;
this.package2VersionCache = new Package2VersionCache();
// prevent mutation of original config
this.projectConfig = lodash.cloneDeep(this.projectConfig);
}
/**
* Resolves package dependency versions in project config
* Skips dependencies on packages that are queued for build, as they are resolved dynamically(packagesToBeSkipped)
* @returns new project config JSON, does not change original JSON
*/
async resolvePackageDependencyVersions() {
for (const packageDirectory of this.projectConfig.packageDirectories) {
if (this.packagesToBeResolved?.length > 0 && this.packagesToBeSkipped?.length > 0) {
throw Error(`Unsupported path.. Use only one of the options at any given time`);
}
if (this.packagesToBeSkipped && !this.packagesToBeSkipped.includes(packageDirectory.package)) {
continue;
}
if (this.packagesToBeResolved && !this.packagesToBeResolved.includes(packageDirectory.package)) {
continue;
}
if (packageDirectory.dependencies && Array.isArray(packageDirectory.dependencies)) {
for (let i = 0; i < packageDirectory.dependencies.length; i++) {
let dependency = packageDirectory.dependencies[i];
if (this.projectConfig.packageAliases[dependency.package] === undefined && !this.isSubscriberPackageVersionId(dependency.package)) {
throw new Error(`Can't find package id for dependency: ${dependency.package}, Please ensure that the package is added to sfdx-project.json in your packageAliases`);
}
let packageVersionId = this.isSubscriberPackageVersionId(dependency.package) ? dependency.package : this.projectConfig.packageAliases[dependency.package];
if (this.isSubscriberPackageVersionId(packageVersionId)) {
// Already resolved
continue;
}
if (this.packagesToBeSkipped && this.packagesToBeSkipped.includes(dependency.package) && !dependency.branch) {
// Dependency is part of the same build, will be resolved when new version is created
continue;
}
let package2VersionForDependency = '';
if (dependency.branch && dependency.branch !== '') {
sfp_logger_1.default.log(`Specified branch: ${dependency.branch} for dependency: ${dependency.package}`, sfp_logger_1.LoggerLevel.INFO);
package2VersionForDependency = await this.getPackage2VersionForDependency(this.conn, dependency, packageVersionId, dependency.branch);
sfp_logger_1.default.log(`Fetched latest branched package of ${dependency.package},`
+ `version: ${package2VersionForDependency.MajorVersion}.`
+ `${package2VersionForDependency.MinorVersion}.`
+ `${package2VersionForDependency.PatchVersion}.`
+ `${package2VersionForDependency.BuildNumber}`, sfp_logger_1.LoggerLevel.INFO);
let branchedPackageAlias = `${dependency.package}@`
+ `${package2VersionForDependency.MajorVersion}.`
+ `${package2VersionForDependency.MinorVersion}.`
+ `${package2VersionForDependency.PatchVersion}.`
+ `${package2VersionForDependency.BuildNumber}-`
+ `${dependency.branch}`;
dependency.package = branchedPackageAlias;
this.projectConfig.packageAliases[branchedPackageAlias] = package2VersionForDependency.SubscriberPackageVersionId;
delete dependency.versionNumber;
delete dependency.branch;
continue;
}
else {
package2VersionForDependency = await this.getPackage2VersionForDependency(this.conn, dependency, packageVersionId);
}
if (package2VersionForDependency == null) {
packageDirectory.dependencies.splice(i, 1);
i--;
}
else
dependency.versionNumber = `${package2VersionForDependency.MajorVersion}.${package2VersionForDependency.MinorVersion}.${package2VersionForDependency.PatchVersion}.${package2VersionForDependency.BuildNumber}`;
}
}
}
return this.projectConfig;
}
/**
* Get last validated Package2 version for package dependency
* @param conn
* @param dependency
* @returns Package2Version
*/
async getPackage2VersionForDependency(conn, dependency, packageVersionId, branch) {
let isReleased = false;
//Dont hit api's if its only for external dependencies
if (this.projectConfig.packageDirectories.find((dir) => dir.package === dependency.package)) {
if (this.resolveExternalDepenciesOnly)
return null;
}
let package2Version;
let versionNumber = dependency.versionNumber;
let vers = versionNumber.split('.');
// fetch only promoted versions
if (vers.length === 4 && vers[3] === 'RELEASED')
isReleased = true;
if (vers.length === 4 && (vers[3] === 'LATEST') || (vers[3] === 'RELEASED')) {
versionNumber = `${vers[0]}.${vers[1]}.${vers[2]}`;
}
let package2Versions;
if (this.package2VersionCache.has(packageVersionId, versionNumber)) {
package2Versions = this.package2VersionCache.get(packageVersionId, versionNumber);
}
else {
const package2VersionFetcher = new Package2VersionFetcher_1.default(conn);
let records;
if (branch) {
records = await package2VersionFetcher.fetchByPackageBranchAndName(branch, dependency.package, versionNumber);
}
else {
records = await package2VersionFetcher.fetchByPackage2Id(packageVersionId, versionNumber, true, isReleased);
}
this.package2VersionCache.set(packageVersionId, versionNumber, records);
package2Versions = this.package2VersionCache.get(packageVersionId, versionNumber);
}
if (package2Versions.length === 0 && !isReleased) {
throw new Error(`Failed to find any validated Package2 versions for the dependency ${dependency.package} with version ${dependency.versionNumber}`);
}
if (package2Versions.length === 0 && isReleased) {
throw new Error(`Failed to find any promoted Package2 versions for the dependency ${dependency.package} with version ${dependency.versionNumber}`);
}
if (this.projectConfig.packageDirectories.find((dir) => dir.package === dependency.package && !branch)) {
package2Version = await this.getPackage2VersionFromCurrentBranch(package2Versions, dependency);
}
else {
// Take last validated package for external packages
package2Version = package2Versions[0];
}
return package2Version;
}
/**
* Get Package2 version created from the current branch
* @param package2Versions
* @param dependency
* @returns Package2Version
*/
async getPackage2VersionFromCurrentBranch(package2Versions, dependency) {
let package2VersionOnCurrentBranch;
const git = await Git_1.default.initiateRepo();
const gitTags = new GitTags_1.default(git, dependency.package);
const tags = await gitTags.listTagsOnBranch();
for (const package2Version of package2Versions) {
const version = `${package2Version.MajorVersion}.${package2Version.MinorVersion}.${package2Version.PatchVersion}.${package2Version.BuildNumber}`;
for (const tag of tags) {
if (tag.endsWith(version)) {
package2VersionOnCurrentBranch = package2Version;
break;
}
}
if (package2VersionOnCurrentBranch)
break;
}
if (!package2VersionOnCurrentBranch) {
throw new Error(`Failed to find validated Package2 version for dependency ${dependency.package} with version ${dependency.versionNumber} created from the current branch,
You will need to create a new version of the package on the current branch to resolve this dependency.`);
}
return package2VersionOnCurrentBranch;
}
isSubscriberPackageVersionId(packageAlias) {
const subscriberPackageVersionIdPrefix = '04t';
return packageAlias.startsWith(subscriberPackageVersionIdPrefix);
}
}
exports.default = PackageDependencyResolver;
class Package2VersionCache {
constructor() {
this.cache = {};
}
/**
* Checks whether cache contains key for package ID and version number
* @param packageId
* @param versionNumberstartw
* @returns true or false
*/
has(packageId, versionNumber) {
const key = `${packageId}-${versionNumber}`;
if (this.cache[key])
return true;
else
return false;
}
/**
* Set the cache value, Package2 versions, for package ID and version number
* @param packageId
* @param versionNumber
* @param package2Versions
* @returns cache
*/
set(packageId, versionNumber, package2Versions) {
const key = `${packageId}-${versionNumber}`;
this.cache[key] = package2Versions;
return this.cache;
}
/**
*
* @param packageId
* @param versionNumber
* @returns Package2 versions for package ID and version number
*/
get(packageId, versionNumber) {
const key = `${packageId}-${versionNumber}`;
return this.cache[key];
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFja2FnZURlcGVuZGVuY3lSZXNvbHZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3BhY2thZ2UvZGVwZW5kZW5jaWVzL1BhY2thZ2VEZXBlbmRlbmN5UmVzb2x2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLGlDQUFrQztBQUNsQyx3REFBZ0M7QUFDaEMsZ0VBQXdDO0FBQ3hDLCtGQUE0RjtBQUM1RixtRUFBOEQ7QUFHOUQ7O0dBRUc7QUFDSCxNQUFxQix5QkFBeUI7SUFHMUMsWUFDWSxJQUFnQixFQUNoQixhQUFhLEVBQ2IsbUJBQThCLEVBQzlCLG9CQUErQixFQUMvQiw0QkFBc0M7UUFKdEMsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNoQixrQkFBYSxHQUFiLGFBQWEsQ0FBQTtRQUNiLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBVztRQUM5Qix5QkFBb0IsR0FBcEIsb0JBQW9CLENBQVc7UUFDL0IsaUNBQTRCLEdBQTVCLDRCQUE0QixDQUFVO1FBUDFDLHlCQUFvQixHQUF5QixJQUFJLG9CQUFvQixFQUFFLENBQUM7UUFTNUUsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsZ0NBQWdDO1FBQ3pDLEtBQUssTUFBTSxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDbkUsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNoRixNQUFNLEtBQUssQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1lBQ3BGLENBQUM7WUFFRCxJ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