UNPKG

@rushstack/heft

Version:

Build all your JavaScript projects the same way: A way that works.

100 lines 5.27 kB
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. import * as path from 'node:path'; import { PackageJsonLookup, Import } from '@rushstack/node-core-library'; /** * Rig resolves requested tools from the project's Heft rig. */ export class RigPackageResolver { constructor(options) { this._packageJsonLookup = new PackageJsonLookup(); this._resolverCache = new Map(); this._buildFolder = options.buildFolder; this._projectPackageJson = options.projectPackageJson; this._rigConfig = options.rigConfig; } /** * Rig resolve the path to a specific package. * * The following rules will apply when rig resolving a package: * - If the local project has a devDependency (not regular or peer dependency) on the tool, * that has highest precedence. * - OTHERWISE if there is a rig.json file, then look at the rig's package.json. Does it have a * regular dependency (not dev or peer dependency) on the tool? If yes, then * resolve the tool from the rig package folder. * - OTHERWISE try to resolve it from the current project. */ async resolvePackageAsync(packageName, terminal) { const buildFolder = this._buildFolder; const projectFolder = this._packageJsonLookup.tryGetPackageFolderFor(buildFolder); if (!projectFolder) { throw new Error(`Unable to find a package.json file for "${buildFolder}".`); } const cacheKey = `${projectFolder};${packageName}`; let resolutionPromise = this._resolverCache.get(cacheKey); if (!resolutionPromise) { resolutionPromise = this._resolvePackageInnerAsync(packageName, terminal); this._resolverCache.set(cacheKey, resolutionPromise); } return await resolutionPromise; } async _resolvePackageInnerAsync(toolPackageName, terminal) { // See if the project has a devDependency on the package if (this._projectPackageJson.devDependencies && this._projectPackageJson.devDependencies[toolPackageName]) { try { const resolvedPackageFolder = Import.resolvePackage({ packageName: toolPackageName, baseFolderPath: this._buildFolder }); terminal.writeVerboseLine(`Resolved ${JSON.stringify(toolPackageName)} as a direct devDependency of the project.`); return resolvedPackageFolder; } catch (e) { throw new Error(`${JSON.stringify(toolPackageName)} is listed as a direct devDependency of the project, but ` + 'could not be resolved. Have dependencies been installed?'); } } // See if the project rig has a regular dependency on the package const rigConfiguration = this._rigConfig; if (rigConfiguration.rigFound) { const rigFolder = rigConfiguration.getResolvedProfileFolder(); const rigPackageJsonPath = this._packageJsonLookup.tryGetPackageJsonFilePathFor(rigFolder); if (!rigPackageJsonPath) { throw new Error('Unable to resolve the package.json file for the ' + `${JSON.stringify(rigConfiguration.rigPackageName)} rig package.`); } const rigPackageJson = this._packageJsonLookup.loadNodePackageJson(rigPackageJsonPath); if (rigPackageJson.dependencies && rigPackageJson.dependencies[toolPackageName]) { try { const resolvedPackageFolder = Import.resolvePackage({ packageName: toolPackageName, baseFolderPath: path.dirname(rigPackageJsonPath) }); terminal.writeVerboseLine(`Resolved ${JSON.stringify(toolPackageName)} as a dependency of the ` + `${JSON.stringify(rigConfiguration.rigPackageName)} rig package.`); return resolvedPackageFolder; } catch (e) { throw new Error(`${JSON.stringify(toolPackageName)} is listed as a dependency of the ` + `${JSON.stringify(rigConfiguration.rigPackageName)} rig package, but could not be resolved. ` + 'Have dependencies been installed?'); } } } // Last attempt, try to resolve it from the current project using node resolution try { const resolvedPackageFolder = Import.resolvePackage({ packageName: toolPackageName, baseFolderPath: this._buildFolder }); terminal.writeVerboseLine(`Resolved ${JSON.stringify(toolPackageName)} from "${resolvedPackageFolder}".`); return resolvedPackageFolder; } catch (e) { throw new Error(`Unable to resolve ${JSON.stringify(toolPackageName)}. For more information on riggable ` + 'dependency resolution, see https://rushstack.io/pages/heft/rig_packages/#3-riggable-dependencies'); } } } //# sourceMappingURL=RigPackageResolver.js.map