@@ -2,17 +2,16 @@ import { Footnote, MetadataGroup } from '@ionic/cli-framework';
2
2
import { onBeforeExit , sleepForever } from '@ionic/utils-process' ;
3
3
import * as Debug from 'debug' ;
4
4
import * as lodash from 'lodash' ;
5
- import * as url from 'url' ;
6
5
7
- import { CommandInstanceInfo , CommandLineInputs , CommandLineOptions , CommandMetadata , CommandMetadataOption , CommandPreRun , IShellRunOptions } from '../../definitions' ;
8
- import { COMMON_BUILD_COMMAND_OPTIONS , build } from '../../lib/build' ;
6
+ import { CommandInstanceInfo , CommandLineInputs , CommandLineOptions , CommandMetadata , CommandMetadataOption , CommandPreRun , IShellRunOptions , ServeDetails } from '../../definitions' ;
7
+ import { COMMON_BUILD_COMMAND_OPTIONS } from '../../lib/build' ;
9
8
import { input , strong , weak } from '../../lib/color' ;
10
- import { FatalException } from '../../lib/errors' ;
9
+ import { FatalException , RunnerException } from '../../lib/errors' ;
11
10
import { loadConfigXml } from '../../lib/integrations/cordova/config' ;
12
11
import { getPackagePath } from '../../lib/integrations/cordova/project' ;
13
12
import { filterArgumentsForCordova , generateOptionsForCordovaBuild } from '../../lib/integrations/cordova/utils' ;
14
13
import { SUPPORTED_PLATFORMS , checkNativeRun , createNativeRunArgs , createNativeRunListArgs , getNativeTargets , runNativeRun } from '../../lib/native-run' ;
15
- import { COMMON_SERVE_COMMAND_OPTIONS , LOCAL_ADDRESSES , serve } from '../../lib/serve' ;
14
+ import { COMMON_SERVE_COMMAND_OPTIONS , LOCAL_ADDRESSES } from '../../lib/serve' ;
16
15
import { createPrefixedWriteStream } from '../../lib/utils/logger' ;
17
16
18
17
import { CORDOVA_BUILD_EXAMPLE_COMMANDS , CORDOVA_RUN_OPTIONS , CordovaCommand } from './base' ;
@@ -233,49 +232,64 @@ Just like with ${input('ionic cordova build')}, you can pass additional options
233
232
}
234
233
235
234
async run ( inputs : CommandLineInputs , options : CommandLineOptions ) : Promise < void > {
236
- if ( options [ 'livereload' ] ) {
237
- await this . runServeDeploy ( inputs , options ) ;
238
- } else {
239
- await this . runBuildDeploy ( inputs , options ) ;
235
+ try {
236
+ if ( options [ 'livereload' ] ) {
237
+ await this . runServeDeploy ( inputs , options ) ;
238
+ } else {
239
+ await this . runBuildDeploy ( inputs , options ) ;
240
+ }
241
+ } catch ( e ) {
242
+ if ( e instanceof RunnerException ) {
243
+ throw new FatalException ( e . message ) ;
244
+ }
245
+
246
+ throw e ;
240
247
}
241
248
}
242
249
243
- protected async runServeDeploy ( inputs : CommandLineInputs , options : CommandLineOptions ) {
250
+ protected async runServeDeploy ( inputs : CommandLineInputs , options : CommandLineOptions ) : Promise < void > {
244
251
const conf = await loadConfigXml ( this . integration ) ;
245
252
const metadata = await this . getMetadata ( ) ;
246
253
247
254
if ( ! this . project ) {
248
255
throw new FatalException ( `Cannot run ${ input ( `ionic cordova ${ metadata . name } ` ) } outside a project directory.` ) ;
249
256
}
250
257
251
- let livereloadUrl = options [ 'livereload-url' ] ? String ( options [ 'livereload-url' ] ) : undefined ;
258
+ const runner = await this . project . requireServeRunner ( ) ;
259
+ const runnerOpts = runner . createOptionsFromCommandLine ( inputs , generateOptionsForCordovaBuild ( metadata , inputs , options ) ) ;
252
260
253
- if ( ! livereloadUrl ) {
254
- // TODO: use runner directly
255
- const details = await serve ( { flags : this . env . flags , config : this . env . config , log : this . env . log , prompt : this . env . prompt , shell : this . env . shell , project : this . project } , inputs , generateOptionsForCordovaBuild ( metadata , inputs , options ) ) ;
261
+ /**
262
+ * With the --livereload-url option, this command won't perform a serve. If
263
+ * this is the case, details will be undefined.
264
+ */
265
+ let details : ServeDetails | undefined ;
266
+ let serverUrl = options [ 'livereload-url' ] ? String ( options [ 'livereload-url' ] ) : undefined ;
267
+
268
+ if ( ! serverUrl ) {
269
+ details = await runner . run ( runnerOpts ) ;
256
270
257
271
if ( details . externallyAccessible === false && ! options [ 'native-run' ] ) {
258
272
const extra = LOCAL_ADDRESSES . includes ( details . externalAddress ) ? '\nEnsure you have proper port forwarding setup from your device to your computer.' : '' ;
259
273
this . env . log . warn ( `Your device or emulator may not be able to access ${ strong ( details . externalAddress ) } .${ extra } \n\n` ) ;
260
274
}
261
275
262
- livereloadUrl = `${ details . protocol || 'http' } ://${ options [ 'native-run' ] ? details . localAddress : details . externalAddress } :${ details . port } ` ;
276
+ serverUrl = `${ details . protocol || 'http' } ://${ details . externalAddress } :${ details . port } ` ;
263
277
}
264
278
265
279
onBeforeExit ( async ( ) => {
266
280
conf . resetContentSrc ( ) ;
267
281
await conf . save ( ) ;
268
282
} ) ;
269
283
270
- conf . writeContentSrc ( livereloadUrl ) ;
284
+ conf . writeContentSrc ( serverUrl ) ;
271
285
await conf . save ( ) ;
272
286
273
287
const cordovalogws = createPrefixedWriteStream ( this . env . log , weak ( `[cordova]` ) ) ;
274
288
275
289
if ( options [ 'native-run' ] ) {
276
290
const [ platform ] = inputs ;
277
291
const packagePath = await getPackagePath ( conf . getProjectInfo ( ) . name , platform , ! options [ 'device' ] ) ;
278
- const { port : portForward } = url . parse ( livereloadUrl ) ;
292
+ const forwardedPorts = details ? runner . getUsedPorts ( runnerOpts , details ) : [ ] ;
279
293
280
294
const buildOpts : IShellRunOptions = { stream : cordovalogws } ;
281
295
// ignore very verbose compiler output unless --verbose (still pipe stderr)
@@ -284,14 +298,14 @@ Just like with ${input('ionic cordova build')}, you can pass additional options
284
298
}
285
299
286
300
await this . runCordova ( filterArgumentsForCordova ( { ...metadata , name : 'build' } , options ) , buildOpts ) ;
287
- await this . runNativeRun ( createNativeRunArgs ( { packagePath, platform, portForward } , options ) ) ;
301
+ await this . runNativeRun ( createNativeRunArgs ( { packagePath, platform, forwardedPorts } , options ) ) ;
288
302
} else {
289
303
await this . runCordova ( filterArgumentsForCordova ( metadata , options ) , { stream : cordovalogws } ) ;
290
304
await sleepForever ( ) ;
291
305
}
292
306
}
293
307
294
- protected async runBuildDeploy ( inputs : CommandLineInputs , options : CommandLineOptions ) {
308
+ protected async runBuildDeploy ( inputs : CommandLineInputs , options : CommandLineOptions ) : Promise < void > {
295
309
const conf = await loadConfigXml ( this . integration ) ;
296
310
const metadata = await this . getMetadata ( ) ;
297
311
@@ -300,8 +314,17 @@ Just like with ${input('ionic cordova build')}, you can pass additional options
300
314
}
301
315
302
316
if ( options . build ) {
303
- // TODO: use runner directly
304
- await build ( { config : this . env . config , log : this . env . log , shell : this . env . shell , prompt : this . env . prompt , project : this . project } , inputs , generateOptionsForCordovaBuild ( metadata , inputs , options ) ) ;
317
+ try {
318
+ const runner = await this . project . requireBuildRunner ( ) ;
319
+ const runnerOpts = runner . createOptionsFromCommandLine ( inputs , generateOptionsForCordovaBuild ( metadata , inputs , options ) ) ;
320
+ await runner . run ( runnerOpts ) ;
321
+ } catch ( e ) {
322
+ if ( e instanceof RunnerException ) {
323
+ throw new FatalException ( e . message ) ;
324
+ }
325
+
326
+ throw e ;
327
+ }
305
328
}
306
329
307
330
if ( options [ 'native-run' ] ) {
0 commit comments