UNPKG

@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
"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 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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