diff --git a/shared/src/main/java/com/itsaky/androidide/utils/AndroidPluginVersion.kt b/shared/src/main/java/com/itsaky/androidide/utils/AndroidPluginVersion.kt
index 9905421f5..ebeb1827e 100644
--- a/shared/src/main/java/com/itsaky/androidide/utils/AndroidPluginVersion.kt
+++ b/shared/src/main/java/com/itsaky/androidide/utils/AndroidPluginVersion.kt
@@ -228,7 +228,7 @@ class AndroidPluginVersion private constructor(
fun toStringSimple(): String = "$major.$minor.$micro" +
(if (previewType != null) "-$previewType" else "") +
- (if (preview > 0) preview else "")
+ (if (preview > 0) if(preview < 10) "0$preview" else preview else "")
companion object {
diff --git a/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/sync/AbstractModelBuilder.kt b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/sync/AbstractModelBuilder.kt
index db6ab14d4..102500ad2 100644
--- a/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/sync/AbstractModelBuilder.kt
+++ b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/sync/AbstractModelBuilder.kt
@@ -22,8 +22,8 @@ import com.itsaky.androidide.builder.model.DefaultSyncIssue
import com.itsaky.androidide.builder.model.IDESyncIssue
import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
import com.itsaky.androidide.tooling.impl.util.StopWatch
+import com.itsaky.androidide.tooling.impl.util.ToolingProps
import com.itsaky.androidide.utils.AndroidPluginVersion
-import com.itsaky.androidide.utils.AndroidPluginVersion.Companion.LATEST_TESTED
import com.itsaky.androidide.utils.AndroidPluginVersion.Companion.MINIMUM_SUPPORTED
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.LogUtils
@@ -78,9 +78,9 @@ abstract class AbstractModelBuilder
(
}
// Warn the user if the project is using a newer AGP version
- if (!newerAgpWarned.get() && agpVersion > LATEST_TESTED) {
+ if (!newerAgpWarned.get() && agpVersion > ToolingProps.latestTestedAgpVersion) {
val syncIssue = DefaultSyncIssue(
- data = "${agpVersion.toStringSimple()}:${LATEST_TESTED.toStringSimple()}",
+ data = "${agpVersion.toStringSimple()}:${ToolingProps.latestTestedAgpVersion.toStringSimple()}",
message = "You are using Android Gradle Plugin version that has not been tested with AndroidIDE.",
multiLineMessage = null,
severity = SyncIssue.SEVERITY_WARNING,
diff --git a/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ToolingProps.kt b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ToolingProps.kt
new file mode 100644
index 000000000..353bfcb89
--- /dev/null
+++ b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ToolingProps.kt
@@ -0,0 +1,45 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.tooling.impl.util
+
+import com.itsaky.androidide.utils.AndroidPluginVersion
+
+/**
+ * System properties for configuring the toolign API.
+ *
+ * @author Akash Yadav
+ */
+object ToolingProps {
+
+ val TESTING_IS_TEST_ENV = propName("testing", "isTestEnv")
+ val TESTING_LATEST_AGP_VERSION = propName("testing", "latestAgpVersion")
+
+ val isTestEnv: Boolean
+ get() = System.getProperty(TESTING_IS_TEST_ENV).toBoolean()
+
+ val latestTestedAgpVersion: AndroidPluginVersion
+ get() {
+ if (!isTestEnv) {
+ return AndroidPluginVersion.LATEST_TESTED
+ }
+ return System.getProperty(TESTING_LATEST_AGP_VERSION)?.let { AndroidPluginVersion.parse(it) }
+ ?: AndroidPluginVersion.LATEST_TESTED
+ }
+
+ fun propName(cat: String, name: String) = "ide.tooling.$cat.$name"
+}
\ No newline at end of file
diff --git a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt
index b715050e2..9d3b52547 100644
--- a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt
+++ b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt
@@ -36,8 +36,10 @@ import com.itsaky.androidide.tooling.api.models.JavaProjectMetadata
import com.itsaky.androidide.tooling.api.models.params.StringParameter
import com.itsaky.androidide.tooling.events.ProgressEvent
import com.itsaky.androidide.tooling.events.task.TaskStartEvent
+import com.itsaky.androidide.tooling.impl.util.ToolingProps
import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher
import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher.MultiVersionTestClient
+import com.itsaky.androidide.utils.AndroidPluginVersion
import com.itsaky.androidide.utils.FileProvider
import com.itsaky.androidide.utils.ILogger
import org.junit.Test
@@ -45,8 +47,10 @@ import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import java.nio.file.Paths
import java.util.concurrent.CompletableFuture
+import kotlin.io.path.createDirectory
import kotlin.io.path.createFile
import kotlin.io.path.deleteIfExists
+import kotlin.io.path.exists
/** @author Akash Yadav */
@RunWith(JUnit4::class)
@@ -69,7 +73,8 @@ class MultiModuleAndroidProjectTest {
@Test
fun `test project initialization with file path`() {
- val path = FileProvider.projectRoot().resolve("build").resolve("should-be-directory.txt")
+ val path = FileProvider.projectRoot().resolve("build")
+ .also { if (!it.exists()) it.createDirectory() }.resolve("should-be-directory.txt")
path.deleteIfExists()
path.createFile()
@@ -294,9 +299,16 @@ class MultiModuleAndroidProjectTest {
fun `test CI-only latest tested AGP version warning`() {
ciOnlyTest {
val log = CollectingLogger()
- val agpVersion = "8.1.1"
- val client = MultiVersionTestClient(agpVersion = agpVersion, gradleVersion = "8.1", log = log)
- val (_, project, result) = ToolingApiTestLauncher().launchServer(client = client, log = log)
+ val agpVersion = AndroidPluginVersion.parse(BuildInfo.AGP_VERSION_LATEST)
+
+ val client = MultiVersionTestClient(agpVersion = agpVersion.toStringSimple(),
+ gradleVersion = "${agpVersion.major}.${agpVersion.minor}", log = log)
+ val (_, project, result) = ToolingApiTestLauncher().launchServer(
+ client = client,
+ log = log,
+ sysProps = mapOf(
+ ToolingProps.TESTING_LATEST_AGP_VERSION to MultiVersionTestClient.DEFAULT_AGP_VERSION)
+ )
val output = log.toString()
if (result?.isSuccessful != true) {
diff --git a/testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt b/testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt
index 6f9f2fa3c..fddc0b37b 100644
--- a/testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt
+++ b/testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt
@@ -30,6 +30,7 @@ import com.itsaky.androidide.tooling.api.messages.result.InitializeResult
import com.itsaky.androidide.tooling.api.messages.toLogLine
import com.itsaky.androidide.tooling.api.util.ToolingApiLauncher
import com.itsaky.androidide.tooling.events.ProgressEvent
+import com.itsaky.androidide.tooling.impl.util.ToolingProps
import com.itsaky.androidide.utils.FileProvider
import com.itsaky.androidide.utils.ILogger
import java.io.BufferedReader
@@ -72,14 +73,23 @@ class ToolingApiTestLauncher {
projectDir.pathString,
client.gradleDistParams
),
- log: ILogger = ILogger.newInstance("BuildOutputLogger")
+ log: ILogger = ILogger.newInstance("BuildOutputLogger"),
+ sysProps: Map = emptyMap(),
+ sysEnvs: Map = emptyMap()
): Triple {
- val builder = ProcessBuilder(createProcessCmd(FileProvider.implModule()
- .resolve("build/libs/tooling-api-all.jar").pathString))
+ val cmdLine = createProcessCmd(
+ FileProvider.implModule()
+ .resolve("build/libs/tooling-api-all.jar").pathString,
+ sysProps
+ )
+
+ val builder = ProcessBuilder(cmdLine)
val androidHome = findAndroidHome()
- println("ANDROID_HOME=$androidHome")
+
builder.environment()["ANDROID_SDK_ROOT"] = androidHome
builder.environment()["ANDROID_HOME"] = androidHome
+ builder.environment().putAll(sysEnvs)
+
val proc = builder.start()
Thread(Reader(proc.errorStream, log)).start()
@@ -95,7 +105,10 @@ class ToolingApiTestLauncher {
return Triple(server, project, result)
}
- private fun createProcessCmd(jar: String): List {
+ private fun createProcessCmd(
+ jar: String,
+ sysProps: Map = emptyMap()
+ ): List {
val cmd = mutableListOf("java")
System.getenv("JAVA_HOME")?.let {
val java = File(it, "bin/java")
@@ -116,6 +129,12 @@ class ToolingApiTestLauncher {
cmd.add("--add-exports=${export.key}/${export.value}=ALL-UNNAMED")
}
+ cmd.add("-D${ToolingProps.TESTING_IS_TEST_ENV}=true")
+
+ sysProps.forEach { (key, value) ->
+ cmd.add("-D$key=$value")
+ }
+
Collections.addAll(cmd, "-jar", jar)
println(
@@ -129,7 +148,7 @@ class ToolingApiTestLauncher {
var agpVersion: String = DEFAULT_AGP_VERSION,
var gradleVersion: String = DEFAULT_GRADLE_VERSION,
private val log: ILogger = ILogger.newInstance(MultiVersionTestClient::class.simpleName),
- private val extraArgs : List = emptyList(),
+ private val extraArgs: List = emptyList(),
private var excludeUnresolvedDependency: Boolean = false
) : IToolingApiClient {
@@ -193,7 +212,8 @@ class ToolingApiTestLauncher {
override fun onProgressEvent(event: ProgressEvent) {}
override fun getBuildArguments(): CompletableFuture> {
- return CompletableFuture.completedFuture(mutableListOf("--stacktrace", "--info").also { it.addAll(extraArgs) })
+ return CompletableFuture.completedFuture(
+ mutableListOf("--stacktrace", "--info").also { it.addAll(extraArgs) })
}
override fun checkGradleWrapperAvailability(): CompletableFuture =