@@ -5,7 +5,6 @@ import { Builder, parseString } from "xml2js";
55import { ILogger } from "log4js" ;
66
77export class AndroidPluginBuildService implements IAndroidPluginBuildService {
8-
98 /**
109 * Required for hooks execution to work.
1110 */
@@ -164,113 +163,101 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
164163 */
165164 public async buildAar ( options : IBuildOptions ) : Promise < boolean > {
166165 this . validateOptions ( options ) ;
167-
168- // IDEA: Accept as an additional parameter the Android Support Library version from CLI, pass it on as -PsupportVersion later to the build
169- // IDEA: apply app.gradle here in order to get any and all user-defined variables
170- // IDEA: apply the entire include.gradle here instead of copying over the repositories {} and dependencies {} scopes
171-
172- const shortPluginName = getShortPluginName ( options . pluginName ) ;
173- const newPluginDir = path . join ( options . tempPluginDirPath , shortPluginName ) ;
174- const newPluginMainSrcDir = path . join ( newPluginDir , "src" , "main" ) ;
175- const defaultPackageName = "org.nativescript." + shortPluginName ;
176-
177- // find manifest file
178- //// prepare manifest file content
179166 const manifestFilePath = this . getManifest ( options . platformsAndroidDirPath ) ;
180- let shouldBuildAar = false ;
181-
182- // look for AndroidManifest.xml
183- if ( manifestFilePath ) {
184- shouldBuildAar = true ;
185- }
186-
187- // look for android resources
188167 const androidSourceSetDirectories = this . getAndroidSourceDirectories ( options . platformsAndroidDirPath ) ;
168+ const shouldBuildAar = ! ! manifestFilePath || androidSourceSetDirectories . length > 0 ;
189169
190- if ( androidSourceSetDirectories . length > 0 ) {
191- shouldBuildAar = true ;
192- }
193-
194- // if a manifest OR/AND resource files are present - write files, build plugin
195170 if ( shouldBuildAar ) {
196- let updatedManifestContent ;
197- this . $fs . ensureDirectoryExists ( newPluginMainSrcDir ) ;
198-
199- if ( manifestFilePath ) {
200- let androidManifestContent ;
201- try {
202- androidManifestContent = this . $fs . readText ( manifestFilePath ) ;
203- } catch ( err ) {
204- throw new Error (
205- `Failed to fs.readFileSync the manifest file located at ${ manifestFilePath } `
206- ) ;
207- }
171+ const shortPluginName = getShortPluginName ( options . pluginName ) ;
172+ const pluginTempDir = path . join ( options . tempPluginDirPath , shortPluginName ) ;
173+ const pluginTempMainSrcDir = path . join ( pluginTempDir , "src" , "main" ) ;
174+
175+ await this . updateManifest ( manifestFilePath , pluginTempMainSrcDir , shortPluginName ) ;
176+ this . copySourceSetDirectories ( androidSourceSetDirectories , pluginTempMainSrcDir ) ;
177+ this . setupGradle ( pluginTempDir , options . platformsAndroidDirPath ) ;
178+ await this . buildPlugin ( { pluginDir : pluginTempDir , pluginName : options . pluginName } ) ;
179+ this . copyAar ( shortPluginName , pluginTempDir , options . aarOutputDir ) ;
180+ }
208181
209- updatedManifestContent = await this . updateManifestContent ( androidManifestContent , defaultPackageName ) ;
210- } else {
211- updatedManifestContent = this . createManifestContent ( defaultPackageName ) ;
212- }
182+ return shouldBuildAar ;
183+ }
213184
214- // write the AndroidManifest in the temp-dir/plugin-name/src/main
215- const pathToNewAndroidManifest = path . join ( newPluginMainSrcDir , MANIFEST_FILE_NAME ) ;
185+ private async updateManifest ( manifestFilePath : string , pluginTempMainSrcDir : string , shortPluginName : string ) : Promise < void > {
186+ let updatedManifestContent ;
187+ this . $fs . ensureDirectoryExists ( pluginTempMainSrcDir ) ;
188+ const defaultPackageName = "org.nativescript." + shortPluginName ;
189+ if ( manifestFilePath ) {
190+ let androidManifestContent ;
216191 try {
217- this . $fs . writeFile ( pathToNewAndroidManifest , updatedManifestContent ) ;
218- } catch ( e ) {
219- throw new Error ( `Failed to write the updated AndroidManifest in the new location - ${ pathToNewAndroidManifest } ` ) ;
192+ androidManifestContent = this . $fs . readText ( manifestFilePath ) ;
193+ } catch ( err ) {
194+ throw new Error (
195+ `Failed to fs.readFileSync the manifest file located at ${ manifestFilePath } `
196+ ) ;
220197 }
221198
222- // copy all android sourceset directories to the new temporary plugin dir
223- for ( const dir of androidSourceSetDirectories ) {
224- // get only the last subdirectory of the entire path string. e.g. 'res', 'java', etc.
225- const dirNameParts = dir . split ( path . sep ) ;
226- const dirName = dirNameParts [ dirNameParts . length - 1 ] ;
199+ updatedManifestContent = await this . updateManifestContent ( androidManifestContent , defaultPackageName ) ;
200+ } else {
201+ updatedManifestContent = this . createManifestContent ( defaultPackageName ) ;
202+ }
227203
228- const destination = path . join ( newPluginMainSrcDir , dirName ) ;
229- this . $fs . ensureDirectoryExists ( destination ) ;
204+ const pathToTempAndroidManifest = path . join ( pluginTempMainSrcDir , MANIFEST_FILE_NAME ) ;
205+ try {
206+ this . $fs . writeFile ( pathToTempAndroidManifest , updatedManifestContent ) ;
207+ } catch ( e ) {
208+ throw new Error ( `Failed to write the updated AndroidManifest in the new location - ${ pathToTempAndroidManifest } ` ) ;
209+ }
210+ }
230211
231- this . $fs . copyFile ( path . join ( dir , "*" ) , destination ) ;
232- }
212+ private copySourceSetDirectories ( androidSourceSetDirectories : string [ ] , pluginTempMainSrcDir : string ) : void {
213+ for ( const dir of androidSourceSetDirectories ) {
214+ const dirNameParts = dir . split ( path . sep ) ;
215+ // get only the last subdirectory of the entire path string. e.g. 'res', 'java', etc.
216+ const dirName = dirNameParts [ dirNameParts . length - 1 ] ;
217+ const destination = path . join ( pluginTempMainSrcDir , dirName ) ;
233218
234- // copy the preconfigured gradle android library project template to the temporary android library
235- this . $fs . copyFile ( path . join ( path . resolve ( path . join ( __dirname , AndroidPluginBuildService . ANDROID_PLUGIN_GRADLE_TEMPLATE ) , "*" ) ) , newPluginDir ) ;
219+ this . $fs . ensureDirectoryExists ( destination ) ;
220+ this . $fs . copyFile ( path . join ( dir , "*" ) , destination ) ;
221+ }
222+ }
236223
237- // sometimes the AndroidManifest.xml or certain resources in /res may have a compile dependency to a library referenced in include.gradle. Make sure to compile the plugin with a compile dependency to those libraries
238- const includeGradlePath = path . join ( options . platformsAndroidDirPath , INCLUDE_GRADLE_NAME ) ;
239- if ( this . $fs . exists ( includeGradlePath ) ) {
240- const includeGradleContent = this . $fs . readText ( includeGradlePath ) ;
241- const repositoriesAndDependenciesScopes = this . getIncludeGradleCompileDependenciesScope ( includeGradleContent ) ;
224+ private setupGradle ( pluginTempDir : string , platformsAndroidDirPath : string ) : void {
225+ const gradleTemplatePath = path . resolve ( path . join ( __dirname , AndroidPluginBuildService . ANDROID_PLUGIN_GRADLE_TEMPLATE ) ) ;
226+ const allGradleTemplateFiles = path . join ( gradleTemplatePath , "*" ) ;
242227
243- // dependencies { } object was found - append dependencies scope
244- if ( repositoriesAndDependenciesScopes . length > 0 ) {
245- const buildGradlePath = path . join ( newPluginDir , "build.gradle" ) ;
246- this . $fs . appendFile ( buildGradlePath , "\n" + repositoriesAndDependenciesScopes . join ( "\n" ) ) ;
247- }
248- }
228+ this . $fs . copyFile ( allGradleTemplateFiles , pluginTempDir ) ;
229+ this . addCompileDependencies ( platformsAndroidDirPath , pluginTempDir ) ;
230+ // TODO: replace placeholders in target destination
231+ }
249232
250- // finally build the plugin
251- this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) ;
252- const androidToolsInfo = this . $androidToolsInfo . getToolsInfo ( ) ;
253- await this . buildPlugin ( { pluginDir : newPluginDir , pluginName : options . pluginName , androidToolsInfo } ) ;
254-
255- const finalAarName = `${ shortPluginName } -release.aar` ;
256- const pathToBuiltAar = path . join ( newPluginDir , "build" , "outputs" , "aar" , finalAarName ) ;
257-
258- if ( this . $fs . exists ( pathToBuiltAar ) ) {
259- try {
260- if ( options . aarOutputDir ) {
261- this . $fs . copyFile ( pathToBuiltAar , path . join ( options . aarOutputDir , `${ shortPluginName } .aar` ) ) ;
262- }
263- } catch ( e ) {
264- throw new Error ( `Failed to copy built aar to destination. ${ e . message } ` ) ;
265- }
233+ private addCompileDependencies ( platformsAndroidDirPath : string , pluginTempDir : string ) : void {
234+ const includeGradlePath = path . join ( platformsAndroidDirPath , INCLUDE_GRADLE_NAME ) ;
235+ if ( this . $fs . exists ( includeGradlePath ) ) {
236+ const includeGradleContent = this . $fs . readText ( includeGradlePath ) ;
237+ const repositoriesAndDependenciesScopes = this . getIncludeGradleCompileDependenciesScope ( includeGradleContent ) ;
266238
267- return true ;
268- } else {
269- throw new Error ( `No built aar found at ${ pathToBuiltAar } ` ) ;
239+ if ( repositoriesAndDependenciesScopes . length > 0 ) {
240+ const buildGradlePath = path . join ( pluginTempDir , "build.gradle" ) ;
241+ this . $fs . appendFile ( buildGradlePath , "\n" + repositoriesAndDependenciesScopes . join ( "\n" ) ) ;
270242 }
271243 }
244+ }
272245
273- return false ;
246+ private copyAar ( shortPluginName : string , pluginTempDir : string , aarOutputDir : string ) : void {
247+ const finalAarName = `${ shortPluginName } -release.aar` ;
248+ const pathToBuiltAar = path . join ( pluginTempDir , "build" , "outputs" , "aar" , finalAarName ) ;
249+
250+ if ( this . $fs . exists ( pathToBuiltAar ) ) {
251+ try {
252+ if ( aarOutputDir ) {
253+ this . $fs . copyFile ( pathToBuiltAar , path . join ( aarOutputDir , `${ shortPluginName } .aar` ) ) ;
254+ }
255+ } catch ( e ) {
256+ throw new Error ( `Failed to copy built aar to destination. ${ e . message } ` ) ;
257+ }
258+ } else {
259+ throw new Error ( `No built aar found at ${ pathToBuiltAar } ` ) ;
260+ }
274261 }
275262
276263 /**
@@ -307,6 +294,11 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
307294
308295 @hook ( "buildAndroidPlugin" )
309296 private async buildPlugin ( pluginBuildSettings : IBuildAndroidPluginData ) : Promise < void > {
297+ if ( ! pluginBuildSettings . androidToolsInfo ) {
298+ this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) ;
299+ pluginBuildSettings . androidToolsInfo = this . $androidToolsInfo . getToolsInfo ( ) ;
300+ }
301+
310302 const gradlew = this . $hostInfo . isWindows ? "gradlew.bat" : "./gradlew" ;
311303
312304 const localArgs = [
0 commit comments