Skip to content

Commit

Permalink
Fixed broken classpath on clean and missing resources (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmazzo authored Dec 24, 2024
1 parent 38ed81b commit 7c9ddcc
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ package io.github.gmazzo.dependencies.embedded

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
import org.gradle.api.attributes.Category.LIBRARY
import org.gradle.api.attributes.LibraryElements
import org.gradle.api.attributes.LibraryElements.CLASSES
import org.gradle.api.attributes.LibraryElements.JAR
import org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE
import org.gradle.api.attributes.LibraryElements.RESOURCES
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.domainObjectContainer
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.registerTransform
import org.gradle.kotlin.dsl.the

class EmbeddedDependenciesPlugin : Plugin<Project> {
Expand Down Expand Up @@ -38,36 +46,50 @@ class EmbeddedDependenciesPlugin : Plugin<Project> {
"META-INF/maven/**",
"META-INF/versions/*/module-info.class"
)

}

the<SourceSetContainer>().configureEach {
val spec = extension.maybeCreate(name)

val config = configurations.maybeCreate(
when (name) {
SourceSet.MAIN_SOURCE_SET_NAME -> "embedded"
else -> "${name}Embedded"
val discriminator = "$path-${if (name == MAIN_SOURCE_SET_NAME) "embedded" else "embedded-$name"}"
val jarElements: LibraryElements = objects.named(JAR)
val classesElements: LibraryElements = objects.named("$CLASSES+$discriminator")
val resourcesElements: LibraryElements = objects.named("$RESOURCES+$discriminator")

dependencies.registerTransform(ExtractJARTransform::class) {
from.attributes.attribute(LIBRARY_ELEMENTS_ATTRIBUTE, jarElements)
to.attributes.attribute(LIBRARY_ELEMENTS_ATTRIBUTE, classesElements)
parameters.forResources = false
parameters.includes.value(spec.includes)
parameters.excludes.value(spec.excludes)
}

dependencies.registerTransform(ExtractJARTransform::class) {
from.attributes.attribute(LIBRARY_ELEMENTS_ATTRIBUTE, jarElements)
to.attributes.attribute(LIBRARY_ELEMENTS_ATTRIBUTE, resourcesElements)
parameters.forResources = true
parameters.includes.value(spec.includes)
parameters.excludes.value(spec.excludes)
}

val config = configurations.create(if (name == MAIN_SOURCE_SET_NAME) "embedded" else "${name}Embedded") {
isCanBeResolved = true
isCanBeConsumed = false
isVisible = false
attributes {
attribute(CATEGORY_ATTRIBUTE, objects.named(LIBRARY))
attribute(LIBRARY_ELEMENTS_ATTRIBUTE, jarElements)
}
)
}

fun extractedFiles(elements: LibraryElements) = config.incoming
.artifactView { attributes.attribute(LIBRARY_ELEMENTS_ATTRIBUTE, elements) }
.files

val classesDir = layout.buildDirectory.dir("embedded-dependencies/$name")
val classes = files()
.from(provider {
sync {
duplicatesStrategy = DuplicatesStrategy.WARN
config.asFileTree.forEach { from(zipTree(it)) }
into(classesDir)
include(spec.includes.get())
exclude(spec.excludes.get())
}
classesDir
})
.builtBy(config)
.apply { finalizeValueOnRead() }

configurations.named(compileOnlyConfigurationName) { extendsFrom(config) }

(output.classesDirs as ConfigurableFileCollection).from(classes)
dependencies.add(compileOnlyConfigurationName, extractedFiles(jarElements))
(output.classesDirs as ConfigurableFileCollection).from(extractedFiles(classesElements))
resources.srcDir(extractedFiles(resourcesElements))
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.github.gmazzo.dependencies.embedded

import org.gradle.api.artifacts.transform.InputArtifact
import org.gradle.api.artifacts.transform.TransformAction
import org.gradle.api.artifacts.transform.TransformOutputs
import org.gradle.api.artifacts.transform.TransformParameters
import org.gradle.api.file.ArchiveOperations
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.provider.Provider
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.work.DisableCachingByDefault
import javax.inject.Inject

@DisableCachingByDefault(because = "Not worth caching")
abstract class ExtractJARTransform @Inject constructor(
private val archiveOperations: ArchiveOperations,
private val fileOperations: FileSystemOperations,
) : TransformAction<ExtractJARTransform.Params> {

@get:PathSensitive(PathSensitivity.NAME_ONLY)
@get:InputArtifact
abstract val inputArtifact: Provider<FileSystemLocation>

override fun transform(outputs: TransformOutputs) {
val inputJar = inputArtifact.get().asFile
val suffix = if (parameters.forResources) "resources" else "classes"

fileOperations.sync {
from(archiveOperations.zipTree(inputJar).matching {
include(parameters.includes.get())
exclude(parameters.excludes.get())
})
into(outputs.dir("${inputJar.nameWithoutExtension}-$suffix"))
if (parameters.forResources) exclude("**.class") else include("**.class")
}
}

interface Params : TransformParameters {

@get:Input
var forResources: Boolean

@get:Input
val includes: SetProperty<String>

@get:Input
val excludes: SetProperty<String>

}

}

0 comments on commit 7c9ddcc

Please sign in to comment.