UNPKG

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