Skip to content

Commit

Permalink
Add ociDependencies extension
Browse files Browse the repository at this point in the history
changed:
oci { imageDependencies.forTest(tasks.test) { add() } } ->
ociDependencies.forTest(tasks.test) { image() }

changed:
oci { imageDependencies.forTest(tasks.test, "v2") { add() } ->
ociDependencies.forTest(tasks.test) { imageScope("v2")() }

new:
ociDependencies.forTestSuite(testing.suites["test"])

new:
testing {
  suites {
    "test"(JvmTestSuite::class) {
      ociDependencies {
        image()
      }
    }
  }
}
  • Loading branch information
SgtSilvio committed Mar 19, 2024
1 parent 8556306 commit a6419aa
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ internal class TestProject(projectDir: File) {
mavenCentral()
}
testing {
suites.withType<JvmTestSuite> {
useJUnitJupiter("5.10.0")
suites {
"test"(JvmTestSuite::class) {
useJUnitJupiter("5.10.0")
ociDependencies {
image(project)
image(project).tag("latest")
image(constraint("library:eclipse-temurin:20.0.1_9-jre-jammy"))
image("hivemq:hivemq4:4.16.0")
}
}
}
}
oci {
Expand All @@ -64,12 +72,6 @@ internal class TestProject(projectDir: File) {
}
}
}
imageDependencies.forTest(tasks.test) {
add(project)
add(project).tag("latest")
add(constraint("library:eclipse-temurin:20.0.1_9-jre-jammy"))
add("hivemq:hivemq4:4.16.0")
}
}
""".trimIndent()
)
Expand Down
9 changes: 9 additions & 0 deletions src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.github.sgtsilvio.gradle.oci

import io.github.sgtsilvio.gradle.oci.attributes.DISTRIBUTION_TYPE_ATTRIBUTE
import io.github.sgtsilvio.gradle.oci.dsl.OciDependenciesExtension
import io.github.sgtsilvio.gradle.oci.dsl.OciExtension
import io.github.sgtsilvio.gradle.oci.internal.concatCamelCase
import io.github.sgtsilvio.gradle.oci.internal.dsl.OciDependenciesExtensionImpl
import io.github.sgtsilvio.gradle.oci.internal.dsl.OciExtensionImpl
import io.github.sgtsilvio.gradle.oci.internal.mainToEmpty
import org.gradle.api.Plugin
Expand All @@ -20,6 +22,12 @@ class OciPlugin : Plugin<Project> {
project.dependencies.attributesSchema.attribute(DISTRIBUTION_TYPE_ATTRIBUTE)
val extension = project.extensions.create(OciExtension::class, EXTENSION_NAME, OciExtensionImpl::class)
registerPushTasks(project, extension)
project.extensions.create(
OciDependenciesExtension::class,
DEPENDENCIES_EXTENSION_NAME,
OciDependenciesExtensionImpl::class,
extension,
)
}

private fun registerPushTasks(project: Project, extension: OciExtension) {
Expand All @@ -40,4 +48,5 @@ class OciPlugin : Plugin<Project> {
}

const val EXTENSION_NAME = "oci"
const val DEPENDENCIES_EXTENSION_NAME = "ociDependencies"
const val TASK_GROUP_NAME = "oci"
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.github.sgtsilvio.gradle.oci.dsl

import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.DependencyConstraint
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.plugins.jvm.JvmTestSuite
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderConvertible
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test

/**
* @author Silvio Giebl
*/
interface OciDependenciesExtension {

fun forTestSuite(testSuite: JvmTestSuite): OciDependencies

fun forTestSuite(testSuite: JvmTestSuite, action: Action<in OciDependencies>) =
action.execute(forTestSuite(testSuite))

fun forTest(testTask: TaskProvider<Test>): OciDependencies

fun forTest(testTask: TaskProvider<Test>, action: Action<in OciDependencies>) = action.execute(forTest(testTask))

// constraint factories

fun constraint(dependencyConstraintNotation: CharSequence): DependencyConstraint

fun constraint(project: Project): DependencyConstraint

fun constraint(dependencyProvider: Provider<out MinimalExternalModuleDependency>): Provider<DependencyConstraint>

fun constraint(dependencyProvider: ProviderConvertible<out MinimalExternalModuleDependency>) =
constraint(dependencyProvider.asProvider())

// dsl syntactic sugar

val JvmTestSuite.image get() = forTestSuite(this).image

fun JvmTestSuite.imageScope(scope: String) = forTestSuite(this).imageScope(scope)
}

interface OciDependencies {

val image: ResolvableOciImageDependencies

fun imageScope(scope: String): ResolvableOciImageDependencies

// constraint factories

fun constraint(dependencyConstraintNotation: CharSequence): DependencyConstraint

fun constraint(project: Project): DependencyConstraint

fun constraint(dependencyProvider: Provider<out MinimalExternalModuleDependency>): Provider<DependencyConstraint>

fun constraint(dependencyProvider: ProviderConvertible<out MinimalExternalModuleDependency>) =
constraint(dependencyProvider.asProvider())
}
13 changes: 0 additions & 13 deletions src/main/kotlin/io/github/sgtsilvio/gradle/oci/dsl/OciExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import io.github.sgtsilvio.gradle.oci.platform.PlatformFilter
import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test

/**
* @author Silvio Giebl
Expand Down Expand Up @@ -47,15 +45,4 @@ interface OciExtension {
val variants: SetProperty<String>
val osVersions: SetProperty<String>
}

fun NamedDomainObjectContainer<ResolvableOciImageDependencies>.forTest(
testTask: TaskProvider<Test>,
action: Action<in ResolvableOciImageDependencies>,
)

fun NamedDomainObjectContainer<ResolvableOciImageDependencies>.forTest(
testTask: TaskProvider<Test>,
scope: String,
action: Action<in ResolvableOciImageDependencies>,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package io.github.sgtsilvio.gradle.oci.internal.dsl

import io.github.sgtsilvio.gradle.oci.OciRegistryDataTask
import io.github.sgtsilvio.gradle.oci.TASK_GROUP_NAME
import io.github.sgtsilvio.gradle.oci.dsl.OciDependencies
import io.github.sgtsilvio.gradle.oci.dsl.OciDependenciesExtension
import io.github.sgtsilvio.gradle.oci.dsl.OciExtension
import io.github.sgtsilvio.gradle.oci.dsl.ResolvableOciImageDependencies
import io.github.sgtsilvio.gradle.oci.internal.concatCamelCase
import org.gradle.api.Project
import org.gradle.api.artifacts.DependencyConstraint
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.jvm.JvmTestSuite
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.invoke
import org.gradle.kotlin.dsl.newInstance
import org.gradle.kotlin.dsl.register
import javax.inject.Inject

/**
* @author Silvio Giebl
*/
internal abstract class OciDependenciesExtensionImpl @Inject constructor(
private val oci: OciExtension,
private val objectFactory: ObjectFactory,
private val taskContainer: TaskContainer,
private val projectLayout: ProjectLayout,
private val dependencyHandler: DependencyHandler,
) : OciDependenciesExtension {

private val testSuiteDependencies = HashMap<String, OciDependenciesImpl>()
private val testDependencies = HashMap<String, OciDependenciesImpl>()

final override fun forTestSuite(testSuite: JvmTestSuite) = testSuiteDependencies.getOrPut(testSuite.name) {
val testSuiteName = testSuite.name
val registryDataTask = taskContainer.register<OciRegistryDataTask>("${testSuiteName}OciRegistryData") {
group = TASK_GROUP_NAME
description = "Creates a Docker registry data directory to be used by the $testSuiteName suite."
registryDataDirectory.set(projectLayout.buildDirectory.dir("oci/registries/$testSuiteName"))
}
testSuite.targets.all {
testTask {
jvmArgumentProviders += OciTestArgumentProvider(objectFactory, registryDataTask)
}
}
objectFactory.newInstance<OciDependenciesImpl>(testSuiteName, registryDataTask, oci)
}

final override fun forTest(testTask: TaskProvider<Test>) = testDependencies.getOrPut(testTask.name) {
val testTaskName = testTask.name
val registryDataTask = taskContainer.register<OciRegistryDataTask>("${testTaskName}OciRegistryData") {
group = TASK_GROUP_NAME
description = "Creates a Docker registry data directory to be used by the $testTaskName task."
registryDataDirectory.set(projectLayout.buildDirectory.dir("oci/registries/$testTaskName"))
}
testTask {
jvmArgumentProviders += OciTestArgumentProvider(objectFactory, registryDataTask)
}
objectFactory.newInstance<OciDependenciesImpl>(testTaskName, registryDataTask, oci)
}

final override fun constraint(dependencyConstraintNotation: CharSequence): DependencyConstraint =
dependencyHandler.constraints.create(dependencyConstraintNotation)

final override fun constraint(project: Project): DependencyConstraint =
dependencyHandler.constraints.create(project)

private fun constraint(dependency: MinimalExternalModuleDependency): DependencyConstraint =
dependencyHandler.constraints.create(dependency)

final override fun constraint(
dependencyProvider: Provider<out MinimalExternalModuleDependency>,
): Provider<DependencyConstraint> = dependencyProvider.map { constraint(it) }
}

internal abstract class OciDependenciesImpl @Inject constructor(
private val name: String,
private val registryDataTask: TaskProvider<OciRegistryDataTask>,
private val oci: OciExtension,
private val dependencyHandler: DependencyHandler,
) : OciDependencies {

private val scopes = HashMap<String, ResolvableOciImageDependencies>()

final override val image = imageScope("")

final override fun imageScope(scope: String): ResolvableOciImageDependencies = scopes.getOrPut(scope) {
val imageDependencies = oci.imageDependencies.create(name.concatCamelCase(scope))
registryDataTask {
from(imageDependencies)
}
imageDependencies
}

final override fun constraint(dependencyConstraintNotation: CharSequence): DependencyConstraint =
dependencyHandler.constraints.create(dependencyConstraintNotation)

final override fun constraint(project: Project): DependencyConstraint =
dependencyHandler.constraints.create(project)

private fun constraint(dependency: MinimalExternalModuleDependency): DependencyConstraint =
dependencyHandler.constraints.create(dependency)

final override fun constraint(
dependencyProvider: Provider<out MinimalExternalModuleDependency>,
): Provider<DependencyConstraint> = dependencyProvider.map { constraint(it) }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.github.sgtsilvio.gradle.oci.internal.dsl

import io.github.sgtsilvio.gradle.oci.OciRegistryDataTask
import io.github.sgtsilvio.gradle.oci.TASK_GROUP_NAME
import io.github.sgtsilvio.gradle.oci.dsl.OciExtension
import io.github.sgtsilvio.gradle.oci.dsl.OciImageDefinition
import io.github.sgtsilvio.gradle.oci.dsl.OciRegistries
Expand All @@ -12,23 +10,15 @@ import io.github.sgtsilvio.gradle.oci.platform.Platform
import io.github.sgtsilvio.gradle.oci.platform.PlatformFilter
import io.github.sgtsilvio.gradle.oci.platform.PlatformImpl
import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.*
import org.gradle.kotlin.dsl.domainObjectContainer
import org.gradle.kotlin.dsl.newInstance
import javax.inject.Inject

/**
* @author Silvio Giebl
*/
internal abstract class OciExtensionImpl @Inject constructor(
private val objectFactory: ObjectFactory,
private val taskContainer: TaskContainer,
private val projectLayout: ProjectLayout,
) : OciExtension {
internal abstract class OciExtensionImpl @Inject constructor(private val objectFactory: ObjectFactory) : OciExtension {

final override val imageMapping = objectFactory.newInstance<OciImageMappingImpl>()

Expand Down Expand Up @@ -75,40 +65,4 @@ internal abstract class OciExtensionImpl @Inject constructor(

final override fun PlatformFilter.or(configuration: Action<in OciExtension.PlatformFilterBuilder>) =
or(platformFilter(configuration))

final override fun NamedDomainObjectContainer<ResolvableOciImageDependencies>.forTest(
testTask: TaskProvider<Test>,
action: Action<in ResolvableOciImageDependencies>,
) = forTest(testTask, "", action)

final override fun NamedDomainObjectContainer<ResolvableOciImageDependencies>.forTest(
testTask: TaskProvider<Test>,
scope: String,
action: Action<in ResolvableOciImageDependencies>,
) {
val testTaskName = testTask.name
val registryDataTaskName = "${testTaskName}OciRegistryData"
val registryDataTask = if (registryDataTaskName in taskContainer.names) {
taskContainer.named<OciRegistryDataTask>(registryDataTaskName)
} else {
val registryDataTask = taskContainer.register<OciRegistryDataTask>(registryDataTaskName) {
group = TASK_GROUP_NAME
description = "Creates a Docker registry data directory to be used by the $testTaskName task."
registryDataDirectory.set(projectLayout.buildDirectory.dir("oci/registries/$testTaskName"))
}
testTask {
jvmArgumentProviders += OciTestArgumentProvider(objectFactory, registryDataTask)
}
registryDataTask
}
val imageDependenciesName = testTaskName + scope.replaceFirstChar(Char::uppercaseChar)
if (imageDependenciesName in imageDependencies.names) {
imageDependencies.named(imageDependenciesName, action)
} else {
val imageDependencies = imageDependencies.register(imageDependenciesName, action)
registryDataTask {
from(imageDependencies.get())
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ internal abstract class OciImageDependenciesImpl<T>(
private fun constraint(dependency: MinimalExternalModuleDependency): DependencyConstraint =
dependencyHandler.constraints.create(dependency)

final override fun constraint(dependencyProvider: Provider<out MinimalExternalModuleDependency>) =
dependencyProvider.map { constraint(it) }
final override fun constraint(
dependencyProvider: Provider<out MinimalExternalModuleDependency>,
): Provider<DependencyConstraint> = dependencyProvider.map { constraint(it) }
}

0 comments on commit a6419aa

Please sign in to comment.