Skip to content

Commit

Permalink
fix: build plugins using same gradle config structure as apps (#5671)
Browse files Browse the repository at this point in the history
  • Loading branch information
farfromrefug authored Feb 13, 2023
1 parent 32d3a0f commit 40e459a
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 122 deletions.
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 @@ -411,18 +377,13 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
const settingsGradlePath = path.join(pluginTempDir, "settings.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);
this.replaceFileContent(settingsGradlePath, "{{pluginName}}", pluginName);
}
Expand Down Expand Up @@ -642,22 +603,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 @@ -669,29 +614,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 @@ -156,6 +295,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 @@ -171,6 +311,10 @@ android {
versionCode 1
versionName "1.0"
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
}


Expand All @@ -187,9 +331,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

0 comments on commit 40e459a

Please sign in to comment.