1 | import * as Bluebird from 'bluebird';
|
2 | import * as cmdExists from 'command-exists';
|
3 | import { ui, spinner, Command, Blueprint, unwrap } from 'denali-cli';
|
4 | import { execSync as run } from 'child_process';
|
5 |
|
6 | const commandExists = Bluebird.promisify<boolean, string>(cmdExists);
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | export default class InstallCommand extends Command {
|
14 |
|
15 |
|
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 |
|
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 |
|
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 |
|
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 | }
|