UNPKG

8.01 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const cli_framework_1 = require("@ionic/cli-framework");
4const utils_process_1 = require("@ionic/utils-process");
5const utils_subprocess_1 = require("@ionic/utils-subprocess");
6const Debug = require("debug");
7const color_1 = require("./color");
8const errors_1 = require("./errors");
9const hooks_1 = require("./hooks");
10const debug = Debug('ionic:lib:build');
11exports.BUILD_SCRIPT = 'ionic:build';
12exports.COMMON_BUILD_COMMAND_OPTIONS = [
13 {
14 name: 'engine',
15 summary: `Target engine (e.g. ${['browser', 'cordova'].map(e => color_1.input(e)).join(', ')})`,
16 groups: ["advanced" /* ADVANCED */],
17 },
18 {
19 name: 'platform',
20 summary: `Target platform on chosen engine (e.g. ${['ios', 'android'].map(e => color_1.input(e)).join(', ')})`,
21 groups: ["advanced" /* ADVANCED */],
22 },
23];
24class BuildRunner {
25 getPkgManagerBuildCLI() {
26 return this.e.config.get('npmClient') === 'npm' ? new NpmBuildCLI(this.e) : new YarnBuildCLI(this.e);
27 }
28 createBaseOptionsFromCommandLine(inputs, options) {
29 const separatedArgs = options['--'];
30 const platform = options['platform'] ? String(options['platform']) : undefined;
31 const engine = this.determineEngineFromCommandLine(options);
32 const project = options['project'] ? String(options['project']) : undefined;
33 const verbose = !!options['verbose'];
34 return { '--': separatedArgs ? separatedArgs : [], engine, platform, project, verbose };
35 }
36 determineEngineFromCommandLine(options) {
37 if (options['engine']) {
38 return String(options['engine']);
39 }
40 if (options['cordova']) {
41 return 'cordova';
42 }
43 return 'browser';
44 }
45 async beforeBuild(options) {
46 const hook = new BuildBeforeHook(this.e);
47 try {
48 await hook.run({ name: hook.name, build: options });
49 }
50 catch (e) {
51 if (e instanceof cli_framework_1.BaseError) {
52 throw new errors_1.FatalException(e.message);
53 }
54 throw e;
55 }
56 }
57 async run(options) {
58 debug('build options: %O', options);
59 if (options.engine === 'cordova' && !options.platform) {
60 this.e.log.warn(`Cordova engine chosen without a target platform. This could cause issues. Please use the ${color_1.input('--platform')} option.`);
61 }
62 await this.beforeBuild(options);
63 await this.buildProject(options);
64 await this.afterBuild(options);
65 }
66 async afterBuild(options) {
67 const hook = new BuildAfterHook(this.e);
68 try {
69 await hook.run({ name: hook.name, build: options });
70 }
71 catch (e) {
72 if (e instanceof cli_framework_1.BaseError) {
73 throw new errors_1.FatalException(e.message);
74 }
75 throw e;
76 }
77 }
78}
79exports.BuildRunner = BuildRunner;
80class BuildCLI {
81 constructor(e) {
82 this.e = e;
83 /**
84 * If true, the Build CLI will not prompt to be installed.
85 */
86 this.global = false;
87 }
88 get resolvedProgram() {
89 if (this._resolvedProgram) {
90 return this._resolvedProgram;
91 }
92 return this.program;
93 }
94 /**
95 * Build the environment variables for this Build CLI. Called by `this.run()`.
96 */
97 async buildEnvVars(options) {
98 return process.env;
99 }
100 async resolveScript() {
101 if (typeof this.script === 'undefined') {
102 return;
103 }
104 const pkg = await this.e.project.requirePackageJson();
105 return pkg.scripts && pkg.scripts[this.script];
106 }
107 async build(options) {
108 this._resolvedProgram = await this.resolveProgram();
109 await this.runWrapper(options);
110 }
111 async runWrapper(options) {
112 try {
113 return await this.run(options);
114 }
115 catch (e) {
116 if (!(e instanceof errors_1.BuildCLIProgramNotFoundException)) {
117 throw e;
118 }
119 if (this.global) {
120 this.e.log.nl();
121 throw new errors_1.FatalException(`${color_1.input(this.pkg)} is required for this command to work properly.`);
122 }
123 this.e.log.nl();
124 this.e.log.info(`Looks like ${color_1.input(this.pkg)} isn't installed in this project.\n` +
125 `This package is required for this command to work properly.`);
126 const installed = await this.promptToInstall();
127 if (!installed) {
128 this.e.log.nl();
129 throw new errors_1.FatalException(`${color_1.input(this.pkg)} is required for this command to work properly.`);
130 }
131 return this.run(options);
132 }
133 }
134 async run(options) {
135 const args = await this.buildArgs(options);
136 const env = await this.buildEnvVars(options);
137 try {
138 await this.e.shell.run(this.resolvedProgram, args, { stdio: 'inherit', cwd: this.e.project.directory, fatalOnNotFound: false, env: utils_process_1.createProcessEnv(env) });
139 }
140 catch (e) {
141 if (e instanceof utils_subprocess_1.SubprocessError && e.code === utils_subprocess_1.ERROR_COMMAND_NOT_FOUND) {
142 throw new errors_1.BuildCLIProgramNotFoundException(`${color_1.strong(this.resolvedProgram)} command not found.`);
143 }
144 throw e;
145 }
146 }
147 async resolveProgram() {
148 if (typeof this.script !== 'undefined') {
149 debug(`Looking for ${color_1.ancillary(this.script)} npm script.`);
150 if (await this.resolveScript()) {
151 debug(`Using ${color_1.ancillary(this.script)} npm script.`);
152 return this.e.config.get('npmClient');
153 }
154 }
155 return this.program;
156 }
157 async promptToInstall() {
158 const { pkgManagerArgs } = await Promise.resolve().then(() => require('./utils/npm'));
159 const [manager, ...managerArgs] = await pkgManagerArgs(this.e.config.get('npmClient'), { command: 'install', pkg: this.pkg, saveDev: true, saveExact: true });
160 this.e.log.nl();
161 const confirm = await this.e.prompt({
162 name: 'confirm',
163 message: `Install ${color_1.input(this.pkg)}?`,
164 type: 'confirm',
165 });
166 if (!confirm) {
167 this.e.log.warn(`Not installing--here's how to install manually: ${color_1.input(`${manager} ${managerArgs.join(' ')}`)}`);
168 return false;
169 }
170 await this.e.shell.run(manager, managerArgs, { cwd: this.e.project.directory });
171 return true;
172 }
173}
174exports.BuildCLI = BuildCLI;
175class PkgManagerBuildCLI extends BuildCLI {
176 constructor() {
177 super(...arguments);
178 this.global = true;
179 this.script = exports.BUILD_SCRIPT;
180 }
181 async resolveProgram() {
182 return this.program;
183 }
184 async buildArgs(options) {
185 const { pkgManagerArgs } = await Promise.resolve().then(() => require('./utils/npm'));
186 const [, ...pkgArgs] = await pkgManagerArgs(this.program, { command: 'run', script: this.script, scriptArgs: [...options['--'] || []] });
187 return pkgArgs;
188 }
189}
190class NpmBuildCLI extends PkgManagerBuildCLI {
191 constructor() {
192 super(...arguments);
193 this.name = 'npm CLI';
194 this.pkg = 'npm';
195 this.program = 'npm';
196 }
197}
198exports.NpmBuildCLI = NpmBuildCLI;
199class YarnBuildCLI extends PkgManagerBuildCLI {
200 constructor() {
201 super(...arguments);
202 this.name = 'Yarn';
203 this.pkg = 'yarn';
204 this.program = 'yarn';
205 }
206}
207exports.YarnBuildCLI = YarnBuildCLI;
208class BuildBeforeHook extends hooks_1.Hook {
209 constructor() {
210 super(...arguments);
211 this.name = 'build:before';
212 }
213}
214class BuildAfterHook extends hooks_1.Hook {
215 constructor() {
216 super(...arguments);
217 this.name = 'build:after';
218 }
219}