UNPKG

@dojo/cli

Version:

Dojo CLI utility

196 lines 7.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const path_1 = require("path"); const chalk_1 = require("chalk"); const allCommands_1 = require("../allCommands"); const installableCommands_1 = require("../installableCommands"); const pkgDir = require('pkg-dir'); // exported for tests exports.versionCurrentVersion = ` You are currently running @dojo/cli@{version} `; exports.versionNoRegisteredCommands = ` There are no registered commands available.`; exports.versionNoVersion = chalk_1.default.yellow('package.json missing'); exports.versionRegisteredCommands = ` The currently installed commands are: `; const INBUILT_COMMAND_VERSION = '__IN_BUILT_COMMAND__'; function getLatestCommandVersions() { return tslib_1.__awaiter(this, void 0, void 0, function* () { const packagePath = pkgDir.sync(__dirname); const packageJsonFilePath = path_1.join(packagePath, 'package.json'); const packageJson = require(packageJsonFilePath); console.log(chalk_1.default.yellow('Fetching latest version information...')); return yield installableCommands_1.getLatestCommands(packageJson.name); }); } /** * Iterate through a ModuleVersions and output if the module can be updated to a later version. * Version checks are async calls to npm - so module repository dependant for now. * * @param {ModuleVersion[]} moduleVersions * @returns {{name, version, group}[]} */ function areCommandsOutdated(moduleVersions) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const latestCommands = yield getLatestCommandVersions(); const latestVersions = latestCommands.reduce((versions, { name, version }) => { versions[name] = version; return versions; }, {}); return moduleVersions.map(({ name, version, group }) => { const latest = latestVersions[name]; return { name, version, latest, group }; }); }); } /** * Is the command a built in command as opposed to an installed command * @param commandPath path to the command module * @returns {boolean} */ function isBuiltInCommand(commandPath) { /*__dirname seems best as the only way to truly know if a command is built in, is by location. * Since this module is a built in command, we can use our location. * This was preferable to using packageDir and relative paths, because we may alter where we build to (_build/src...) */ return commandPath.startsWith(__dirname); } /** * Create the stdout output * @param myPackageDetails * @param commandVersions * @returns {string} */ function createOutput(myPackageDetails, commandVersions) { let output = exports.versionCurrentVersion.replace('{version}', chalk_1.default.blue(myPackageDetails.version)); if (commandVersions.length) { output += exports.versionRegisteredCommands; output += '\n' + commandVersions .map((command) => { return command.version === command.latest || command.latest === undefined ? ` ▹ ${command.name}@${chalk_1.default.blue(command.version)}` : ` ▹ ${command.name}@${chalk_1.default.blue(command.version)} ${chalk_1.default.green(`(latest is ${command.latest})`)}`; }) .join('\n') + '\n'; } else { output += exports.versionNoRegisteredCommands; } return output; } function register(options) { options('o', { alias: 'outdated', describe: 'Output a list of installed commands and check if any can be updated to a more recent stable version.', demand: false, type: 'boolean' }); } /** * Read information about a package/module, if available, or return default values. * * @param {string} packageDir The directory containing the package.json file. * @returns {{name: (any|string), version: any}} */ function readPackageDetails(packageDir) { let data = {}; // rather than add another prop to Command, declare the command to be builtin by setting its version if (isBuiltInCommand(packageDir)) { data.version = INBUILT_COMMAND_VERSION; } else { try { data = require(path_1.join(packageDir, 'package.json')); } catch (e) { data.name = packageDir; data.version = exports.versionNoVersion; } } return { name: data.name, version: data.version }; } /** * Iterate through a CommandsMap and retrieve the module details of each module referenced in the * CommandsMap. The returned list is sorted in alphabetical order, by group. * * @param {CommandsMap} commandsMap * @returns {{name, version, group}[]} */ function buildVersions(groupMap) { /* * commandsMap comes in as a map of [command-name, command]. The command has a default command, * the map will actually contain two entries for one command, on for the default command, one for the real, * expanded, command. * * Loop over commandsMap and create a new map with one entry per command, then loop over each entry and extract * the package details. */ const consolidatedCommands = []; for (let [, commandMap] of groupMap.entries()) { for (let [, value] of commandMap.entries()) { consolidatedCommands.push([value.path, value.group]); } } const versionInfo = consolidatedCommands .map(([path, group]) => { const { name, version } = readPackageDetails(path); return { name, version, group }; }) .filter((val) => { // remove inbuilt commands or commands that dont have a valid version in the package.json return val.version !== exports.versionNoVersion && val.version !== INBUILT_COMMAND_VERSION; }) .sort((a, b) => (a.group > b.group ? 1 : -1)); return versionInfo; } /** * Returns a string describing the command group, module name, and module version of each * command referenced in a specified CommandsMap. This is used to print the string. * * @param {CommandsMap} commandsMap maps of commands to output the versions for * @param {boolean} checkOutdated should we check if there is a later stable version available for the command * @returns {string} the stdout output */ function createVersionsString(groupMap, checkOutdated) { const packagePath = pkgDir.sync(__dirname); const myPackageDetails = readPackageDetails(packagePath); // fetch the cli's package details const versions = buildVersions(groupMap); if (checkOutdated) { return areCommandsOutdated(versions).then((commandVersions) => createOutput(myPackageDetails, commandVersions), (err) => { return `Something went wrong trying to fetch command versions: ${err.message}`; }); } else { return Promise.resolve(createOutput(myPackageDetails, versions)); } } function run(helper, args) { return allCommands_1.default() .then((groupMap) => { return createVersionsString(groupMap, args.outdated); }) .then(console.log); } exports.default = { name: '', group: 'version', description: 'provides version information for all installed commands and the cli itself', register, global: true, installed: true, run }; //# sourceMappingURL=version.js.map