UNPKG

2.47 kBPlain TextView Raw
1import * as Bluebird from 'bluebird';
2import * as cmdExists from 'command-exists';
3import { ui, spinner, Command, Blueprint, unwrap } from 'denali-cli';
4import { execSync as run } from 'child_process';
5
6const commandExists = Bluebird.promisify<boolean, string>(cmdExists);
7
8/**
9 * Install an addon in your app.
10 *
11 * @package commands
12 */
13export default class InstallCommand extends Command {
14
15 /* tslint:disable:completed-docs typedef */
16 static commandName = 'install';
17 static description = 'Install an addon in your app.';
18 static longDescription = unwrap`
19 Installs the supplied addon in the project. Essentially a shortcut for \`npm install --save
20 <addon>\`, with sanity checking that the project actually is a Denali addon.`;
21
22 static runsInApp = true;
23
24 static params = '<addonName>';
25
26 async run(argv: any) {
27 try {
28 await this.installAddon(argv.addonName);
29 } catch (err) {
30 await this.fail(err.stack || err);
31 }
32 }
33
34 async installAddon(addonName: string) {
35 // Find the package info first to confirm it exists and is a denali addon
36 let pkgManager = await commandExists('yarn') ? 'yarn' : 'npm';
37 await spinner.start(`Searching for "${ addonName }" addon ...`);
38 let pkgInfo;
39 let pkg;
40 try {
41 pkgInfo = run(`npm info ${ addonName } --json`);
42 pkg = JSON.parse(pkgInfo.toString());
43 } catch (e) {
44 this.fail('Lookup failed: ' + e.stack);
45 }
46 let isAddon = pkg.keywords.includes('denali-addon');
47 if (!isAddon) {
48 this.fail(`${ addonName } is not a Denali addon.`);
49 }
50 await spinner.succeed('Addon package found');
51
52 // Install the package
53 await spinner.start(`Installing ${ pkg.name }@${ pkg.version }`);
54 let installCommand = pkgManager === 'yarn' ? 'yarn add --mutex network' : 'npm install --save';
55 try {
56 run(`${ installCommand } ${ addonName }`, { stdio: 'pipe' });
57 } catch (e) {
58 this.fail('Install failed: ' + e.stack);
59 }
60 await spinner.succeed('Addon package installed');
61
62 // Run the installation blueprint
63 let blueprints = Blueprint.findBlueprints(true);
64 if (blueprints[addonName]) {
65 ui.info('Running default blueprint for addon');
66 let blueprint = new blueprints[addonName]();
67 await blueprint.generate({});
68 await spinner.succeed('Addon installed');
69 }
70
71 }
72
73 protected async fail(msg: string) {
74 await spinner.fail(`Install failed: ${ msg }`);
75 await process.exit(1);
76 }
77
78}