11import * as path from "path" ;
2- import { MANIFEST_FILE_NAME , INCLUDE_GRADLE_NAME , ASSETS_DIR , RESOURCES_DIR , TNS_ANDROID_RUNTIME_NAME , AndroidBuildDefaults } from "../constants" ;
2+ import { MANIFEST_FILE_NAME , INCLUDE_GRADLE_NAME , ASSETS_DIR , RESOURCES_DIR , TNS_ANDROID_RUNTIME_NAME , AndroidBuildDefaults , PLUGIN_BUILD_DATA_FILENAME } from "../constants" ;
33import { getShortPluginName , hook } from "../common/helpers" ;
44import { Builder , parseString } from "xml2js" ;
55import { ILogger } from "log4js" ;
@@ -25,7 +25,8 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
2525 private $npm : INodePackageManager ,
2626 private $projectDataService : IProjectDataService ,
2727 private $devicePlatformsConstants : Mobile . IDevicePlatformsConstants ,
28- private $errors : IErrors ) { }
28+ private $errors : IErrors ,
29+ private $filesHashService : IFilesHashService ) { }
2930
3031 private static MANIFEST_ROOT = {
3132 $ : {
@@ -172,23 +173,80 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
172173 this . validateOptions ( options ) ;
173174 const manifestFilePath = this . getManifest ( options . platformsAndroidDirPath ) ;
174175 const androidSourceDirectories = this . getAndroidSourceDirectories ( options . platformsAndroidDirPath ) ;
175- const shouldBuildAar = ! ! manifestFilePath || androidSourceDirectories . length > 0 ;
176+ const shortPluginName = getShortPluginName ( options . pluginName ) ;
177+ const pluginTempDir = path . join ( options . tempPluginDirPath , shortPluginName ) ;
178+ const pluginSourceFileHashesInfo = await this . getSourceFilesHashes ( options . platformsAndroidDirPath , shortPluginName ) ;
179+
180+ const shouldBuildAar = await this . shouldBuildAar ( {
181+ manifestFilePath,
182+ androidSourceDirectories,
183+ pluginTempDir,
184+ pluginSourceDir : options . platformsAndroidDirPath ,
185+ shortPluginName,
186+ fileHashesInfo : pluginSourceFileHashesInfo
187+ } ) ;
176188
177189 if ( shouldBuildAar ) {
178- const shortPluginName = getShortPluginName ( options . pluginName ) ;
179- const pluginTempDir = path . join ( options . tempPluginDirPath , shortPluginName ) ;
180- const pluginTempMainSrcDir = path . join ( pluginTempDir , "src" , "main" ) ;
190+ this . cleanPluginDir ( pluginTempDir ) ;
181191
192+ const pluginTempMainSrcDir = path . join ( pluginTempDir , "src" , "main" ) ;
182193 await this . updateManifest ( manifestFilePath , pluginTempMainSrcDir , shortPluginName ) ;
183194 this . copySourceSetDirectories ( androidSourceDirectories , pluginTempMainSrcDir ) ;
184195 await this . setupGradle ( pluginTempDir , options . platformsAndroidDirPath , options . projectDir ) ;
185196 await this . buildPlugin ( { pluginDir : pluginTempDir , pluginName : options . pluginName } ) ;
186197 this . copyAar ( shortPluginName , pluginTempDir , options . aarOutputDir ) ;
198+ this . writePluginHashInfo ( pluginSourceFileHashesInfo , pluginTempDir ) ;
187199 }
188200
189201 return shouldBuildAar ;
190202 }
191203
204+ private cleanPluginDir ( pluginTempDir : string ) : void {
205+ // In case plugin was already built in the current process, we need to clean the old sources as they may break the new build.
206+ this . $fs . deleteDirectory ( pluginTempDir ) ;
207+ this . $fs . ensureDirectoryExists ( pluginTempDir ) ;
208+ }
209+
210+ private getSourceFilesHashes ( pluginTempPlatformsAndroidDir : string , shortPluginName : string ) : Promise < IStringDictionary > {
211+ const pathToAar = path . join ( pluginTempPlatformsAndroidDir , `${ shortPluginName } .aar` ) ;
212+ const pluginNativeDataFiles = this . $fs . enumerateFilesInDirectorySync ( pluginTempPlatformsAndroidDir , ( file : string , stat : IFsStats ) => file !== pathToAar ) ;
213+ return this . $filesHashService . generateHashes ( pluginNativeDataFiles ) ;
214+ }
215+
216+ private writePluginHashInfo ( fileHashesInfo : IStringDictionary , pluginTempDir : string ) : void {
217+ const buildDataFile = this . getPathToPluginBuildDataFile ( pluginTempDir ) ;
218+ this . $fs . writeJson ( buildDataFile , fileHashesInfo ) ;
219+ }
220+
221+ private async shouldBuildAar ( opts : {
222+ manifestFilePath : string ,
223+ androidSourceDirectories : string [ ] ,
224+ pluginTempDir : string ,
225+ pluginSourceDir : string ,
226+ shortPluginName : string ,
227+ fileHashesInfo : IStringDictionary
228+ } ) : Promise < boolean > {
229+
230+ let shouldBuildAar = ! ! opts . manifestFilePath || ! ! opts . androidSourceDirectories . length ;
231+
232+ if ( shouldBuildAar &&
233+ this . $fs . exists ( opts . pluginTempDir ) &&
234+ this . $fs . exists ( path . join ( opts . pluginSourceDir , `${ opts . shortPluginName } .aar` ) ) ) {
235+
236+ const buildDataFile = this . getPathToPluginBuildDataFile ( opts . pluginTempDir ) ;
237+ if ( this . $fs . exists ( buildDataFile ) ) {
238+ const oldHashes = this . $fs . readJson ( buildDataFile ) ;
239+ shouldBuildAar = this . $filesHashService . hasChangesInShasums ( oldHashes , opts . fileHashesInfo ) ;
240+ }
241+ }
242+
243+ return shouldBuildAar ;
244+ }
245+
246+ private getPathToPluginBuildDataFile ( pluginDir : string ) : string {
247+ return path . join ( pluginDir , PLUGIN_BUILD_DATA_FILENAME ) ;
248+ }
249+
192250 private async updateManifest ( manifestFilePath : string , pluginTempMainSrcDir : string , shortPluginName : string ) : Promise < void > {
193251 let updatedManifestContent ;
194252 this . $fs . ensureDirectoryExists ( pluginTempMainSrcDir ) ;
@@ -256,7 +314,7 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
256314 return runtimeGradleVersions || { } ;
257315 }
258316
259- private getGradleVersions ( packageData : { gradle : { version : string , android : string } } ) : IRuntimeGradleVersions {
317+ private getGradleVersions ( packageData : { gradle : { version : string , android : string } } ) : IRuntimeGradleVersions {
260318 const packageJsonGradle = packageData && packageData . gradle ;
261319 let runtimeVersions : IRuntimeGradleVersions = null ;
262320 if ( packageJsonGradle && ( packageJsonGradle . version || packageJsonGradle . android ) ) {
0 commit comments