From e1212e9fccd79f5c302a8380157288df356081da Mon Sep 17 00:00:00 2001 From: Abdullah Al-Faqeir Date: Thu, 19 Sep 2024 22:24:13 +0300 Subject: [PATCH] feat(android): be able to add plugins to build.gradle (#14019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(android): added classpathes to manifest feat(android): plugins classpathes to manifest feat(android): custom root.build.gradle for modules * Update root.build.gradle Co-authored-by: Hans Knöchel * feat(android): added default root.build.gradle file * Update _buildModule.js check if this.manifest.plugins is there before splitting * fix: fix typos * fix: fix some more typos * fix: guard non-existing classpaths * fix(android): fix generating build.gradle files * fix(android): added examples in the manifest file on how to use android classpaths and plugins --------- Co-authored-by: Hans Knöchel Co-authored-by: Hans Knöchel --- android/cli/commands/_build.js | 10 ++++++---- android/cli/commands/_buildModule.js | 11 +++++++---- android/templates/build/root.build.gradle | 10 ++++++++++ .../module/default/template/android/manifest.ejs | 9 +++++++++ .../module/default/template/android/root.build.gradle | 4 ++++ android/templates/module/generated/build.gradle | 3 +++ build/lib/test/test.js | 2 +- .../TitaniumKit/TitaniumKit/Sources/API/KrollModule.h | 2 +- 8 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 android/templates/module/default/template/android/root.build.gradle diff --git a/android/cli/commands/_build.js b/android/cli/commands/_build.js index 96411a1dd72..234b92aecb9 100644 --- a/android/cli/commands/_build.js +++ b/android/cli/commands/_build.js @@ -2174,10 +2174,12 @@ AndroidBuilder.prototype.generateRootProjectFiles = async function generateRootP // Create a "local.properties" file providing a path to the Android SDK directory. await gradlew.writeLocalPropertiesFile(this.androidInfo.sdk.path); - // Copy our root "build.gradle" template script to the root build directory. - await fs.copyFile( - path.join(this.templatesDir, 'root.build.gradle'), - path.join(this.buildDir, 'build.gradle')); + // Generate root "build.gradle" template script to the root build directory. + let buildGradleContent = await fs.readFile(path.join(this.templatesDir, 'root.build.gradle')); + buildGradleContent = ejs.render(buildGradleContent.toString(), { + classpaths: [], + }); + await fs.writeFile(path.join(this.buildDir, 'build.gradle'), buildGradleContent); // Copy our Titanium template's gradle constants file. // This provides the Google library versions we use and defines our custom "AndroidManifest.xml" placeholders. diff --git a/android/cli/commands/_buildModule.js b/android/cli/commands/_buildModule.js index 3405f072cc1..144c65b7c4a 100644 --- a/android/cli/commands/_buildModule.js +++ b/android/cli/commands/_buildModule.js @@ -512,11 +512,13 @@ AndroidModuleBuilder.prototype.generateRootProjectFiles = async function generat // Create a "local.properties" file providing a path to the Android SDK directory. await gradlew.writeLocalPropertiesFile(this.androidInfo.sdk.path); - // Copy our root "build.gradle" template script to the root build directory. + // Generate root "build.gradle" template script to the root build directory. const templatesDir = path.join(this.platformPath, 'templates', 'build'); - await fs.copyFile( - path.join(templatesDir, 'root.build.gradle'), - path.join(this.buildDir, 'build.gradle')); + let buildGradleContent = await fs.readFile(path.join(templatesDir, 'root.build.gradle')); + buildGradleContent = ejs.render(buildGradleContent.toString(), { + classpaths: (this.manifest.classpaths?.split(',') ?? []).filter(classpath => classpath !== ''), + }); + await fs.writeFile(path.join(this.buildDir, 'build.gradle'), buildGradleContent); // Copy our Titanium template's gradle constants file. // This provides the Google library versions we use and defines our custom "AndroidManifest.xml" placeholders. @@ -562,6 +564,7 @@ AndroidModuleBuilder.prototype.generateModuleProject = async function generateMo let buildGradleContent = await fs.readFile(path.join(this.moduleTemplateDir, 'build.gradle')); buildGradleContent = ejs.render(buildGradleContent.toString(), { compileSdkVersion: this.compileSdkVersion, + plugins: (this.manifest.plugins?.split(',') ?? []).filter(plugin => plugin !== ''), krollAptJarPath: path.join(this.platformPath, 'kroll-apt.jar'), minSdkVersion: this.minSupportedApiLevel, moduleAuthor: this.manifest.author, diff --git a/android/templates/build/root.build.gradle b/android/templates/build/root.build.gradle index d400cc80468..9ed2fe1d5c5 100644 --- a/android/templates/build/root.build.gradle +++ b/android/templates/build/root.build.gradle @@ -9,9 +9,19 @@ buildscript { classpath 'com.android.tools.build:gradle:8.3.1' classpath 'com.google.gms:google-services:4.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + <% for (let i = 0; i < classpaths.length; i++) {%> + classpath '<%= classpaths[i] %>' + <% } %> } } +// Load the module developer's optional "root.build.gradle" file from "/android" directory. +// This gradle file is expected to provide the module's "dependencies". +def moduleRootBuildGradlePath = "${projectDir}/../root.build.gradle" +if (file(moduleRootBuildGradlePath).exists()) { + apply from: moduleRootBuildGradlePath +} + allprojects { repositories { google() diff --git a/android/templates/module/default/template/android/manifest.ejs b/android/templates/module/default/template/android/manifest.ejs index 0afbaac181a..b198ad393bc 100644 --- a/android/templates/module/default/template/android/manifest.ejs +++ b/android/templates/module/default/template/android/manifest.ejs @@ -15,4 +15,13 @@ name: <%- moduleName %> moduleid: <%- moduleId %> guid: <%- guid %> platform: <%- platform %> +# +# Classpaths and plugins are used for android packages that requires them +# to use them you have to add your classpaths and plugins comma separated +# Ex: +# classpaths: classpath1,classpath2 +# plugins: plugin1,plugin2 +# +classpaths: +plugins: minsdk: <%- tisdkVersion %> diff --git a/android/templates/module/default/template/android/root.build.gradle b/android/templates/module/default/template/android/root.build.gradle new file mode 100644 index 00000000000..fa2361da412 --- /dev/null +++ b/android/templates/module/default/template/android/root.build.gradle @@ -0,0 +1,4 @@ + +dependencies { + // Add the module's library root project dependencies here. +} diff --git a/android/templates/module/generated/build.gradle b/android/templates/module/generated/build.gradle index 9a54bd32738..648bedebf4a 100644 --- a/android/templates/module/generated/build.gradle +++ b/android/templates/module/generated/build.gradle @@ -3,6 +3,9 @@ apply plugin: 'com.android.library' apply plugin: 'maven-publish' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' +<% for(var i=0; i +apply plugin: '<%= plugins[i] %>' +<% } %> repositories { maven { diff --git a/build/lib/test/test.js b/build/lib/test/test.js index beb51094541..81392c1f4ef 100644 --- a/build/lib/test/test.js +++ b/build/lib/test/test.js @@ -315,7 +315,7 @@ async function addTiAppProperties() { } else if (line.indexOf('') >= 0) { content.pop(); content.push('\t\tfalse'); - // Grab contents of modules/modules.xml to inject as moduel listing for tiapp.xml + // Grab contents of modules/modules.xml to inject as module listing for tiapp.xml // This allows PR to override } else if (line.indexOf('') >= 0) { // remove open tag diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/KrollModule.h b/iphone/TitaniumKit/TitaniumKit/Sources/API/KrollModule.h index 2dbfa4541c4..7ab4a7198c2 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/KrollModule.h +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/KrollModule.h @@ -23,7 +23,7 @@ /** * @param moduleID is assumed to be the module name (classname with the "Module" suffix stripped off) - i.e. "UI", "App", "Media" * We will generate the full class name from the moduleID: "UI" => "UIModule", "com.appcelerator.urlSession" => "ComAppceleratorUrlSessionModule" - * @return TiModule* or ObjcProxy* based on whether the module is an older style proxy moduel or a new Obj-C JSC API style (currently only 1st party in-SDK code) + * @return TiModule* or ObjcProxy* based on whether the module is an older style proxy module or a new Obj-C JSC API style (currently only 1st party in-SDK code) */ + (id)loadCoreModule:(NSString *)moduleID inContext:(JSContext *)jsContext;