UNPKG

@enact/cli

Version:

Full-featured build environment tool for Enact applications.

184 lines (171 loc) 6.29 kB
/* eslint-env node, es6 */ const path = require('path'); const fs = require('fs'); const spawn = require('cross-spawn'); const minimist = require('minimist'); const resolveSync = require('resolve').sync; let chalk; function displayHelp() { let e = 'node ' + path.relative(process.cwd(), __filename); if (require.main !== module) e = 'enact info'; console.log(' Usage'); console.log(` ${e} [options]`); console.log(); console.log(' Options'); console.log(' --dev Include dev dependencies'); console.log(' --cli Display CLI information'); console.log(' -v, --version Display version information'); console.log(' -h, --help Display help information'); console.log(); process.exit(0); } function logVersion(pkg, rel = __dirname) { try { const jsonPath = resolveSync(pkg + '/package.json', {basedir: rel}); const meta = require(jsonPath); const dir = path.dirname(jsonPath); if (fs.lstatSync(dir).isSymbolicLink()) { const realDir = fs.realpathSync(dir); const git = gitInfo(realDir); console.log(meta.name + ': ' + (git || meta.version)); console.log(chalk.cyan('\tSymlinked from'), realDir); } else { console.log(meta.name + ': ' + meta.version); } } catch (e) { console.log(pkg + ': ' + chalk.red('<unknown>')); } } function gitInfo(dir) { const git = (args = []) => { try { const result = spawn.sync('git', args, {encoding: 'utf8', cwd: dir, env: process.env}); if (!result.error && result.status === 0) return result.stdout.trim(); } catch (e) { // do nothing } }; const tag = git(['describe', '--tags', '--exact-match']); if (tag) { return chalk.green(`${tag} (git)`); } else { const branch = git(['symbolic-ref', '-q', '--short', 'HEAD']) || 'HEAD'; const commit = git(['rev-parse', '--short', 'HEAD']); if (commit) return chalk.green(`${branch} @ ${commit} (git)`); } } function globalModules() { try { const result = spawn.sync('npm', ['config', 'get', 'prefix', '-g'], { cwd: process.cwd(), env: process.env }); if (result.error || result.status !== 0 || !(result.stdout = result.stdout.trim())) { return require('global-modules'); } else if (process.platform === 'win32' || ['msys', 'cygwin'].includes(process.env.OSTYPE)) { return path.resolve(result.stdout, 'node_modules'); } else { return path.resolve(result.stdout, 'lib/node_modules'); } } catch (e) { return require('global-modules'); } } function api({cliInfo = false, dev = false} = {}) { return new Promise((resolve, reject) => { try { if (cliInfo) { // Display info on CLI itself const gm = globalModules(); const gCLI = path.join(gm, '@enact', 'cli'); const isGlobal = fs.existsSync(gCLI) && path.dirname(require.resolve(path.join(gCLI, 'package.json'))) === path.dirname(__dirname); console.log(chalk.yellow.bold('==Enact CLI Info==')); if (isGlobal && fs.lstatSync(gCLI).isSymbolicLink()) { const ver = gitInfo(__dirname) || require('../package.json').version; console.log(`Enact CLI: ${ver}`); console.log(chalk.cyan('\tSymlinked from'), path.dirname(__dirname)); } else { console.log(`@enact/cli: ${require('../package.json').version}`); } console.log(`Installed Globally: ${isGlobal}`); if (isGlobal) console.log(`Global Modules: ${gm}`); console.log(); // Display info on in-house components, likely to be linked in console.log(chalk.yellow.bold('==Enact Components==')); [ '@enact/dev-utils', 'babel-preset-enact', 'eslint-config-enact', 'eslint-plugin-enact', 'postcss-resolution-independence' ].forEach(dep => logVersion(dep)); console.log(); // Display info on notable 3rd party components console.log(chalk.yellow.bold('==Third Party Components==')); console.log(`Babel: ${require('@babel/core/package.json').version}`); console.log(`ESLint: ${require('eslint/package.json').version}`); console.log(`Jest: ${require('jest/package.json').version}`); console.log(`LESS: ${require('less/package.json').version}`); console.log(`Webpack: ${require('webpack/package.json').version}`); } else { const app = require('@enact/dev-utils').optionParser; const meta = require(path.join(app.context, 'package.json')); const bl = require( resolveSync('browserslist', { basedir: path.dirname(require.resolve('@enact/dev-utils/package.json')), preserveSymlinks: false }) ); app.setEnactTargetsAsDefault(); console.log(chalk.yellow.bold('==Project Info==')); console.log(`Name: ${app.name}`); console.log(`Version: ${gitInfo(app.context) || meta.version}`); console.log(`Path: ${app.context}`); console.log(`Theme: ${(app.theme || {}).name}`); if (app.proxer) console.log(`Serve Proxy: ${app.proxy}`); if (app.template) console.log(`Template: ${app.template}`); if (app.externalStartup) console.log(`External Startup: ${app.externalStartup}`); if (app.deep) console.log(`Deep: ${app.deep}`); if (app.forceCSSModules) console.log(`Force CSS Modules: ${app.forceCSSModules}`); console.log(`Resolution Independence: ${JSON.stringify(app.ri)}`); console.log(`Browserslist: ${bl.loadConfig({path: app.context})}`); console.log(`Environment: ${app.environment}`); console.log(); console.log(chalk.yellow.bold('==Dependencies==')); if (meta.dependencies) { Object.keys(meta.dependencies).forEach(dep => { logVersion(dep, app.context); }); } if (dev && meta.devDependencies) { console.log(); console.log(chalk.yellow.bold('==Dev Dependencies==')); Object.keys(meta.devDependencies).forEach(dep => { logVersion(dep, app.context); }); } } resolve(); } catch (e) { reject(e); } }); } function cli(args) { const opts = minimist(args, { boolean: ['cli', 'help'], alias: {h: 'help'} }); if (opts.help) displayHelp(); import('chalk').then(({default: _chalk}) => { chalk = _chalk; api({cliInfo: opts.cli, dev: opts.dev}).catch(err => { console.error(chalk.red('ERROR: ') + 'Failed to display info.\n' + err.message); process.exit(1); }); }); } module.exports = {api, cli}; if (require.main === module) cli(process.argv.slice(2));