diff --git a/.gitignore b/.gitignore index 0f893808..1c7047cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Ignore Gradle project-specific cache directory .gradle +# claude +.claude + # Ignore Gradle build output directory build diff --git a/gradle.properties b/gradle.properties index 4bbfffa6..5354330f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,5 +5,5 @@ org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAME --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED org.gradle.configuration-cache=true org.gradle.caching=true -version=0.11.0 +version=0.12.0 group=com.ryandens diff --git a/plugin/src/main/java/com/ryandens/javaagent/JibExtensionConfiguration.java b/plugin/src/main/java/com/ryandens/javaagent/JibExtensionConfiguration.java new file mode 100644 index 00000000..c101d447 --- /dev/null +++ b/plugin/src/main/java/com/ryandens/javaagent/JibExtensionConfiguration.java @@ -0,0 +1,46 @@ +package com.ryandens.javaagent; + +import java.io.File; +import javax.inject.Inject; +import org.gradle.api.Project; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.ListProperty; +import org.gradle.api.tasks.Input; + +/** + * Extra configuration for {@link JavaagentJibExtension}. Declares the javaagent files that should + * be copied into the container image and referenced via {@code -javaagent} JVM flags. + * + *

Instances are created by Jib's plugin extension mechanism via {@link + * org.gradle.api.model.ObjectFactory}, so this class must have a single-argument constructor + * accepting {@link ObjectFactory}. + */ +public class JibExtensionConfiguration { + + private final ListProperty javaagentFiles; + + /** + * Instantiated by Jib's plugin extension mechanism + * + *

Not compatible with configuration cache due to usage of Project at task execution time. + */ + @Inject + public JibExtensionConfiguration(final Project project) { + this(project.getObjects()); + } + + public JibExtensionConfiguration(final ObjectFactory objectFactory) { + javaagentFiles = objectFactory.listProperty(File.class); + } + + /** + * Returns the list of javaagent {@link File}s to include in the container image. Each file is + * placed under {@code /opt/jib-agents/} in the image and added to the container entrypoint as a + * {@code -javaagent} flag. Package-private: intended to be accessed only by {@link + * JavaagentJibExtension}. + */ + @Input + ListProperty getJavaagentFiles() { + return javaagentFiles; + } +} diff --git a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentJibExtension.kt b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentJibExtension.kt index 210aa4f5..b5d867a2 100644 --- a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentJibExtension.kt +++ b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentJibExtension.kt @@ -10,6 +10,8 @@ import com.google.cloud.tools.jib.gradle.JibExtension import com.google.cloud.tools.jib.gradle.extension.GradleData import com.google.cloud.tools.jib.gradle.extension.JibGradlePluginExtension import com.google.cloud.tools.jib.plugins.extension.ExtensionLogger +import org.gradle.api.Action +import org.gradle.api.GradleException import org.gradle.api.NamedDomainObjectProvider import org.gradle.api.Project import org.gradle.api.artifacts.Configuration @@ -24,31 +26,24 @@ import java.util.Optional */ @ExperimentalStdlibApi class JavaagentJibExtension : - JibGradlePluginExtension, + JibGradlePluginExtension, JavaagentPlugin { - override fun getExtraConfigType(): Optional> = Optional.empty() + override fun getExtraConfigType(): Optional> = Optional.of(JibExtensionConfiguration::class.java) override fun extendContainerBuildPlan( - buildPlan: ContainerBuildPlan?, - properties: MutableMap?, - extraConfig: Optional?, + buildPlan: ContainerBuildPlan, + properties: MutableMap, + extraConfig: Optional, gradleData: GradleData?, logger: ExtensionLogger?, ): ContainerBuildPlan { - checkNotNull(buildPlan) val entrypoint = checkNotNull(buildPlan.entrypoint) check(entrypoint.isNotEmpty()) + if (extraConfig.isEmpty) { + throw GradleException("Javaagent Jib plugin must be provided an extraConfig containing javaagent files to configure") + } - val localAgentPaths = - checkNotNull( - gradleData - ?.project - ?.plugins - ?.getPlugin( - JavaagentJibExtension::class.java, - )?.javaagentPathProvider - ?.invoke(), - ) + val localAgentPaths = extraConfig.get().javaagentFiles.get() val planBuilder = buildPlan.toBuilder() val newEntrypoint = @@ -90,24 +85,41 @@ class JavaagentJibExtension : it.into(destinationDirectory) } - listOf("jib", "jibDockerBuild", "jibBuildTar").forEach { jibTaskName -> - project.tasks.named(jibTaskName) { jibTask -> - jibTask.dependsOn(copyAgents) + if (project.pluginManager.hasPlugin("com.google.cloud.tools.jib")) { + listOf("jib", "jibDockerBuild", "jibBuildTar").forEach { jibTaskName -> + project.tasks.named(jibTaskName) { jibTask -> + jibTask.dependsOn(copyAgents) + } + } + } else if (project.pluginManager.hasPlugin("tel.schich.tinyjib")) { + listOf("tinyJibPublish", "tinyJibDocker", "tinyJibTar").forEach { jibTaskName -> + project.tasks.named(jibTaskName) { jibTask -> + jibTask.dependsOn(copyAgents) + } } + } else { + throw IllegalStateException("Should not be possible") } val jibExtension: JibExtension? = project.extensions.findByType(JibExtension::class.java) jibExtension?.pluginExtensions { extensionParametersSpec -> - extensionParametersSpec.pluginExtension { - it.implementation = "com.ryandens.javaagent.JavaagentJibExtension" + extensionParametersSpec.pluginExtension { extension -> + extension.implementation = "com.ryandens.javaagent.JavaagentJibExtension" + extension.configuration( + Action { extensionConfiguration -> + extensionConfiguration.javaagentFiles.set( + project.provider { + javaagentConfiguration + .get() + .files + .map { File(destinationDirectory.get().asFile, it.name) } + .toList() + }, + ) + }, + ) } } - - javaagentPathProvider = { - javaagentConfiguration.get().files.map { File(destinationDirectory.get().asFile, it.name) } - } } - - private lateinit var javaagentPathProvider: () -> List }