Skip to content

Commit

Permalink
add mechanism for downgrading dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed May 29, 2024
1 parent f074d52 commit aa5d39d
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 13 deletions.
2 changes: 2 additions & 0 deletions gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ tasks.getByName<Jar>("sourcesJar") {
isReproducibleFileOrder = true
}

signing.isRequired = !project.hasProperty("is_local")

gradlePlugin {
website = metadata.url
vcsUrl = metadata.github.get().vcsUrl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ package xyz.wagyourtail.jvmdg.gradle

import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Attribute
import org.gradle.jvm.tasks.Jar
import org.jetbrains.annotations.ApiStatus
import xyz.wagyourtail.jvmdg.ClassDowngrader
import xyz.wagyourtail.jvmdg.cli.Flags
import xyz.wagyourtail.jvmdg.compile.ZipDowngrader
import xyz.wagyourtail.jvmdg.gradle.task.DowngradeJar
import xyz.wagyourtail.jvmdg.gradle.task.ShadeAPI
import xyz.wagyourtail.jvmdg.gradle.transform.DowngradeTransform
import xyz.wagyourtail.jvmdg.gradle.transform.ShadeTransform
import xyz.wagyourtail.jvmdg.util.FinalizeOnRead
import xyz.wagyourtail.jvmdg.util.LazyMutable
import xyz.wagyourtail.jvmdg.util.defaultedMapOf
Expand Down Expand Up @@ -69,4 +73,66 @@ abstract class JVMDowngraderExtension(val project: Project) {

fun getDowngradedApi(version: JavaVersion): File = downgradedApis[version]

var depDgVersion by FinalizeOnRead(JavaVersion.VERSION_1_8)

val downgradeAttribute by lazy {
val artifactType = Attribute.of("artifactType", String::class.java)
val downgrade = Attribute.of("downgrade", Boolean::class.javaObjectType)

project.dependencies.apply {
attributesSchema {
it.attribute(downgrade)
}
artifactTypes.getByName("jar") {
it.attributes.attribute(downgrade, false)
}
registerTransform(DowngradeTransform::class.java) { spec ->
spec.from.attribute(artifactType, "jar").attribute(downgrade, false)
spec.to.attribute(artifactType, "jar").attribute(downgrade, true)

spec.parameters {
it.downgradeTo.set(depDgVersion)
it.apiJar.set(apiJar)
}
}
}

downgrade
}

val shadeAttribute by lazy {
val artifactType = Attribute.of("artifactType", String::class.java)
val downgrade = Attribute.of("shadeDowngraded", Boolean::class.javaObjectType)

project.dependencies.apply {
attributesSchema {
it.attribute(downgrade)
}
artifactTypes.getByName("jar") {
it.attributes.attribute(downgrade, false)
}
registerTransform(ShadeTransform::class.java) { spec ->
spec.from.attribute(artifactType, "jar").attribute(downgrade, false).attribute(downgradeAttribute, true)
spec.to.attribute(artifactType, "jar").attribute(downgrade, true)

spec.parameters {
it.downgradeTo.set(depDgVersion)
it.apiJar.set(downgradedApis[depDgVersion]!!)
}
}
}

downgrade
}

@JvmOverloads
fun dg(dep: Configuration, shade: Boolean = true) {
dep.attributes {
it.attribute(downgradeAttribute, true)
if (shade) {
it.attribute(shadeAttribute, true)
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ import xyz.wagyourtail.jvmdg.cli.Flags
import xyz.wagyourtail.jvmdg.compile.PathDowngrader
import xyz.wagyourtail.jvmdg.gradle.JVMDowngraderExtension
import xyz.wagyourtail.jvmdg.util.*
import java.io.File
import java.nio.file.FileSystem
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.name

abstract class DowngradeFiles : ConventionTask() {
private val jvmdg by lazy {

@get:Internal
protected val jvmdg by lazy {
project.extensions.getByType(JVMDowngraderExtension::class.java)
}

Expand All @@ -27,21 +30,34 @@ abstract class DowngradeFiles : ConventionTask() {
var downgradeTo by FinalizeOnRead(JavaVersion.VERSION_1_8)

@get:InputFiles
var toDowngrade: FileCollection by FinalizeOnRead(MustSet())
open var toDowngrade: FileCollection by FinalizeOnRead(MustSet())

@get:InputFiles
var classpath: FileCollection by FinalizeOnRead(LazyMutable {
project.extensions.getByType(SourceSetContainer::class.java).getByName("main").runtimeClasspath
})

@get:Internal
val outputMap: Map<File, File>
get() = toDowngrade.associateWith { temporaryDir.resolve(it.name) }

/**
* this is the output, gradle just doesn't have a
* this is the true output, gradle just doesn't have a
* \@OutputDirectoriesAndFiles
*/
@get:Internal
val outputCollection: FileCollection by lazy {
project.files(toDowngrade.map { temporaryDir.resolve(it.name) })
}
val outputCollection: FileCollection
get() = project.files(toDowngrade.map { temporaryDir.resolve(it.name) })

@get:OutputFiles
@get:ApiStatus.Internal
val outputFiles: FileCollection
get() = outputCollection.filter { it.isFile }

@get:OutputDirectories
@get:ApiStatus.Internal
val outputDirectories: FileCollection
get() = outputCollection.filter { it.isDirectory }

@get:Input
@get:Optional
Expand All @@ -60,7 +76,7 @@ abstract class DowngradeFiles : ConventionTask() {

@TaskAction
fun doDowngrade() {
var toDowngrade = toDowngrade.files.map { it.toPath() }.filter { it.exists() }
var toDowngrade = toDowngrade.map { it.toPath() }.filter { it.exists() }
val classpath = classpath.files

val fileSystems = mutableSetOf<FileSystem>()
Expand Down Expand Up @@ -98,5 +114,8 @@ abstract class DowngradeFiles : ConventionTask() {
}
}

fun forInputs(files: Set<File>): FileCollection {
return project.files(outputMap.filterKeys { it in files }.values)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package xyz.wagyourtail.jvmdg.gradle.transform

import org.gradle.api.JavaVersion
import org.gradle.api.artifacts.transform.TransformParameters
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import xyz.wagyourtail.jvmdg.cli.Flags
import xyz.wagyourtail.jvmdg.util.toOpcode
import java.io.File

abstract class DowngradeFlags : TransformParameters {

@get:Input
@get:Optional
abstract val downgradeTo: Property<JavaVersion>

@get:Input
abstract val apiJar: Property<File>

@get:Input
@get:Optional
abstract val quiet: Property<Boolean>

@get:Input
@get:Optional
abstract val debug: Property<Boolean>

@get:Input
@get:Optional
abstract val debugSkipStubs: SetProperty<JavaVersion>

init {
downgradeTo.convention(JavaVersion.VERSION_1_8)
quiet.convention(false)
debug.convention(false)
debugSkipStubs.convention(emptySet())
}
}

fun DowngradeFlags.toFlags(): Flags {
val flags = Flags()
flags.api = apiJar.get()
flags.printDebug = debug.get()
flags.quiet = quiet.get()
flags.classVersion = downgradeTo.get().toOpcode()
flags.debugSkipStubs = debugSkipStubs.get().map { it.toOpcode() }.toSet()
return flags
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package xyz.wagyourtail.jvmdg.gradle.transform

import org.gradle.api.artifacts.transform.CacheableTransform
import org.gradle.api.artifacts.transform.InputArtifact
import org.gradle.api.artifacts.transform.InputArtifactDependencies
import org.gradle.api.artifacts.transform.TransformAction
import org.gradle.api.artifacts.transform.TransformOutputs
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.CompileClasspath
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import xyz.wagyourtail.jvmdg.ClassDowngrader
import xyz.wagyourtail.jvmdg.compile.ZipDowngrader

@CacheableTransform
abstract class DowngradeTransform : TransformAction<DowngradeFlags> {

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

@get:Classpath
@get:InputArtifactDependencies
abstract val dependencies: FileCollection

override fun transform(outputs: TransformOutputs) {
val input = input.get().asFile
val flags = parameters
val output = outputs.file("${input.nameWithoutExtension}-downgraded-${flags.downgradeTo.get()}.${input.extension}")
val classpath = dependencies.files

ClassDowngrader.downgradeTo(flags.toFlags()).use {
ZipDowngrader.downgradeZip(it, input.toPath(), classpath.map { it.toURI().toURL() }.toSet(), output.toPath())
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package xyz.wagyourtail.jvmdg.gradle.transform

import org.gradle.api.artifacts.transform.CacheableTransform
import org.gradle.api.artifacts.transform.InputArtifact
import org.gradle.api.artifacts.transform.InputArtifactDependencies
import org.gradle.api.artifacts.transform.TransformAction
import org.gradle.api.artifacts.transform.TransformOutputs
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.CompileClasspath
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import xyz.wagyourtail.jvmdg.ClassDowngrader
import xyz.wagyourtail.jvmdg.compile.ApiShader
import xyz.wagyourtail.jvmdg.compile.ZipDowngrader

@CacheableTransform
abstract class ShadeTransform : TransformAction<DowngradeFlags> {

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

override fun transform(outputs: TransformOutputs) {
val input = input.get().asFile
val flags = parameters
val output = outputs.file("${input.nameWithoutExtension}-shaded-${flags.downgradeTo.get()}.${input.extension}")

ApiShader.shadeApis(flags.toFlags(), input.nameWithoutExtension, input, output, flags.apiJar.get())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,6 @@ fun JavaVersion.toOpcode(): Int = when (this) {
JavaVersion.VERSION_21 -> Opcodes.V21
JavaVersion.VERSION_22 -> Opcodes.V22
else -> throw IllegalArgumentException("Unsupported Java Version: $this")
}
}

fun safeName(name: String): String = name.replace(Regex("[.;\\[/]"), "-")
11 changes: 11 additions & 0 deletions gradle-plugin/test-downgrade/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import xyz.wagyourtail.jvmdg.gradle.JVMDowngraderExtension
import xyz.wagyourtail.jvmdg.gradle.task.DowngradeJar
import xyz.wagyourtail.jvmdg.gradle.task.ShadeAPI
import java.util.*
Expand Down Expand Up @@ -75,10 +76,20 @@ sourceSets {
}
}

val jvmdg = extensions.getByType(JVMDowngraderExtension::class.java)
val downgrade by configurations.creating
jvmdg.dg(downgrade)

dependencies {
implementation("org.jetbrains:annotations-java5:24.1.0")

// first thing I could think of that's not java 8
downgrade("com.github.javakeyring:java-keyring:1.0.4")

implementation(files(downgrade.files))
}


val downgradeJar9 by tasks.creating(DowngradeJar::class) {
inputFile.set(tasks.jar.get().archiveFile)
archiveClassifier.set("downgraded-9")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ kotlin.code.style=official
org.gradle.jvmargs=-Xmx4G
org.gradle.parallel=true

version=0.5.1
version=0.6.0

asm_version=9.7

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ public byte[] apply(String s) {
}
}
} else {
// strip signatures since downgraded classes will not have the same signatures
if (path.toString().startsWith("META-INF/") && (path.toString().endsWith(".SF") || path.toString().endsWith(".DSA") || path.toString().endsWith(".RSA"))) {
return;
}
Files.copy(path, outFile, StandardCopyOption.REPLACE_EXISTING);
}
}
Expand Down

0 comments on commit aa5d39d

Please sign in to comment.