1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const path = require("path");
|
5 | const util = require("util");
|
6 | const chalk_1 = require("chalk");
|
7 | const cli_utils_1 = require("@ionic/cli-utils");
|
8 | const errors_1 = require("@ionic/cli-utils/lib/errors");
|
9 | const init_1 = require("@ionic/cli-utils/lib/init");
|
10 | const fs_1 = require("@ionic/cli-framework/utils/fs");
|
11 | const guards_1 = require("@ionic/cli-utils/guards");
|
12 | const commands_1 = require("./commands");
|
13 | const name = 'ionic';
|
14 | exports.namespace = new commands_1.IonicNamespace();
|
15 | function registerHooks(hooks) {
|
16 | hooks.register(name, 'info', ({ env, project }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
17 | const osName = yield Promise.resolve().then(() => require('os-name'));
|
18 | const os = osName();
|
19 | const node = process.version;
|
20 | const npm = yield env.shell.cmdinfo('npm', ['-v']);
|
21 | const config = yield env.config.load();
|
22 | const info = [
|
23 | { type: 'cli-packages', key: name, flair: 'Ionic CLI', value: env.plugins.ionic.meta.version, path: path.dirname(path.dirname(env.plugins.ionic.meta.filePath)) },
|
24 | { type: 'system', key: 'Node', value: node },
|
25 | { type: 'system', key: 'npm', value: npm || 'not installed' },
|
26 | { type: 'system', key: 'OS', value: os },
|
27 | { type: 'misc', key: 'backend', value: config.backend },
|
28 | ];
|
29 | const projectFile = project.directory ? yield project.load() : undefined;
|
30 | if (projectFile) {
|
31 | if (projectFile.type === 'ionic1') {
|
32 | const { getIonic1Version } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/ionic1/utils'));
|
33 | const ionic1Version = yield getIonic1Version(env);
|
34 | info.push({ type: 'local-packages', key: 'Ionic Framework', value: ionic1Version ? `ionic1 ${ionic1Version}` : 'unknown' });
|
35 | }
|
36 | else if (projectFile.type === 'ionic-angular') {
|
37 | const { getIonicAngularVersion, getAppScriptsVersion } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/ionic-angular/utils'));
|
38 | const [ionicAngularVersion, appScriptsVersion] = yield Promise.all([getIonicAngularVersion(env, project), getAppScriptsVersion(env, project)]);
|
39 | info.push({ type: 'local-packages', key: 'Ionic Framework', value: ionicAngularVersion ? `ionic-angular ${ionicAngularVersion}` : 'not installed' });
|
40 | info.push({ type: 'local-packages', key: '@ionic/app-scripts', value: appScriptsVersion ? appScriptsVersion : 'not installed' });
|
41 | }
|
42 | if (projectFile.integrations.cordova && projectFile.integrations.cordova.enabled !== false) {
|
43 | const { getAndroidSdkToolsVersion } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/android'));
|
44 | const { getCordovaCLIVersion, getCordovaPlatformVersions } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/cordova/utils'));
|
45 | const [cordovaVersion, cordovaPlatforms, xcode, iosDeploy, iosSim, androidSdkToolsVersion,] = yield Promise.all([
|
46 | getCordovaCLIVersion(env),
|
47 | getCordovaPlatformVersions(env),
|
48 | env.shell.cmdinfo('xcodebuild', ['-version']),
|
49 | env.shell.cmdinfo('ios-deploy', ['--version']),
|
50 | env.shell.cmdinfo('ios-sim', ['--version']),
|
51 | getAndroidSdkToolsVersion(),
|
52 | ]);
|
53 | info.push({ type: 'global-packages', key: 'cordova', flair: 'Cordova CLI', value: cordovaVersion || 'not installed' });
|
54 | info.push({ type: 'local-packages', key: 'Cordova Platforms', value: cordovaPlatforms || 'none' });
|
55 | if (xcode) {
|
56 | info.push({ type: 'system', key: 'Xcode', value: xcode });
|
57 | }
|
58 | if (iosDeploy) {
|
59 | info.push({ type: 'system', key: 'ios-deploy', value: iosDeploy });
|
60 | }
|
61 | if (iosSim) {
|
62 | info.push({ type: 'system', key: 'ios-sim', value: iosSim });
|
63 | }
|
64 | if (androidSdkToolsVersion) {
|
65 | info.push({ type: 'system', key: 'Android SDK Tools', value: androidSdkToolsVersion });
|
66 | }
|
67 | info.push({ type: 'environment', key: 'ANDROID_HOME', value: process.env.ANDROID_HOME || 'not set' });
|
68 | }
|
69 | if (projectFile.integrations.gulp && projectFile.integrations.gulp.enabled !== false) {
|
70 | const { getGulpVersion } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/gulp'));
|
71 | const gulpVersion = yield getGulpVersion(env);
|
72 | info.push({ type: 'global-packages', key: 'Gulp CLI', value: gulpVersion || 'not installed globally' });
|
73 | }
|
74 | }
|
75 | return info;
|
76 | }));
|
77 | hooks.register(name, 'cordova:project:info', ({ env }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
78 | const { ConfigXml } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/cordova/config'));
|
79 | const conf = yield ConfigXml.load(env.project.directory);
|
80 | return conf.getProjectInfo();
|
81 | }));
|
82 | }
|
83 | exports.registerHooks = registerHooks;
|
84 | function generateRootPlugin() {
|
85 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
86 | const { getPluginMeta } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/plugins'));
|
87 | return {
|
88 | namespace: exports.namespace,
|
89 | registerHooks,
|
90 | meta: yield getPluginMeta(__filename),
|
91 | };
|
92 | });
|
93 | }
|
94 | exports.generateRootPlugin = generateRootPlugin;
|
95 | function run(pargv, env) {
|
96 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
97 | const now = new Date();
|
98 | let err;
|
99 | pargv = init_1.modifyArguments(pargv.slice(2));
|
100 | env['IONIC_CLI_LIB'] = __filename;
|
101 | const { isSuperAgentError } = yield Promise.resolve().then(() => require('@ionic/cli-utils/guards'));
|
102 | const { isValidationErrorArray } = yield Promise.resolve().then(() => require('@ionic/cli-framework/guards'));
|
103 | const plugin = yield generateRootPlugin();
|
104 | const ienv = yield cli_utils_1.generateIonicEnvironment(plugin, pargv, env);
|
105 | try {
|
106 | const config = yield ienv.config.load();
|
107 | registerHooks(ienv.hooks);
|
108 | ienv.log.debug(() => util.inspect(ienv.meta, { breakLength: Infinity, colors: chalk_1.default.enabled }));
|
109 | if (env['IONIC_EMAIL'] && env['IONIC_PASSWORD']) {
|
110 | ienv.log.debug(() => `${chalk_1.default.bold('IONIC_EMAIL')} / ${chalk_1.default.bold('IONIC_PASSWORD')} environment variables detected`);
|
111 | if (config.user.email !== env['IONIC_EMAIL']) {
|
112 | ienv.log.debug(() => `${chalk_1.default.bold('IONIC_EMAIL')} mismatch with current session--attempting login`);
|
113 | try {
|
114 | yield ienv.session.login(env['IONIC_EMAIL'], env['IONIC_PASSWORD']);
|
115 | }
|
116 | catch (e) {
|
117 | ienv.log.error(`Error occurred during automatic login via ${chalk_1.default.bold('IONIC_EMAIL')} / ${chalk_1.default.bold('IONIC_PASSWORD')} environment variables.`);
|
118 | throw e;
|
119 | }
|
120 | }
|
121 | }
|
122 | if (ienv.project.directory) {
|
123 | const nodeModulesExists = yield fs_1.pathExists(path.join(ienv.project.directory, 'node_modules'));
|
124 | if (!nodeModulesExists) {
|
125 | const confirm = yield ienv.prompt({
|
126 | type: 'confirm',
|
127 | name: 'confirm',
|
128 | message: `Looks like a fresh checkout! No ${chalk_1.default.green('./node_modules')} directory found. Would you like to install project dependencies?`,
|
129 | });
|
130 | if (confirm) {
|
131 | ienv.log.info('Installing dependencies may take several minutes!');
|
132 | const { pkgManagerArgs } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/utils/npm'));
|
133 | const [installer, ...installerArgs] = yield pkgManagerArgs(ienv, { command: 'install' });
|
134 | yield ienv.shell.run(installer, installerArgs, {});
|
135 | }
|
136 | }
|
137 | }
|
138 | const argv = init_1.parseArgs(pargv, { boolean: true, string: '_' });
|
139 |
|
140 | const foundCommand = init_1.mapLegacyCommand(argv._[0]);
|
141 | if (foundCommand) {
|
142 | ienv.log.msg(`The ${chalk_1.default.green(argv._[0])} command has been renamed. To find out more, run:\n\n` +
|
143 | ` ${chalk_1.default.green(`ionic ${foundCommand} --help`)}\n\n`);
|
144 | }
|
145 | else {
|
146 | const { loadPlugins } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/plugins'));
|
147 | try {
|
148 | yield loadPlugins(ienv);
|
149 | }
|
150 | catch (e) {
|
151 | if (e.fatal) {
|
152 | throw e;
|
153 | }
|
154 | ienv.log.error(chalk_1.default.red.bold('Error occurred while loading plugins. CLI functionality may be limited.'));
|
155 | ienv.log.debug(() => chalk_1.default.red(chalk_1.default.bold('Plugin error: ') + (e.stack ? e.stack : e)));
|
156 | }
|
157 | if (ienv.flags.interactive) {
|
158 | if (yield ienv.config.isUpdatingEnabled()) {
|
159 | const { checkForDaemon } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/daemon'));
|
160 | yield checkForDaemon(ienv);
|
161 | const { checkForUpdates, getLatestPluginVersion, versionNeedsUpdating } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/plugins'));
|
162 | const latestVersion = yield getLatestPluginVersion(ienv, plugin.meta.name, plugin.meta.version);
|
163 | if (latestVersion) {
|
164 | plugin.meta.latestVersion = latestVersion;
|
165 | plugin.meta.updateAvailable = yield versionNeedsUpdating(plugin.meta.version, latestVersion);
|
166 | yield checkForUpdates(ienv);
|
167 | }
|
168 | }
|
169 | }
|
170 | yield ienv.hooks.fire('plugins:init', { env: ienv });
|
171 | yield exports.namespace.runCommand(ienv, pargv);
|
172 | config.state.lastCommand = now.toISOString();
|
173 | }
|
174 | }
|
175 | catch (e) {
|
176 | err = e;
|
177 | }
|
178 | try {
|
179 | yield Promise.all([
|
180 | ienv.config.save(),
|
181 | ienv.project.save(),
|
182 | ienv.daemon.save(),
|
183 | ]);
|
184 | }
|
185 | catch (e) {
|
186 | ienv.log.error(String(e.stack ? e.stack : e));
|
187 | }
|
188 | if (err) {
|
189 | ienv.tasks.fail();
|
190 | process.exitCode = 1;
|
191 | if (isValidationErrorArray(err)) {
|
192 | for (let e of err) {
|
193 | ienv.log.error(e.message);
|
194 | }
|
195 | ienv.log.msg(`Use the ${chalk_1.default.green('--help')} flag for more details.`);
|
196 | }
|
197 | else if (isSuperAgentError(err)) {
|
198 | const { formatSuperAgentError } = yield Promise.resolve().then(() => require('@ionic/cli-utils/lib/http'));
|
199 | ienv.log.msg(formatSuperAgentError(err));
|
200 | }
|
201 | else if (err.code && err.code === 'ENOTFOUND' || err.code === 'ECONNREFUSED') {
|
202 | ienv.log.error(`Network connectivity error occurred, are you offline?\n` +
|
203 | `If you are behind a firewall and need to configure proxy settings, see: ${chalk_1.default.bold('https://ionicframework.com/docs/cli/configuring.html#using-a-proxy')}\n\n` +
|
204 | chalk_1.default.red(String(err.stack ? err.stack : err)));
|
205 | }
|
206 | else if (guards_1.isExitCodeException(err)) {
|
207 | process.exitCode = err.exitCode;
|
208 | if (err.message) {
|
209 | if (err.exitCode > 0) {
|
210 | ienv.log.error(err.message);
|
211 | }
|
212 | else {
|
213 | ienv.log.msg(err.message);
|
214 | }
|
215 | }
|
216 | }
|
217 | else if (err instanceof errors_1.Exception) {
|
218 | ienv.log.error(err.message);
|
219 | }
|
220 | else {
|
221 | ienv.log.msg(chalk_1.default.red(String(err.stack ? err.stack : err)));
|
222 | if (err.stack) {
|
223 | ienv.log.debug(() => chalk_1.default.red(String(err.stack)));
|
224 | }
|
225 | }
|
226 | }
|
227 | yield ienv.close();
|
228 | });
|
229 | }
|
230 | exports.run = run;
|