@@ -4,9 +4,7 @@ import * as constants from "../constants";
4
4
import * as semver from "semver" ;
5
5
import * as projectServiceBaseLib from "./platform-project-service-base" ;
6
6
import { DeviceAndroidDebugBridge } from "../common/mobile/android/device-android-debug-bridge" ;
7
- import { attachAwaitDetach } from "../common/helpers" ;
8
7
import { Configurations , LiveSyncPaths } from "../common/constants" ;
9
- import { SpawnOptions } from "child_process" ;
10
8
import { performanceLog } from ".././common/decorators" ;
11
9
12
10
export class AndroidProjectService extends projectServiceBaseLib . PlatformProjectServiceBase implements IPlatformProjectService {
@@ -15,23 +13,20 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
15
13
private static ANDROID_PLATFORM_NAME = "android" ;
16
14
private static MIN_RUNTIME_VERSION_WITH_GRADLE = "1.5.0" ;
17
15
18
- private isAndroidStudioTemplate : boolean ;
19
-
20
16
constructor ( private $androidToolsInfo : IAndroidToolsInfo ,
21
- private $childProcess : IChildProcess ,
22
17
private $errors : IErrors ,
23
18
$fs : IFileSystem ,
24
- private $hostInfo : IHostInfo ,
25
19
private $logger : ILogger ,
26
20
$projectDataService : IProjectDataService ,
27
21
private $injector : IInjector ,
28
22
private $devicePlatformsConstants : Mobile . IDevicePlatformsConstants ,
29
23
private $androidPluginBuildService : IAndroidPluginBuildService ,
30
24
private $platformEnvironmentRequirements : IPlatformEnvironmentRequirements ,
31
25
private $androidResourcesMigrationService : IAndroidResourcesMigrationService ,
32
- private $filesHashService : IFilesHashService ) {
26
+ private $filesHashService : IFilesHashService ,
27
+ private $gradleCommandService : IGradleCommandService ,
28
+ private $gradleBuildService : IGradleBuildService ) {
33
29
super ( $fs , $projectDataService ) ;
34
- this . isAndroidStudioTemplate = false ;
35
30
}
36
31
37
32
private _platformData : IPlatformData = null ;
@@ -41,27 +36,10 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
41
36
}
42
37
if ( projectData && projectData . platformsDir ) {
43
38
const projectRoot = path . join ( projectData . platformsDir , AndroidProjectService . ANDROID_PLATFORM_NAME ) ;
44
- if ( this . isAndroidStudioCompatibleTemplate ( projectData ) ) {
45
- this . isAndroidStudioTemplate = true ;
46
- }
47
-
48
- const appDestinationDirectoryArr = [ projectRoot ] ;
49
- if ( this . isAndroidStudioTemplate ) {
50
- appDestinationDirectoryArr . push ( constants . APP_FOLDER_NAME ) ;
51
- }
52
- appDestinationDirectoryArr . push ( constants . SRC_DIR , constants . MAIN_DIR , constants . ASSETS_DIR ) ;
53
39
54
- const configurationsDirectoryArr = [ projectRoot ] ;
55
- if ( this . isAndroidStudioTemplate ) {
56
- configurationsDirectoryArr . push ( constants . APP_FOLDER_NAME ) ;
57
- }
58
- configurationsDirectoryArr . push ( constants . SRC_DIR , constants . MAIN_DIR , constants . MANIFEST_FILE_NAME ) ;
59
-
60
- const deviceBuildOutputArr = [ projectRoot ] ;
61
- if ( this . isAndroidStudioTemplate ) {
62
- deviceBuildOutputArr . push ( constants . APP_FOLDER_NAME ) ;
63
- }
64
- deviceBuildOutputArr . push ( constants . BUILD_DIR , constants . OUTPUTS_DIR , constants . APK_DIR ) ;
40
+ const appDestinationDirectoryArr = [ projectRoot , constants . APP_FOLDER_NAME , constants . SRC_DIR , constants . MAIN_DIR , constants . ASSETS_DIR ] ;
41
+ const configurationsDirectoryArr = [ projectRoot , constants . APP_FOLDER_NAME , constants . SRC_DIR , constants . MAIN_DIR , constants . MANIFEST_FILE_NAME ] ;
42
+ const deviceBuildOutputArr = [ projectRoot , constants . APP_FOLDER_NAME , constants . BUILD_DIR , constants . OUTPUTS_DIR , constants . APK_DIR ] ;
65
43
66
44
const packageName = this . getProjectNameFromId ( projectData ) ;
67
45
@@ -155,30 +133,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
155
133
const targetSdkVersion = androidToolsInfo && androidToolsInfo . targetSdkVersion ;
156
134
this . $logger . trace ( `Using Android SDK '${ targetSdkVersion } '.` ) ;
157
135
158
- this . isAndroidStudioTemplate = this . isAndroidStudioCompatibleTemplate ( projectData , frameworkVersion ) ;
159
- if ( this . isAndroidStudioTemplate ) {
160
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "*" , "-R" ) ;
161
- } else {
162
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "libs" , "-R" ) ;
163
-
164
- if ( config . pathToTemplate ) {
165
- const mainPath = path . join ( this . getPlatformData ( projectData ) . projectRoot , constants . SRC_DIR , constants . MAIN_DIR ) ;
166
- this . $fs . createDirectory ( mainPath ) ;
167
- shell . cp ( "-R" , path . join ( path . resolve ( config . pathToTemplate ) , "*" ) , mainPath ) ;
168
- } else {
169
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , constants . SRC_DIR , "-R" ) ;
170
- }
171
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "build.gradle settings.gradle build-tools" , "-Rf" ) ;
172
-
173
- try {
174
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "gradle.properties" , "-Rf" ) ;
175
- } catch ( e ) {
176
- this . $logger . warn ( `\n${ e } \nIt's possible, the final .apk file will contain all architectures instead of the ones described in the abiFilters!\nYou can fix this by using the latest android platform.` ) ;
177
- }
178
-
179
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "gradle" , "-R" ) ;
180
- this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "gradlew gradlew.bat" , "-f" ) ;
181
- }
136
+ this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "*" , "-R" ) ;
182
137
183
138
this . cleanResValues ( targetSdkVersion , projectData ) ;
184
139
}
@@ -277,76 +232,13 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
277
232
278
233
@performanceLog ( )
279
234
public async buildProject ( projectRoot : string , projectData : IProjectData , buildConfig : IBuildConfig ) : Promise < void > {
280
- let task ;
281
- const gradleArgs = this . getGradleBuildOptions ( buildConfig , projectData ) ;
282
- const baseTask = buildConfig . androidBundle ? "bundle" : "assemble" ;
283
235
const platformData = this . getPlatformData ( projectData ) ;
284
- const outputPath = buildConfig . androidBundle ? platformData . bundleBuildOutputPath : platformData . getBuildOutputPath ( buildConfig ) ;
285
- if ( this . $logger . getLevel ( ) === "TRACE" ) {
286
- gradleArgs . unshift ( "--stacktrace" ) ;
287
- gradleArgs . unshift ( "--debug" ) ;
288
- }
289
- if ( buildConfig . release ) {
290
- task = `${ baseTask } Release` ;
291
- } else {
292
- task = `${ baseTask } Debug` ;
293
- }
294
-
295
- gradleArgs . unshift ( task ) ;
296
-
297
- const handler = ( data : any ) => {
298
- this . emit ( constants . BUILD_OUTPUT_EVENT_NAME , data ) ;
299
- } ;
300
-
301
- await attachAwaitDetach ( constants . BUILD_OUTPUT_EVENT_NAME ,
302
- this . $childProcess ,
303
- handler ,
304
- this . executeCommand ( {
305
- projectRoot : this . getPlatformData ( projectData ) . projectRoot ,
306
- gradleArgs,
307
- childProcessOpts : { stdio : buildConfig . buildOutputStdio || "inherit" } ,
308
- spawnFromEventOptions : { emitOptions : { eventName : constants . BUILD_OUTPUT_EVENT_NAME } , throwError : true } ,
309
- message : "Gradle build..."
310
- } )
311
- ) ;
236
+ await this . $gradleBuildService . buildProject ( platformData . projectRoot , buildConfig ) ;
312
237
238
+ const outputPath = buildConfig . androidBundle ? platformData . bundleBuildOutputPath : platformData . getBuildOutputPath ( buildConfig ) ;
313
239
await this . $filesHashService . saveHashesForProject ( this . _platformData , outputPath ) ;
314
240
}
315
241
316
- private getGradleBuildOptions ( settings : IAndroidBuildOptionsSettings , projectData : IProjectData ) : Array < string > {
317
- const configurationFilePath = this . getPlatformData ( projectData ) . configurationFilePath ;
318
-
319
- const buildOptions : Array < string > = this . getBuildOptions ( configurationFilePath ) ;
320
-
321
- if ( settings . release ) {
322
- buildOptions . push ( "-Prelease" ) ;
323
- buildOptions . push ( `-PksPath=${ path . resolve ( settings . keyStorePath ) } ` ) ;
324
- buildOptions . push ( `-Palias=${ settings . keyStoreAlias } ` ) ;
325
- buildOptions . push ( `-Ppassword=${ settings . keyStoreAliasPassword } ` ) ;
326
- buildOptions . push ( `-PksPassword=${ settings . keyStorePassword } ` ) ;
327
- }
328
-
329
- return buildOptions ;
330
- }
331
-
332
- private getBuildOptions ( configurationFilePath ?: string ) : Array < string > {
333
- this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) ;
334
-
335
- const androidToolsInfo = this . $androidToolsInfo . getToolsInfo ( ) ;
336
- const compileSdk = androidToolsInfo . compileSdkVersion ;
337
- const targetSdk = this . getTargetFromAndroidManifest ( configurationFilePath ) || compileSdk ;
338
- const buildToolsVersion = androidToolsInfo . buildToolsVersion ;
339
- const generateTypings = androidToolsInfo . generateTypings ;
340
- const buildOptions = [
341
- `-PcompileSdk=android-${ compileSdk } ` ,
342
- `-PtargetSdk=${ targetSdk } ` ,
343
- `-PbuildToolsVersion=${ buildToolsVersion } ` ,
344
- `-PgenerateTypings=${ generateTypings } `
345
- ] ;
346
-
347
- return buildOptions ;
348
- }
349
-
350
242
public async buildForDeploy ( projectRoot : string , projectData : IProjectData , buildConfig ?: IBuildConfig ) : Promise < void > {
351
243
return this . buildProject ( projectRoot , projectData , buildConfig ) ;
352
244
}
@@ -456,25 +348,18 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
456
348
return nativescript && ( nativescript . android || ( nativescript . platforms && nativescript . platforms . android ) ) ;
457
349
}
458
350
459
- public stopServices ( projectRoot : string ) : Promise < ISpawnResult > {
460
- return this . executeCommand ( {
461
- projectRoot,
462
- gradleArgs : [ "--stop" , "--quiet" ] ,
463
- childProcessOpts : { stdio : "pipe" } ,
464
- message : "Gradle stop services..."
351
+ public async stopServices ( platformData : IPlatformData ) : Promise < ISpawnResult > {
352
+ const result = await this . $gradleCommandService . executeCommand ( [ "--stop" , "--quiet" ] , {
353
+ cwd : platformData . projectRoot ,
354
+ message : "Gradle stop services..." ,
355
+ stdio : "pipe"
465
356
} ) ;
357
+
358
+ return result ;
466
359
}
467
360
468
361
public async cleanProject ( projectRoot : string , projectData : IProjectData ) : Promise < void > {
469
- if ( this . $androidToolsInfo . getToolsInfo ( ) . androidHomeEnvVar ) {
470
- const gradleArgs = this . getGradleBuildOptions ( { release : false } , projectData ) ;
471
- gradleArgs . unshift ( "clean" ) ;
472
- await this . executeCommand ( {
473
- projectRoot,
474
- gradleArgs,
475
- message : "Gradle clean..."
476
- } ) ;
477
- }
362
+ await this . $gradleBuildService . cleanProject ( projectRoot , { release : false } ) ;
478
363
}
479
364
480
365
public async cleanDeviceTempFolder ( deviceIdentifier : string , projectData : IProjectData ) : Promise < void > {
@@ -494,10 +379,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
494
379
shell . cp ( cpArg , paths , projectRoot ) ;
495
380
}
496
381
497
- private async spawn ( command : string , args : string [ ] , opts ?: any , spawnOpts ?: ISpawnFromEventOptions ) : Promise < ISpawnResult > {
498
- return this . $childProcess . spawnFromEvent ( command , args , "close" , opts || { stdio : "inherit" } , spawnOpts ) ;
499
- }
500
-
501
382
private validatePackageName ( packageName : string ) : void {
502
383
//Make the package conform to Java package types
503
384
//Enforce underscore limitation
@@ -522,81 +403,14 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
522
403
}
523
404
}
524
405
525
- private getTargetFromAndroidManifest ( configurationFilePath : string ) : string {
526
- let versionInManifest : string ;
527
- if ( this . $fs . exists ( configurationFilePath ) ) {
528
- const targetFromAndroidManifest : string = this . $fs . readText ( configurationFilePath ) ;
529
- if ( targetFromAndroidManifest ) {
530
- const match = targetFromAndroidManifest . match ( / .* ?a n d r o i d : t a r g e t S d k V e r s i o n = \" ( .* ?) \" / ) ;
531
- if ( match && match [ 1 ] ) {
532
- versionInManifest = match [ 1 ] ;
533
- }
534
- }
535
- }
536
-
537
- return versionInManifest ;
538
- }
539
-
540
- private async executeCommand ( opts : { projectRoot : string , gradleArgs : any , childProcessOpts ?: SpawnOptions , spawnFromEventOptions ?: ISpawnFromEventOptions , message : string } ) : Promise < ISpawnResult > {
541
- if ( this . $androidToolsInfo . getToolsInfo ( ) . androidHomeEnvVar ) {
542
- const { projectRoot, gradleArgs, message, spawnFromEventOptions } = opts ;
543
- const gradlew = this . $hostInfo . isWindows ? "gradlew.bat" : "./gradlew" ;
544
-
545
- if ( this . $logger . getLevel ( ) === "INFO" ) {
546
- gradleArgs . push ( "--quiet" ) ;
547
- }
548
-
549
- this . $logger . info ( message ) ;
550
-
551
- const childProcessOpts = opts . childProcessOpts || { } ;
552
- childProcessOpts . cwd = childProcessOpts . cwd || projectRoot ;
553
- childProcessOpts . stdio = childProcessOpts . stdio || "inherit" ;
554
- let commandResult ;
555
- try {
556
- commandResult = await this . spawn ( gradlew ,
557
- gradleArgs ,
558
- childProcessOpts ,
559
- spawnFromEventOptions ) ;
560
- } catch ( err ) {
561
- this . $errors . failWithoutHelp ( err . message ) ;
562
- }
563
-
564
- return commandResult ;
565
- }
566
- }
567
-
568
- private isAndroidStudioCompatibleTemplate ( projectData : IProjectData , frameworkVersion ?: string ) : boolean {
569
- const currentPlatformData : IDictionary < any > = this . $projectDataService . getNSValue ( projectData . projectDir , constants . TNS_ANDROID_RUNTIME_NAME ) ;
570
- const platformVersion = ( currentPlatformData && currentPlatformData [ constants . VERSION_STRING ] ) || frameworkVersion ;
571
-
572
- if ( ! platformVersion ) {
573
- return true ;
574
- }
575
-
576
- if ( platformVersion === constants . PackageVersion . NEXT || platformVersion === constants . PackageVersion . LATEST || platformVersion === constants . PackageVersion . RC ) {
577
- return true ;
578
- }
579
-
580
- const androidStudioCompatibleTemplate = "3.4.0" ;
581
- const normalizedPlatformVersion = `${ semver . major ( platformVersion ) } .${ semver . minor ( platformVersion ) } .0` ;
582
-
583
- return semver . gte ( normalizedPlatformVersion , androidStudioCompatibleTemplate ) ;
584
- }
585
-
586
406
private getLegacyAppResourcesDestinationDirPath ( projectData : IProjectData ) : string {
587
- const resourcePath : string [ ] = [ constants . SRC_DIR , constants . MAIN_DIR , constants . RESOURCES_DIR ] ;
588
- if ( this . isAndroidStudioTemplate ) {
589
- resourcePath . unshift ( constants . APP_FOLDER_NAME ) ;
590
- }
407
+ const resourcePath : string [ ] = [ constants . APP_FOLDER_NAME , constants . SRC_DIR , constants . MAIN_DIR , constants . RESOURCES_DIR ] ;
591
408
592
409
return path . join ( this . getPlatformData ( projectData ) . projectRoot , ...resourcePath ) ;
593
410
}
594
411
595
412
private getUpdatedAppResourcesDestinationDirPath ( projectData : IProjectData ) : string {
596
- const resourcePath : string [ ] = [ constants . SRC_DIR ] ;
597
- if ( this . isAndroidStudioTemplate ) {
598
- resourcePath . unshift ( constants . APP_FOLDER_NAME ) ;
599
- }
413
+ const resourcePath : string [ ] = [ constants . APP_FOLDER_NAME , constants . SRC_DIR ] ;
600
414
601
415
return path . join ( this . getPlatformData ( projectData ) . projectRoot , ...resourcePath ) ;
602
416
}
0 commit comments