-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
ApplySourceAT.kt
135 lines (115 loc) · 4.55 KB
/
ApplySourceAT.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* paperweight is a Gradle plugin for the PaperMC project.
*
* Copyright (c) 2023 Kyle Wood (DenWav)
* Contributors
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 only, no later versions.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package io.papermc.paperweight.tasks.softspoon
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.restamp.Restamp
import io.papermc.restamp.RestampContextConfiguration
import io.papermc.restamp.RestampInput
import java.nio.file.Files
import javax.inject.Inject
import kotlin.io.path.*
import org.cadixdev.at.io.AccessTransformFormats
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.*
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor
import org.openrewrite.InMemoryExecutionContext
@CacheableTask
abstract class ApplySourceAT : BaseTask() {
@get:Classpath
abstract val inputJar: RegularFileProperty
@get:OutputFile
abstract val outputJar: RegularFileProperty
@get:Optional
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val atFile: RegularFileProperty
@get:Optional
@get:CompileClasspath
abstract val minecraftClasspath: ConfigurableFileCollection
@get:Inject
abstract val worker: WorkerExecutor
override fun init() {
outputJar.convention(defaultOutput())
}
@TaskAction
fun run() {
val queue = worker.processIsolation {
forkOptions {
maxHeapSize = "2G"
}
}
val classPath = minecraftClasspath.files.map { it.toPath() }.toMutableList()
classPath.add(inputJar.convertToPath())
queue.submit(RestampWorker::class) {
minecraftClasspath.from(minecraftClasspath)
atFile.set(atFile)
inputJar.set(inputJar)
outputJar.set(outputJar)
}
}
}
abstract class RestampWorker : WorkAction<RestampWorker.Params> {
interface Params : WorkParameters {
val minecraftClasspath: ConfigurableFileCollection
val atFile: RegularFileProperty
val inputJar: RegularFileProperty
val outputJar: RegularFileProperty
}
override fun execute() {
val inputZip = parameters.inputJar.convertToPath().openZip()
val classPath = parameters.minecraftClasspath.files.map { it.toPath() }.toMutableList()
classPath.add(parameters.inputJar.convertToPath())
val configuration = RestampContextConfiguration.builder()
.accessTransformers(parameters.atFile.convertToPath(), AccessTransformFormats.FML)
.sourceRoot(inputZip.getPath("/"))
.sourceFilesFromAccessTransformers()
.classpath(classPath)
.executionContext(InMemoryExecutionContext { it.printStackTrace() })
.failWithNotApplicableAccessTransformers()
.build()
val parsedInput = RestampInput.parseFrom(configuration)
val results = Restamp.run(parsedInput).allResults
parameters.outputJar.convertToPath().writeZip().use { zip ->
val alreadyWritten = mutableSetOf<String>()
results.forEach { result ->
if (result.after == null) {
println("Ignoring ${result.before?.sourcePath} because result.after is null?")
return@forEach
}
result.after?.let { after ->
zip.getPath(after.sourcePath.toString()).writeText(after.printAll())
alreadyWritten.add("/" + after.sourcePath.toString())
}
}
inputZip.walk().filter { Files.isRegularFile(it) }.filter { !alreadyWritten.contains(it.toString()) }.forEach { file ->
zip.getPath(file.toString()).writeText(file.readText())
}
zip.close()
}
inputZip.close()
}
}