@rushstack/heft
Version:
Build all your JavaScript projects the same way: A way that works.
190 lines • 10.4 kB
JavaScript
;
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CoreConfigFiles = void 0;
const path = __importStar(require("path"));
const heft_config_file_1 = require("@rushstack/heft-config-file");
const node_core_library_1 = require("@rushstack/node-core-library");
const Constants_1 = require("./Constants");
class CoreConfigFiles {
/**
* Returns the loader for the `config/heft.json` config file.
*/
static async loadHeftConfigurationFileForProjectAsync(terminal, projectPath, rigConfig) {
var _a, _b;
if (!CoreConfigFiles._heftConfigFileLoader) {
let heftPluginPackageFolder;
const pluginPackageResolver = (options) => {
const { propertyValue, configurationFilePath } = options;
if (propertyValue === Constants_1.Constants.heftPackageName) {
// If the value is "@rushstack/heft", then resolve to the Heft package that is
// installed in the project folder. This avoids issues with mismatched versions
// between the project and the globally installed Heft. Use the PackageJsonLookup
// class to find the package folder to avoid hardcoding the path for compatibility
// with bundling.
if (!heftPluginPackageFolder) {
heftPluginPackageFolder = node_core_library_1.PackageJsonLookup.instance.tryGetPackageFolderFor(__dirname);
}
if (!heftPluginPackageFolder) {
// This should never happen
throw new node_core_library_1.InternalError('Unable to find the @rushstack/heft package folder');
}
return heftPluginPackageFolder;
}
else {
const configurationFileDirectory = path.dirname(configurationFilePath);
return node_core_library_1.Import.resolvePackage({
packageName: propertyValue,
baseFolderPath: configurationFileDirectory,
allowSelfReference: true
});
}
};
const schemaObject = await Promise.resolve().then(() => __importStar(require('../schemas/heft.schema.json')));
CoreConfigFiles._heftConfigFileLoader = new heft_config_file_1.ProjectConfigurationFile({
projectRelativeFilePath: CoreConfigFiles.heftConfigurationProjectRelativeFilePath,
jsonSchemaObject: schemaObject,
propertyInheritanceDefaults: {
array: { inheritanceType: heft_config_file_1.InheritanceType.append },
object: { inheritanceType: heft_config_file_1.InheritanceType.merge }
},
jsonPathMetadata: {
// Use a custom resolver for the plugin packages, since the NodeResolve algorithm will resolve to the
// package.json exports/module property, which may or may not exist.
'$.heftPlugins.*.pluginPackage': {
pathResolutionMethod: heft_config_file_1.PathResolutionMethod.custom,
customResolver: pluginPackageResolver
},
// Use a custom resolver for the plugin packages, since the NodeResolve algorithm will resolve to the
// package.json exports/module property, which may or may not exist.
'$.phasesByName.*.tasksByName.*.taskPlugin.pluginPackage': {
pathResolutionMethod: heft_config_file_1.PathResolutionMethod.custom,
customResolver: pluginPackageResolver
}
}
});
}
const heftConfigFileLoader = CoreConfigFiles._heftConfigFileLoader;
let configurationFile;
try {
configurationFile = await heftConfigFileLoader.loadConfigurationFileForProjectAsync(terminal, projectPath, rigConfig);
}
catch (e) {
if (!(e instanceof Error) ||
!e.message.startsWith('Resolved configuration object does not match schema')) {
throw e;
}
try {
// If the config file doesn't match the schema, then we should check to see if it does
// match the legacy schema. We don't need to worry about the resulting object, we just
// want to see if it parses. We will use the ConfigurationFile class to load it to ensure
// that we follow the "extends" chain for the entire config file.
const legacySchemaObject = await Promise.resolve().then(() => __importStar(require('../schemas/heft-legacy.schema.json')));
const legacyConfigFileLoader = new heft_config_file_1.ProjectConfigurationFile({
projectRelativeFilePath: CoreConfigFiles.heftConfigurationProjectRelativeFilePath,
jsonSchemaObject: legacySchemaObject
});
await legacyConfigFileLoader.loadConfigurationFileForProjectAsync(terminal, projectPath, rigConfig);
}
catch (e2) {
// It doesn't match the legacy schema either. Throw the original error.
throw e;
}
// Matches the legacy schema, so throw a more helpful error.
throw new Error("This project's Heft configuration appears to be using an outdated schema.\n\n" +
'Heft 0.51.0 introduced a major breaking change for Heft configuration files. ' +
'Your project appears to be using the older file format. You will need to ' +
'migrate your project to the new format. Follow these instructions: ' +
'https://rushstack.io/link/heft-0.51');
}
// The pluginPackage field was resolved to the root of the package, but we also want to have
// the original plugin package name in the config file.
function getUpdatedPluginSpecifier(rawSpecifier) {
const pluginPackageName = heftConfigFileLoader.getPropertyOriginalValue({
parentObject: rawSpecifier,
propertyName: 'pluginPackage'
});
const newSpecifier = {
...rawSpecifier,
pluginPackageRoot: rawSpecifier.pluginPackage,
pluginPackage: pluginPackageName
};
return newSpecifier;
}
const phasesByName = {};
const normalizedConfigurationFile = {
...configurationFile,
heftPlugins: (_b = (_a = configurationFile.heftPlugins) === null || _a === void 0 ? void 0 : _a.map(getUpdatedPluginSpecifier)) !== null && _b !== void 0 ? _b : [],
phasesByName
};
for (const [phaseName, phase] of Object.entries(configurationFile.phasesByName || {})) {
const tasksByName = {};
phasesByName[phaseName] = {
...phase,
tasksByName
};
for (const [taskName, task] of Object.entries(phase.tasksByName || {})) {
if (task.taskPlugin) {
tasksByName[taskName] = {
...task,
taskPlugin: getUpdatedPluginSpecifier(task.taskPlugin)
};
}
else {
tasksByName[taskName] = task;
}
}
}
return normalizedConfigurationFile;
}
static async tryLoadNodeServiceConfigurationFileAsync(terminal, projectPath, rigConfig) {
if (!CoreConfigFiles._nodeServiceConfigurationLoader) {
const schemaObject = await Promise.resolve().then(() => __importStar(require('../schemas/node-service.schema.json')));
CoreConfigFiles._nodeServiceConfigurationLoader =
new heft_config_file_1.ProjectConfigurationFile({
projectRelativeFilePath: CoreConfigFiles.nodeServiceConfigurationProjectRelativeFilePath,
jsonSchemaObject: schemaObject
});
}
const configurationFile = await CoreConfigFiles._nodeServiceConfigurationLoader.tryLoadConfigurationFileForProjectAsync(terminal, projectPath, rigConfig);
return configurationFile;
}
}
exports.CoreConfigFiles = CoreConfigFiles;
CoreConfigFiles.heftConfigurationProjectRelativeFilePath = `${Constants_1.Constants.projectConfigFolderName}/${Constants_1.Constants.heftConfigurationFilename}`;
CoreConfigFiles.nodeServiceConfigurationProjectRelativeFilePath = `${Constants_1.Constants.projectConfigFolderName}/${Constants_1.Constants.nodeServiceConfigurationFilename}`;
//# sourceMappingURL=CoreConfigFiles.js.map