Skip to content

fix: android plugins now built using same “gradle” as apps #5671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 0 additions & 78 deletions lib/services/android-plugin-build-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,40 +144,6 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
return promise;
}

private getIncludeGradleCompileDependenciesScope(
includeGradleFileContent: string
): Array<string> {
const indexOfDependenciesScope = includeGradleFileContent.indexOf(
"dependencies"
);
const result: Array<string> = [];

if (indexOfDependenciesScope === -1) {
return result;
}

const indexOfRepositoriesScope = includeGradleFileContent.indexOf(
"repositories"
);

let repositoriesScope = "";
if (indexOfRepositoriesScope >= 0) {
repositoriesScope = this.getScope(
"repositories",
includeGradleFileContent
);
result.push(repositoriesScope);
}

const dependenciesScope = this.getScope(
"dependencies",
includeGradleFileContent
);
result.push(dependenciesScope);

return result;
}

private getScope(scopeName: string, content: string): string {
const indexOfScopeName = content.indexOf(scopeName);
const openingBracket = "{";
Expand Down Expand Up @@ -410,18 +376,13 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
const buildGradlePath = path.join(pluginTempDir, "build.gradle");

this.$fs.copyFile(allGradleTemplateFiles, pluginTempDir);
this.addCompileDependencies(platformsAndroidDirPath, buildGradlePath);
const runtimeGradleVersions = await this.getRuntimeGradleVersions(
projectDir
);
this.replaceGradleVersion(
pluginTempDir,
runtimeGradleVersions.gradleVersion
);
this.replaceGradleAndroidPluginVersion(
buildGradlePath,
runtimeGradleVersions.gradleAndroidPluginVersion
);
this.replaceFileContent(buildGradlePath, "{{pluginName}}", pluginName);
}

Expand Down Expand Up @@ -640,22 +601,6 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
);
}

private replaceGradleAndroidPluginVersion(
buildGradlePath: string,
version: string
): void {
const gradleAndroidPluginVersionPlaceholder =
"{{runtimeAndroidPluginVersion}}";
const gradleAndroidPluginVersion =
version || AndroidBuildDefaults.GradleAndroidPluginVersion;

this.replaceFileContent(
buildGradlePath,
gradleAndroidPluginVersionPlaceholder,
gradleAndroidPluginVersion
);
}

private replaceFileContent(
filePath: string,
content: string,
Expand All @@ -667,29 +612,6 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
this.$fs.writeFile(filePath, replacedFileContent);
}

private addCompileDependencies(
platformsAndroidDirPath: string,
buildGradlePath: string
): void {
const includeGradlePath = path.join(
platformsAndroidDirPath,
INCLUDE_GRADLE_NAME
);
if (this.$fs.exists(includeGradlePath)) {
const includeGradleContent = this.$fs.readText(includeGradlePath);
const compileDependencies = this.getIncludeGradleCompileDependenciesScope(
includeGradleContent
);

if (compileDependencies.length) {
this.$fs.appendFile(
buildGradlePath,
"\n" + compileDependencies.join("\n")
);
}
}
}

