Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ class AndroidIDEInitScriptPlugin : Plugin<Gradle> {
override fun apply(target: Gradle) {
removeDaemonLogs(target)

target.beforeSettings { settings ->
settings.addLocalMavenRepoToBuildscript(logger)
}

target.beforeProject { project ->
project.addLocalMavenRepoToBuildscript(logger)
}

target.settingsEvaluated { settings ->
settings.pluginManager.apply(COTGSettingsPlugin::class.java)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.itsaky.androidide.tooling.api.GradlePluginConfig._PROPERTY_MAVEN_LOCA
import org.adfa.constants.MAVEN_LOCAL_REPOSITORY
import org.gradle.StartParameter
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.initialization.Settings
Expand Down Expand Up @@ -64,6 +65,41 @@ class COTGSettingsPlugin : Plugin<Settings> {
}
}

/**
* Add the on-device Maven repo to a settings-level `buildscript` classpath.
*
* [COTGSettingsPlugin] only reaches `pluginManagement` and
* `dependencyResolutionManagement`, and it is applied from `settingsEvaluated` -- by
* which point a `buildscript { }` block in `settings.gradle.kts` has already resolved
* against its own repositories. A project that declares its build classpath that way
* (the plugin template does) therefore had no offline repository to resolve from and
* could only be built online. This must run from `beforeSettings`.
*
* Missing repo is not fatal here: the directory does not exist until onboarding has
* installed the assets, and failing would break every build before that point.
*/
fun Settings.addLocalMavenRepoToBuildscript(logger: Logger) {
localMavenRepoDir(logger)?.let { buildscript.repositories.addMavenRepoIfMissing(logger, it.toURI()) }
}

/**
* Same problem, project scope: a `buildscript { }` block in build.gradle.kts resolves against
* its own repositories, which [COTGSettingsPlugin] never reaches. Templates pin the Kotlin
* version there for AGP 9's built-in Kotlin, so that classpath must resolve offline.
*/
fun Project.addLocalMavenRepoToBuildscript(logger: Logger) {
localMavenRepoDir(logger)?.let { buildscript.repositories.addMavenRepoIfMissing(logger, it.toURI()) }
}

private fun localMavenRepoDir(logger: Logger): File? {
val dir = File(MAVEN_LOCAL_REPOSITORY)
if (!dir.isDirectory) {
logger.info("Local maven repo not installed yet, skipping buildscript injection: $MAVEN_LOCAL_REPOSITORY")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- target file ---'
sed -n '1,130p' gradle-plugin/src/main/java/com/itsaky/androidide/gradle/COTGSettingsPlugin.kt
printf '%s\n' '--- declared Gradle versions and logger usage ---'
rg -n -C 2 'gradle|GradleVersion|logger\.(info|lifecycle|warn|error|debug)\(' gradle-plugin gradle/libs.versions.toml build.gradle.kts settings.gradle.kts 2>/dev/null | head -240
printf '%s\n' '--- relevant tests ---'
rg -n -C 3 'COTGSettingsPlugin|MAVEN_LOCAL_REPOSITORY|Local maven repo' --glob '*Test*' --glob '*.kt' --glob '*.java' .

Repository: appdevforall/CodeOnTheGo

Length of output: 30725


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- buildscript helper call sites ---'
rg -n -C 5 'addLocalMavenRepoToBuildscript|localMavenRepoDir' --glob '*.kt' --glob '*.java' .
printf '%s\n' '--- Gradle wrapper and plugin configuration ---'
rg -n -C 3 'distributionUrl|gradleApi|gradleTestKit|org\.gradle' gradle/wrapper gradle-plugin/build.gradle.kts settings.gradle.kts build.gradle.kts 2>/dev/null
printf '%s\n' '--- local Gradle API artifacts, if present ---'
find . -type f \( -name 'gradle-api-*.jar' -o -name 'gradle-*.jar' \) -print | head -40
printf '%s\n' '--- source-level verifier for the claimed interpolation and call shape ---'
python3 - <<'PY'
from pathlib import Path
p = Path("gradle-plugin/src/main/java/com/itsaky/androidide/gradle/COTGSettingsPlugin.kt")
s = p.read_text()
line = next((x for x in s.splitlines() if 'Local maven repo not installed yet' in x), '')
print("interpolated_message:", '$MAVEN_LOCAL_REPOSITORY' in line)
print("parameterized_call_present:", 'logger.info(' in line and '{}" ,' in line)
print("helper_call_count:", s.count('localMavenRepoDir(logger)'))
PY

Repository: appdevforall/CodeOnTheGo

Length of output: 7380


🌐 Web query:

Gradle org.gradle.api.logging.Logger info(String, Object...) API

πŸ’‘ Result:

The org.gradle.api.logging.Logger.info(String, Object...) method is part of the Gradle logging API, which extends the standard SLF4J Logger interface [1][2]. It is used to log messages at the 'info' level [1][3]. Usage and Details: - Functionality: This method logs a message at the info level, where the String parameter represents the log message, potentially containing placeholders (e.g., {}), and the Object... parameter provides the arguments to replace those placeholders [1][4][2]. - SLF4J Pattern: The method supports the standard SLF4J formatting pattern, allowing you to use curly braces as placeholders for values [4][2]. For example: logger.info("A {} log message", "info") [4][2]. - Availability: It is available within Gradle build scripts via the logger property and can also be used in custom classes (such as those in buildSrc) by obtaining an SLF4J logger instance [4][2]. - Security Note: Gradle advises caution when logging sensitive information (such as credentials, tokens, or environment variables). It is a security vulnerability to log such information at any level above debug [1][3]. The Logger interface is the primary entry point for Gradle's logging system and includes additional Gradle-specific log levels like 'quiet' and 'lifecycle', beyond the standard SLF4J levels [2][5][6].

Citations:


Use the parameterized Logger.info overload.

When the repository is missing, pass MAVEN_LOCAL_REPOSITORY as a logger parameter instead of interpolating it before the call. The helper runs during beforeSettings and beforeProject.

Proposed fix
-	logger.info("Local maven repo not installed yet, skipping buildscript injection: $MAVEN_LOCAL_REPOSITORY")
+	logger.info(
+		"Local maven repo not installed yet, skipping buildscript injection: {}",
+		MAVEN_LOCAL_REPOSITORY,
+	)
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
logger.info("Local maven repo not installed yet, skipping buildscript injection: $MAVEN_LOCAL_REPOSITORY")
logger.info(
"Local maven repo not installed yet, skipping buildscript injection: {}",
MAVEN_LOCAL_REPOSITORY,
)
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@gradle-plugin/src/main/java/com/itsaky/androidide/gradle/COTGSettingsPlugin.kt`
at line 97, Update the missing-repository log in the
beforeSettings/beforeProject helper to use the parameterized Logger.info
overload: keep the repository value as a placeholder argument and pass
MAVEN_LOCAL_REPOSITORY separately instead of interpolating it into the message.

Sources: Coding guidelines, MCP tools

return null
}
return dir
}

private fun RepositoryHandler.addLocalMavenRepoIfMissing(
logger: Logger,
path: String,
Expand Down
Loading