forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(dev-infra): allow build-worker to be used in forked process (angu…
…lar#40012) Generates a local copy of the build-worker file to allow it to be loaded at runtime in a forked process. PR Close angular#40012
- Loading branch information
1 parent
74e42cf
commit c043ecf
Showing
4 changed files
with
381 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,316 @@ | ||
'use strict'; | ||
|
||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
|
||
var tslib = require('tslib'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var chalk = _interopDefault(require('chalk')); | ||
require('inquirer'); | ||
require('inquirer-autocomplete-prompt'); | ||
var shelljs = require('shelljs'); | ||
|
||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
/** Reexport of chalk colors for convenient access. */ | ||
var red = chalk.red; | ||
var green = chalk.green; | ||
var yellow = chalk.yellow; | ||
var bold = chalk.bold; | ||
var blue = chalk.blue; | ||
/** | ||
* Supported levels for logging functions. | ||
* | ||
* Levels are mapped to numbers to represent a hierarchy of logging levels. | ||
*/ | ||
var LOG_LEVELS; | ||
(function (LOG_LEVELS) { | ||
LOG_LEVELS[LOG_LEVELS["SILENT"] = 0] = "SILENT"; | ||
LOG_LEVELS[LOG_LEVELS["ERROR"] = 1] = "ERROR"; | ||
LOG_LEVELS[LOG_LEVELS["WARN"] = 2] = "WARN"; | ||
LOG_LEVELS[LOG_LEVELS["LOG"] = 3] = "LOG"; | ||
LOG_LEVELS[LOG_LEVELS["INFO"] = 4] = "INFO"; | ||
LOG_LEVELS[LOG_LEVELS["DEBUG"] = 5] = "DEBUG"; | ||
})(LOG_LEVELS || (LOG_LEVELS = {})); | ||
/** Default log level for the tool. */ | ||
var DEFAULT_LOG_LEVEL = LOG_LEVELS.INFO; | ||
/** Write to the console for at INFO logging level */ | ||
var info = buildLogLevelFunction(function () { return console.info; }, LOG_LEVELS.INFO); | ||
/** Write to the console for at ERROR logging level */ | ||
var error = buildLogLevelFunction(function () { return console.error; }, LOG_LEVELS.ERROR); | ||
/** Write to the console for at DEBUG logging level */ | ||
var debug = buildLogLevelFunction(function () { return console.debug; }, LOG_LEVELS.DEBUG); | ||
/** Write to the console for at LOG logging level */ | ||
// tslint:disable-next-line: no-console | ||
var log = buildLogLevelFunction(function () { return console.log; }, LOG_LEVELS.LOG); | ||
/** Write to the console for at WARN logging level */ | ||
var warn = buildLogLevelFunction(function () { return console.warn; }, LOG_LEVELS.WARN); | ||
/** Build an instance of a logging function for the provided level. */ | ||
function buildLogLevelFunction(loadCommand, level) { | ||
/** Write to stdout for the LOG_LEVEL. */ | ||
var loggingFunction = function () { | ||
var text = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
text[_i] = arguments[_i]; | ||
} | ||
runConsoleCommand.apply(void 0, tslib.__spread([loadCommand, level], text)); | ||
}; | ||
/** Start a group at the LOG_LEVEL, optionally starting it as collapsed. */ | ||
loggingFunction.group = function (text, collapsed) { | ||
if (collapsed === void 0) { collapsed = false; } | ||
var command = collapsed ? console.groupCollapsed : console.group; | ||
runConsoleCommand(function () { return command; }, level, text); | ||
}; | ||
/** End the group at the LOG_LEVEL. */ | ||
loggingFunction.groupEnd = function () { | ||
runConsoleCommand(function () { return console.groupEnd; }, level); | ||
}; | ||
return loggingFunction; | ||
} | ||
/** | ||
* Run the console command provided, if the environments logging level greater than the | ||
* provided logging level. | ||
* | ||
* The loadCommand takes in a function which is called to retrieve the console.* function | ||
* to allow for jasmine spies to still work in testing. Without this method of retrieval | ||
* the console.* function, the function is saved into the closure of the created logging | ||
* function before jasmine can spy. | ||
*/ | ||
function runConsoleCommand(loadCommand, logLevel) { | ||
var text = []; | ||
for (var _i = 2; _i < arguments.length; _i++) { | ||
text[_i - 2] = arguments[_i]; | ||
} | ||
if (getLogLevel() >= logLevel) { | ||
loadCommand().apply(void 0, tslib.__spread(text)); | ||
} | ||
printToLogFile.apply(void 0, tslib.__spread([logLevel], text)); | ||
} | ||
/** | ||
* Retrieve the log level from environment variables, if the value found | ||
* based on the LOG_LEVEL environment variable is undefined, return the default | ||
* logging level. | ||
*/ | ||
function getLogLevel() { | ||
var logLevelEnvValue = (process.env["LOG_LEVEL"] || '').toUpperCase(); | ||
var logLevel = LOG_LEVELS[logLevelEnvValue]; | ||
if (logLevel === undefined) { | ||
return DEFAULT_LOG_LEVEL; | ||
} | ||
return logLevel; | ||
} | ||
/** | ||
* The number of columns used in the prepended log level information on each line of the logging | ||
* output file. | ||
*/ | ||
var LOG_LEVEL_COLUMNS = 7; | ||
/** Write the provided text to the log file, prepending each line with the log level. */ | ||
function printToLogFile(logLevel) { | ||
var text = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
text[_i - 1] = arguments[_i]; | ||
} | ||
var logLevelText = (LOG_LEVELS[logLevel] + ":").padEnd(LOG_LEVEL_COLUMNS); | ||
} | ||
|
||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
/** | ||
* Runs an given command as child process. By default, child process | ||
* output will not be printed. | ||
*/ | ||
function exec(cmd, opts) { | ||
return shelljs.exec(cmd, tslib.__assign(tslib.__assign({ silent: true }, opts), { async: false })); | ||
} | ||
|
||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
/** Whether ts-node has been installed and is available to ng-dev. */ | ||
function isTsNodeAvailable() { | ||
try { | ||
require.resolve('ts-node'); | ||
return true; | ||
} | ||
catch (_a) { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
/** | ||
* The filename expected for creating the ng-dev config, without the file | ||
* extension to allow either a typescript or javascript file to be used. | ||
*/ | ||
var CONFIG_FILE_PATH = '.ng-dev/config'; | ||
/** The configuration for ng-dev. */ | ||
var cachedConfig = null; | ||
/** | ||
* Get the configuration from the file system, returning the already loaded | ||
* copy if it is defined. | ||
*/ | ||
function getConfig() { | ||
// If the global config is not defined, load it from the file system. | ||
if (cachedConfig === null) { | ||
// The full path to the configuration file. | ||
var configPath = path.join(getRepoBaseDir(), CONFIG_FILE_PATH); | ||
// Read the configuration and validate it before caching it for the future. | ||
cachedConfig = validateCommonConfig(readConfigFile(configPath)); | ||
} | ||
// Return a clone of the cached global config to ensure that a new instance of the config | ||
// is returned each time, preventing unexpected effects of modifications to the config object. | ||
return tslib.__assign({}, cachedConfig); | ||
} | ||
/** Validate the common configuration has been met for the ng-dev command. */ | ||
function validateCommonConfig(config) { | ||
var errors = []; | ||
// Validate the github configuration. | ||
if (config.github === undefined) { | ||
errors.push("Github repository not configured. Set the \"github\" option."); | ||
} | ||
else { | ||
if (config.github.name === undefined) { | ||
errors.push("\"github.name\" is not defined"); | ||
} | ||
if (config.github.owner === undefined) { | ||
errors.push("\"github.owner\" is not defined"); | ||
} | ||
} | ||
assertNoErrors(errors); | ||
return config; | ||
} | ||
/** | ||
* Resolves and reads the specified configuration file, optionally returning an empty object if the | ||
* configuration file cannot be read. | ||
*/ | ||
function readConfigFile(configPath, returnEmptyObjectOnError) { | ||
if (returnEmptyObjectOnError === void 0) { returnEmptyObjectOnError = false; } | ||
// If the the `.ts` extension has not been set up already, and a TypeScript based | ||
// version of the given configuration seems to exist, set up `ts-node` if available. | ||
if (require.extensions['.ts'] === undefined && fs.existsSync(configPath + ".ts") && | ||
isTsNodeAvailable()) { | ||
// Ensure the module target is set to `commonjs`. This is necessary because the | ||
// dev-infra tool runs in NodeJS which does not support ES modules by default. | ||
// Additionally, set the `dir` option to the directory that contains the configuration | ||
// file. This allows for custom compiler options (such as `--strict`). | ||
require('ts-node').register({ dir: path.dirname(configPath), transpileOnly: true, compilerOptions: { module: 'commonjs' } }); | ||
} | ||
try { | ||
return require(configPath); | ||
} | ||
catch (e) { | ||
if (returnEmptyObjectOnError) { | ||
debug("Could not read configuration file at " + configPath + ", returning empty object instead."); | ||
debug(e); | ||
return {}; | ||
} | ||
error("Could not read configuration file at " + configPath + "."); | ||
error(e); | ||
process.exit(1); | ||
} | ||
} | ||
/** | ||
* Asserts the provided array of error messages is empty. If any errors are in the array, | ||
* logs the errors and exit the process as a failure. | ||
*/ | ||
function assertNoErrors(errors) { | ||
var e_1, _a; | ||
if (errors.length == 0) { | ||
return; | ||
} | ||
error("Errors discovered while loading configuration file:"); | ||
try { | ||
for (var errors_1 = tslib.__values(errors), errors_1_1 = errors_1.next(); !errors_1_1.done; errors_1_1 = errors_1.next()) { | ||
var err = errors_1_1.value; | ||
error(" - " + err); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (errors_1_1 && !errors_1_1.done && (_a = errors_1.return)) _a.call(errors_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
process.exit(1); | ||
} | ||
/** Gets the path of the directory for the repository base. */ | ||
function getRepoBaseDir() { | ||
var baseRepoDir = exec("git rev-parse --show-toplevel"); | ||
if (baseRepoDir.code) { | ||
throw Error("Unable to find the path to the base directory of the repository.\n" + | ||
"Was the command run from inside of the repo?\n\n" + | ||
("ERROR:\n " + baseRepoDir.stderr)); | ||
} | ||
return baseRepoDir.trim(); | ||
} | ||
|
||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
/** Retrieve and validate the config as `ReleaseConfig`. */ | ||
function getReleaseConfig(config = getConfig()) { | ||
var _a, _b, _c; | ||
// List of errors encountered validating the config. | ||
const errors = []; | ||
if (config.release === undefined) { | ||
errors.push(`No configuration defined for "release"`); | ||
} | ||
if (((_a = config.release) === null || _a === void 0 ? void 0 : _a.npmPackages) === undefined) { | ||
errors.push(`No "npmPackages" configured for releasing.`); | ||
} | ||
if (((_b = config.release) === null || _b === void 0 ? void 0 : _b.buildPackages) === undefined) { | ||
errors.push(`No "buildPackages" function configured for releasing.`); | ||
} | ||
if (((_c = config.release) === null || _c === void 0 ? void 0 : _c.generateReleaseNotesForHead) === undefined) { | ||
errors.push(`No "generateReleaseNotesForHead" function configured for releasing.`); | ||
} | ||
assertNoErrors(errors); | ||
return config.release; | ||
} | ||
|
||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
// Start the release package building. | ||
main(); | ||
/** Main function for building the release packages. */ | ||
function main() { | ||
return tslib.__awaiter(this, void 0, void 0, function* () { | ||
if (process.send === undefined) { | ||
throw Error('This script needs to be invoked as a NodeJS worker.'); | ||
} | ||
const config = getReleaseConfig(); | ||
const builtPackages = yield config.buildPackages(); | ||
// Transfer the built packages back to the parent process. | ||
process.send(builtPackages); | ||
}); | ||
} |
Oops, something went wrong.