private copyAar(
shortPluginName: string,
pluginTempDir: string,
Expand Down
204 changes: 176 additions & 28 deletions vendor/gradle-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,72 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'

buildscript {
def getDepPlatformDir = { dep ->
file("${project.ext.USER_PROJECT_ROOT}/${project.ext.PLATFORMS_ANDROID}/${dep.directory}/$PLATFORMS_ANDROID")
}
def computeKotlinVersion = { -> project.hasProperty("kotlinVersion") ? kotlinVersion : "1.6.0" }
def kotlinVersion = computeKotlinVersion()
repositories {
google()
jcenter()
def loadPropertyFile = { path ->
try {
if(project.hasProperty("loadedProperties_${path}")) {
logger.info "\t + gradle properties already loaded. SKIPPING"
} else {
logger.info "\t + trying to load gradle properties from \"$path\""

Properties properties = new Properties()
properties.load(new FileInputStream("$path"))
properties.each { prop ->
logger.info "\t + [$path] setting ${prop.key} = ${prop.value}"
project.ext.set(prop.key, prop.value)
}
project.ext.set("loadedProperties_${path}", true)

outLogger.withStyle(Style.SuccessHeader).println "\t + loaded gradle properties from \"$path\""
}
} catch(Exception ex) {
logger.warn "\t + failed to load gradle properties from \"$path\". Error is: ${ex.getMessage()}"
}
dependencies {
classpath 'com.android.tools.build:gradle:{{runtimeAndroidPluginVersion}}'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}

buildscript {
def GRADLE_PROPERTIES_FILENAME = "gradle.properties"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
def getFile = { dir, filename ->
File file = new File("$dir$File.separator$filename")
file?.exists() ? file : null
}

// Set up styled logger
project.ext.getDepPlatformDir = getDepPlatformDir
project.ext.outLogger = services.get(StyledTextOutputFactory).create("colouredOutputLogger")
def getPropertyFile = { dir ->
return getFile(dir, GRADLE_PROPERTIES_FILENAME)
}
def getUserProperties = { dir ->
def file = getPropertyFile(dir)
if (!file) {
return null
}

project.ext.USER_PROJECT_ROOT = "$rootDir/../../.."
project.ext.PLATFORMS_ANDROID = "platforms/android"
project.ext.PLUGIN_NAME = "{{pluginName}}"
Properties properties = new Properties()
properties.load(file.newInputStream())

// the build script will not work with previous versions of the CLI (3.1 or earlier)
def dependenciesJson = file("${project.ext.USER_PROJECT_ROOT}/${project.ext.PLATFORMS_ANDROID}/dependencies.json")
def appDependencies = new JsonSlurper().parseText(dependenciesJson.text)
def pluginData = appDependencies.find { it.name == project.ext.PLUGIN_NAME }
project.ext.nativescriptDependencies = appDependencies.findAll{pluginData.dependencies.contains(it.name)}
project.ext.getAppPath = { ->
return properties
}
def loadPropertyFile = { path ->
try {
if(project.hasProperty("loadedProperties_${path}")) {
logger.info "\t + gradle properties already loaded. SKIPPING"
} else {
logger.info "\t + trying to load gradle properties from \"$path\""

Properties properties = new Properties()
properties.load(new FileInputStream("$path"))
properties.each { prop ->
logger.info "\t + [$path] setting ${prop.key} = ${prop.value}"
project.ext.set(prop.key, prop.value)
}
project.ext.set("loadedProperties_${path}", true)

outLogger.withStyle(Style.SuccessHeader).println "\t + loaded gradle properties from \"$path\""
}
} catch(Exception ex) {
logger.warn "\t + failed to load gradle properties from \"$path\". Error is: ${ex.getMessage()}"
}
}
def getAppPath = { ->
def relativePathToApp = "app"
def nsConfigFile = file("$USER_PROJECT_ROOT/nsconfig.json")
def nsConfig
Expand All @@ -59,8 +93,7 @@ buildscript {

return project.ext.appPath
}

project.ext.getAppResourcesPath = { ->
def getAppResourcesPath = { ->
def relativePathToAppResources
def absolutePathToAppResources
def nsConfigFile = file("$USER_PROJECT_ROOT/nsconfig.json")
Expand All @@ -87,6 +120,95 @@ buildscript {
return absolutePathToAppResources
}

def initialize = { ->
// set up our logger
project.ext.outLogger = services.get(StyledTextOutputFactory).create("colouredOutputLogger")
outLogger.withStyle(Style.SuccessHeader).println "\t ~initialize"


project.ext.USER_PROJECT_ROOT = "$rootDir/../../.."
project.ext.PLATFORMS_ANDROID = "platforms/android"
project.ext.PLUGIN_NAME = "{{pluginName}}"

def userDir = "$USER_PROJECT_ROOT"
rootProject.ext.userDefinedGradleProperties = getUserProperties("${getAppResourcesPath()}/Android")

loadPropertyFile("$USER_PROJECT_ROOT/${project.ext.PLATFORMS_ANDROID}/gradle.properties")
loadPropertyFile("$USER_PROJECT_ROOT/${project.ext.PLATFORMS_ANDROID}/additional_gradle.properties")

if (rootProject.hasProperty("userDefinedGradleProperties")) {
rootProject.ext.userDefinedGradleProperties.each { entry ->
def propertyName = entry.getKey()
def propertyValue = entry.getValue()
project.ext.set(propertyName, propertyValue)
}
}

def getDepPlatformDir = { dep ->
file("${project.ext.USER_PROJECT_ROOT}/${project.ext.PLATFORMS_ANDROID}/${dep.directory}/$PLATFORMS_ANDROID")
}

// Set up styled logger
project.ext.getDepPlatformDir = getDepPlatformDir
project.ext.outLogger = services.get(StyledTextOutputFactory).create("colouredOutputLogger")


// the build script will not work with previous versions of the CLI (3.1 or earlier)
def dependenciesJson = file("${project.ext.USER_PROJECT_ROOT}/${project.ext.PLATFORMS_ANDROID}/dependencies.json")
def appDependencies = new JsonSlurper().parseText(dependenciesJson.text)
def pluginData = appDependencies.find { it.name == project.ext.PLUGIN_NAME }
project.ext.nativescriptDependencies = appDependencies.findAll{pluginData.dependencies.contains(it.name)}.plus([pluginData])

project.ext.getAppResourcesPath = { ->
def relativePathToAppResources
def absolutePathToAppResources
def nsConfigFile = file("$USER_PROJECT_ROOT/nsconfig.json")
def nsConfig

if (nsConfigFile.exists()) {
nsConfig = new JsonSlurper().parseText(nsConfigFile.getText("UTF-8"))
}

if (project.hasProperty("appResourcesPath")) {
// when appResourcesPath is passed through -PappResourcesPath=/path/to/App_Resources
// the path could be relative or absolute - either case will work
relativePathToAppResources = appResourcesPath
absolutePathToAppResources = Paths.get(USER_PROJECT_ROOT).resolve(relativePathToAppResources).toAbsolutePath()
} else if (nsConfig != null && nsConfig.appResourcesPath != null) {
relativePathToAppResources = nsConfig.appResourcesPath
absolutePathToAppResources = Paths.get(USER_PROJECT_ROOT).resolve(relativePathToAppResources).toAbsolutePath()
} else {
absolutePathToAppResources = "${getAppPath()}/App_Resources"
}

project.ext.appResourcesPath = absolutePathToAppResources

return absolutePathToAppResources
}


project.ext.getAppPath = { ->
def relativePathToApp = "app"
def nsConfigFile = file("$USER_PROJECT_ROOT/nsconfig.json")
def nsConfig

if (nsConfigFile.exists()) {
nsConfig = new JsonSlurper().parseText(nsConfigFile.getText("UTF-8"))
}

if (project.hasProperty("appPath")) {
// when appPath is passed through -PappPath=/path/to/app
// the path could be relative or absolute - either case will work
relativePathToApp = appPath
} else if (nsConfig != null && nsConfig.appPath != null) {
relativePathToApp = nsConfig.appPath
}

project.ext.appPath = Paths.get(USER_PROJECT_ROOT).resolve(relativePathToApp).toAbsolutePath()

return project.ext.appPath
}
}
def applyBuildScriptConfigurations = { ->
def absolutePathToAppResources = getAppResourcesPath()
def pathToBuildScriptGradle = "$absolutePathToAppResources/Android/buildscript.gradle"
Expand All @@ -112,8 +234,25 @@ buildscript {
apply from: pathToPluginBuildScriptGradle, to: buildscript
}
}

initialize()
applyBuildScriptConfigurations()

def computeKotlinVersion = { -> project.hasProperty("kotlinVersion") ? kotlinVersion : "${ns_default_kotlin_version}" }
def computeBuildToolsVersion = { -> project.hasProperty("androidBuildToolsVersion") ? androidBuildToolsVersion : "${NS_DEFAULT_ANDROID_BUILD_TOOLS_VERSION}" }
def kotlinVersion = computeKotlinVersion()
def androidBuildToolsVersion = computeBuildToolsVersion()

repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:$androidBuildToolsVersion"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.codehaus.groovy:groovy-all:3.0.8"
}

}

def pluginDependencies
Expand Down Expand Up @@ -155,6 +294,7 @@ android {
nativescriptDependencies.each { dep ->
def includeGradlePath = "${getDepPlatformDir(dep)}/include.gradle"
if (file(includeGradlePath).exists()) {
outLogger.withStyle(Style.SuccessHeader).println "\t + applying plugin include.gradle from dependency ${includeGradlePath}"
apply from: includeGradlePath
}
}
Expand All @@ -170,6 +310,10 @@ android {
versionCode 1
versionName "1.0"
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
}


Expand All @@ -186,9 +330,13 @@ def applyBeforePluginGradleConfiguration() {
task addDependenciesFromNativeScriptPlugins {
nativescriptDependencies.each { dep ->
def aarFiles = fileTree(dir: getDepPlatformDir(dep), include: ["**/*.aar"])
def currentDirname = file(project.buildscript.sourceFile).getParentFile().getName()
aarFiles.each { aarFile ->
def length = aarFile.name.length() - 4
def fileName = aarFile.name[0..<length]
if(fileName == currentDirname) {
return
}
outLogger.withStyle(Style.SuccessHeader).println "\t + adding aar plugin dependency: " + aarFile.getAbsolutePath()
project.dependencies.add("implementation", [name: fileName, ext: "aar"])
}
Expand Down
17 changes: 1 addition & 16 deletions vendor/gradle-plugin/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
#org.gradle.parallel=true

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Nativescript CLI plugin build gradle properties
org.gradle.jvmargs=-Xmx16384M

android.enableJetifier=true
Expand Down