317 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			317 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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 `.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);
 | 
						|
    });
 | 
						|
}
 |