@@ -4,10 +4,11 @@ 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 { EOL } from "os" ;
8
+ import { attachAwaitDetach , isBuildFromCLI } from "../common/helpers" ;
9
9
import { Configurations } from "../common/constants" ;
10
10
import { SpawnOptions } from "child_process" ;
11
+ import { buildAar , migrateIncludeGradle , BuildAarOptions } from "plugin-migrator" ;
11
12
12
13
export class AndroidProjectService extends projectServiceBaseLib . PlatformProjectServiceBase implements IPlatformProjectService {
13
14
private static VALUES_DIRNAME = "values" ;
@@ -413,14 +414,90 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
413
414
}
414
415
415
416
public async preparePluginNativeCode ( pluginData : IPluginData , projectData : IProjectData ) : Promise < void > {
416
- if ( ! this . shouldUseNewRuntimeGradleRoutine ( projectData ) ) {
417
+ if ( ! this . runtimeVersionIsGreaterThanOrEquals ( projectData , "3.3.0" ) ) {
417
418
const pluginPlatformsFolderPath = this . getPluginPlatformsFolderPath ( pluginData , AndroidProjectService . ANDROID_PLATFORM_NAME ) ;
418
419
await this . processResourcesFromPlugin ( pluginData , pluginPlatformsFolderPath , projectData ) ;
420
+ } else if ( this . runtimeVersionIsGreaterThanOrEquals ( projectData , "4.0.0" ) ) {
421
+ // build Android plugins which contain AndroidManifest.xml and/or resources
422
+ const pluginPlatformsFolderPath = this . getPluginPlatformsFolderPath ( pluginData , AndroidProjectService . ANDROID_PLATFORM_NAME ) ;
423
+ if ( this . $fs . exists ( pluginPlatformsFolderPath ) ) {
424
+ this . prebuildNativePlugin ( pluginData . name , pluginPlatformsFolderPath , pluginPlatformsFolderPath , path . join ( projectData . platformsDir , "tempPlugin" ) ) ;
425
+ }
419
426
}
420
427
421
428
// Do nothing, the Android Gradle script will configure itself based on the input dependencies.json
422
429
}
423
430
431
+ public async checkIfPluginsNeedBuild ( projectData : IProjectData ) : Promise < Array < any > > {
432
+ const detectedPlugins : Array < any > = [ ] ;
433
+
434
+ const platformsAndroid = path . join ( constants . PLATFORMS_DIR_NAME , "android" ) ;
435
+ const pathToPlatformsAndroid = path . join ( projectData . projectDir , platformsAndroid ) ;
436
+ const dependenciesJson = await this . $fs . readJson ( path . join ( pathToPlatformsAndroid , constants . DEPENDENCIES_JSON_NAME ) ) ;
437
+ const productionDependencies = dependenciesJson . map ( ( item : any ) => {
438
+ return path . resolve ( pathToPlatformsAndroid , item . directory ) ;
439
+ } ) ;
440
+
441
+ for ( const dependencyKey in productionDependencies ) {
442
+ const dependency = productionDependencies [ dependencyKey ] ;
443
+ const jsonContent = this . $fs . readJson ( path . join ( dependency , constants . PACKAGE_JSON_FILE_NAME ) ) ;
444
+ const isPlugin = ! ! jsonContent . nativescript ;
445
+ const pluginName = jsonContent . name ;
446
+ if ( isPlugin ) {
447
+ const platformsAndroidDirPath = path . join ( dependency , platformsAndroid ) ;
448
+ if ( this . $fs . exists ( platformsAndroidDirPath ) ) {
449
+ let hasGeneratedAar = false ;
450
+ let generatedAarPath = "" ;
451
+ const nativeFiles = this . $fs . enumerateFilesInDirectorySync ( platformsAndroidDirPath ) . filter ( ( item ) => {
452
+ if ( isBuildFromCLI ( item ) ) {
453
+ generatedAarPath = item ;
454
+ hasGeneratedAar = true ;
455
+ }
456
+ return this . isAllowedFile ( item ) ;
457
+ } ) ;
458
+
459
+ if ( hasGeneratedAar ) {
460
+ const aarStat = this . $fs . getFsStats ( generatedAarPath ) ;
461
+ nativeFiles . forEach ( ( item ) => {
462
+ const currentItemStat = this . $fs . getFsStats ( item ) ;
463
+ if ( currentItemStat . mtime > aarStat . mtime ) {
464
+ detectedPlugins . push ( {
465
+ platformsAndroidDirPath : platformsAndroidDirPath ,
466
+ pluginName : pluginName
467
+ } ) ;
468
+ }
469
+ } ) ;
470
+ } else if ( nativeFiles . length > 0 ) {
471
+ detectedPlugins . push ( {
472
+ platformsAndroidDirPath : platformsAndroidDirPath ,
473
+ pluginName : pluginName
474
+ } ) ;
475
+ }
476
+ }
477
+ }
478
+ }
479
+ return detectedPlugins ;
480
+ }
481
+
482
+ private isAllowedFile ( item : string ) {
483
+ return item . endsWith ( constants . MANIFEST_FILE_NAME ) || item . endsWith ( constants . RESOURCES_DIR ) ;
484
+ }
485
+
486
+ public async prebuildNativePlugin ( pluginName : string , platformsAndroidDirPath : string , aarOutputDir : string , tmpBuildDir : string ) : Promise < void > {
487
+ const options : BuildAarOptions = {
488
+ pluginName : pluginName ,
489
+ platformsAndroidDirPath : platformsAndroidDirPath ,
490
+ aarOutputDir : aarOutputDir ,
491
+ tempPluginDirPath : tmpBuildDir
492
+ } ;
493
+
494
+ if ( await buildAar ( options ) ) {
495
+ this . $logger . info ( `Built aar for ${ pluginName } ` ) ;
496
+ }
497
+
498
+ migrateIncludeGradle ( options ) ;
499
+ }
500
+
424
501
public async processConfigurationFilesFromAppResources ( ) : Promise < void > {
425
502
return ;
426
503
}
@@ -458,9 +535,9 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
458
535
public async removePluginNativeCode ( pluginData : IPluginData , projectData : IProjectData ) : Promise < void > {
459
536
try {
460
537
// check whether the dependency that's being removed has native code
461
- // TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
538
+ // TODO: Remove prior to the 4.1 CLI release @Pip3r4o @PanayotCankov
462
539
// the updated gradle script will take care of cleaning the prepared android plugins
463
- if ( ! this . shouldUseNewRuntimeGradleRoutine ( projectData ) ) {
540
+ if ( ! this . runtimeVersionIsGreaterThanOrEquals ( projectData , "3.3.0" ) ) {
464
541
const pluginConfigDir = path . join ( this . getPlatformData ( projectData ) . projectRoot , "configurations" , pluginData . name ) ;
465
542
if ( this . $fs . exists ( pluginConfigDir ) ) {
466
543
await this . cleanProject ( this . getPlatformData ( projectData ) . projectRoot , projectData ) ;
@@ -480,14 +557,14 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
480
557
}
481
558
482
559
public async beforePrepareAllPlugins ( projectData : IProjectData , dependencies ?: IDependencyData [ ] ) : Promise < void > {
483
- const shouldUseNewRoutine = this . shouldUseNewRuntimeGradleRoutine ( projectData ) ;
560
+ const shouldUseNewRoutine = this . runtimeVersionIsGreaterThanOrEquals ( projectData , "3.3.0" ) ;
484
561
485
562
if ( dependencies ) {
486
563
dependencies = this . filterUniqueDependencies ( dependencies ) ;
487
564
if ( shouldUseNewRoutine ) {
488
565
this . provideDependenciesJson ( projectData , dependencies ) ;
489
566
} else {
490
- // TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
567
+ // TODO: Remove prior to the 4.1 CLI release @Pip3r4o @PanayotCankov
491
568
492
569
const platformDir = path . join ( projectData . platformsDir , AndroidProjectService . ANDROID_PLATFORM_NAME ) ;
493
570
const buildDir = path . join ( platformDir , "build-tools" ) ;
@@ -524,7 +601,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
524
601
525
602
private provideDependenciesJson ( projectData : IProjectData , dependencies : IDependencyData [ ] ) : void {
526
603
const platformDir = path . join ( projectData . platformsDir , AndroidProjectService . ANDROID_PLATFORM_NAME ) ;
527
- const dependenciesJsonPath = path . join ( platformDir , "dependencies.json" ) ;
604
+ const dependenciesJsonPath = path . join ( platformDir , constants . DEPENDENCIES_JSON_NAME ) ;
528
605
const nativeDependencies = dependencies
529
606
. filter ( AndroidProjectService . isNativeAndroidDependency )
530
607
. map ( ( { name, directory } ) => ( { name, directory : path . relative ( platformDir , directory ) } ) ) ;
@@ -642,15 +719,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
642
719
}
643
720
}
644
721
645
- // TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
646
- private shouldUseNewRuntimeGradleRoutine ( projectData : IProjectData ) : boolean {
647
- const platformVersion = this . getCurrentPlatformVersion ( this . getPlatformData ( projectData ) , projectData ) ;
648
- const newRuntimeGradleRoutineVersion = "3.3.0" ;
649
-
650
- const normalizedPlatformVersion = `${ semver . major ( platformVersion ) } .${ semver . minor ( platformVersion ) } .0` ;
651
- return semver . gte ( normalizedPlatformVersion , newRuntimeGradleRoutineVersion ) ;
652
- }
653
-
654
722
private isAndroidStudioCompatibleTemplate ( projectData : IProjectData ) : boolean {
655
723
const currentPlatformData : IDictionary < any > = this . $projectDataService . getNSValue ( projectData . projectDir , constants . TNS_ANDROID_RUNTIME_NAME ) ;
656
724
let platformVersion = currentPlatformData && currentPlatformData [ constants . VERSION_STRING ] ;
@@ -676,6 +744,17 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
676
744
677
745
return semver . gte ( normalizedPlatformVersion , androidStudioCompatibleTemplate ) ;
678
746
}
747
+
748
+ private runtimeVersionIsGreaterThanOrEquals ( projectData : IProjectData , versionString : string ) : boolean {
749
+ const platformVersion = this . getCurrentPlatformVersion ( this . getPlatformData ( projectData ) , projectData ) ;
750
+
751
+ if ( platformVersion === constants . PackageVersion . NEXT ) {
752
+ return true ;
753
+ }
754
+
755
+ const normalizedPlatformVersion = `${ semver . major ( platformVersion ) } .${ semver . minor ( platformVersion ) } .0` ;
756
+ return semver . gte ( normalizedPlatformVersion , versionString ) ;
757
+ }
679
758
}
680
759
681
760
$injector . register ( "androidProjectService" , AndroidProjectService ) ;
0 commit comments