Skip to content

Commit 342d27d

Browse files
committed
feat: allow for specifying ATs for upstream sources
These changes provide fork developers with a way to specify an AT file (or have it detected automatically) for upstream sources, such as `paper-server` and `paper-api` for a fork of Paper. This allows fork developers to benefit from using ATs while modifying these sources without needing to clutter patches, with lots of manual access transforms, and as such this greatly improves the overall comfort of making more involving changes, in the sources. It also allows for fork devs to be able to organize ATs in one place which makes it easier to review later. The implementation proposed in this commit works as follows: 1. Derive the location of the build-data dir from the output dir specified in the PatchRepo/Directory's config. 2. Search for an AT file, by the name of the patch repo/directory as specified. 3. Apply them before applying source patches. The locations in steps 1 and 2 can be overriden per patch repo/directory by just overriding the val. In order to achieve this change, we introduce a new task, with its implementation sitting in SetupForkUpstreamSources which applies those ATs. Everything else not explained here or even explained should follow the behaviour of AT application for minecraft sources. The change has been tested in production in an organisation fork of paperweight for over 6 months with both a nested fork project that uses them heavily and then fork projects depending on the nested fork project, and no issues have been reported or arose, so i'm confident that this implementation will work properly.
1 parent 3a4e5d7 commit 342d27d

4 files changed

Lines changed: 133 additions & 2 deletions

File tree

paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/UpstreamConfig.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import org.gradle.api.model.ObjectFactory
3535
import org.gradle.api.provider.ListProperty
3636
import org.gradle.api.provider.Property
3737
import org.gradle.api.provider.Provider
38+
import org.gradle.api.provider.ProviderFactory
3839
import org.gradle.api.provider.SetProperty
3940
import org.gradle.kotlin.dsl.*
4041

@@ -93,6 +94,7 @@ abstract class UpstreamConfig @Inject constructor(
9394

9495
abstract class DirectoryPatchSet @Inject constructor(
9596
objects: ObjectFactory,
97+
providers: ProviderFactory,
9698
private val setName: String,
9799
) : Named {
98100
override fun getName(): String = setName
@@ -101,6 +103,8 @@ abstract class UpstreamConfig @Inject constructor(
101103
abstract val excludes: SetProperty<String>
102104

103105
abstract val outputDir: DirectoryProperty
106+
val buildDataDir: DirectoryProperty = objects.directoryProperty().convention(outputDir.dir("../build-data"))
107+
val additionalAts: RegularFileProperty = objects.fileFrom(buildDataDir, providers.provider { "$name.at" })
104108

105109
abstract val patchesDir: DirectoryProperty
106110
val rejectsDir: DirectoryProperty = objects.dirFrom(patchesDir, "rejected")
@@ -110,8 +114,9 @@ abstract class UpstreamConfig @Inject constructor(
110114

111115
abstract class RepoPatchSet @Inject constructor(
112116
objects: ObjectFactory,
117+
providers: ProviderFactory,
113118
name: String,
114-
) : DirectoryPatchSet(objects, name) {
119+
) : DirectoryPatchSet(objects, providers, name) {
115120
abstract val upstreamRepo: Property<DirectoryPatchSet>
116121

117122
fun Provider<ForkConfig>.patchedRepo(name: String): Provider<DirectoryPatchSet> =

paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/PatchingTasks.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,22 @@
2222

2323
package io.papermc.paperweight.core.taskcontainers
2424

25+
import io.papermc.paperweight.core.tasks.SetupForkUpstreamSources
2526
import io.papermc.paperweight.core.tasks.patching.ApplyFeaturePatches
2627
import io.papermc.paperweight.core.tasks.patching.ApplyFilePatches
2728
import io.papermc.paperweight.core.tasks.patching.ApplyFilePatchesFuzzy
2829
import io.papermc.paperweight.core.tasks.patching.FixupFilePatches
2930
import io.papermc.paperweight.core.tasks.patching.RebuildFilePatches
3031
import io.papermc.paperweight.tasks.*
3132
import io.papermc.paperweight.util.*
33+
import io.papermc.paperweight.util.constants.JST_CONFIG
3234
import io.papermc.paperweight.util.constants.paperTaskOutput
3335
import java.nio.file.Path
3436
import org.gradle.api.Project
3537
import org.gradle.api.Task
3638
import org.gradle.api.file.Directory
3739
import org.gradle.api.file.DirectoryProperty
40+
import org.gradle.api.file.RegularFileProperty
3841
import org.gradle.api.provider.Provider
3942
import org.gradle.api.tasks.TaskContainer
4043
import org.gradle.kotlin.dsl.*
@@ -48,6 +51,7 @@ class PatchingTasks(
4851
private val filePatchDir: DirectoryProperty,
4952
private val rejectsDir: DirectoryProperty,
5053
private val featurePatchDir: DirectoryProperty,
54+
private val additionalAts: RegularFileProperty,
5155
private val baseDir: Provider<Directory>,
5256
private val gitFilePatches: Provider<Boolean>,
5357
private val filterPatches: Provider<Boolean>,
@@ -110,6 +114,40 @@ class PatchingTasks(
110114
}
111115
}
112116

117+
fun setupUpstream() {
118+
val collectAccessTransform = tasks.register<CollectATsFromPatches>("collect${namePart}ATsFromPatches") {
119+
patchDir.set(this@PatchingTasks.featurePatchDir.fileExists())
120+
}
121+
122+
val mergeCollectedAts = tasks.register<MergeAccessTransforms>("merge${namePart}ATs") {
123+
firstFile.set(additionalAts.fileExists())
124+
secondFile.set(collectAccessTransform.flatMap { it.outputFile })
125+
}
126+
127+
val setup = tasks.register<SetupForkUpstreamSources>("run${namePart}Setup") {
128+
description = "Applies $forkName ATs to $namePart sources"
129+
inputDir.set(baseDir)
130+
outputDir.set(layout.cache.resolve(paperTaskOutput()))
131+
identifier.set(namePart)
132+
atFile.set(mergeCollectedAts.flatMap { it.outputFile })
133+
ats.jst.from(project.configurations.named(JST_CONFIG))
134+
}
135+
136+
applyFilePatches.configure {
137+
input.set(setup.flatMap { it.outputDir })
138+
}
139+
140+
applyFilePatchesFuzzy.configure {
141+
input.set(setup.flatMap { it.outputDir })
142+
}
143+
val name = "rebuild${namePart}FilePatches"
144+
if (name in tasks.names) {
145+
tasks.named<RebuildFilePatches>(name) {
146+
base.set(setup.flatMap { it.outputDir })
147+
}
148+
}
149+
}
150+
113151
private fun setupWritable() {
114152
listOf(
115153
applyFilePatches,

paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/UpstreamConfigTasks.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class UpstreamConfigTasks(
118118
createBaseFromDirectoryInRepo(cfg)
119119
}
120120

121-
return PatchingTasks(
121+
val tasks = PatchingTasks(
122122
target,
123123
forkName,
124124
cfg.name,
@@ -127,11 +127,14 @@ class UpstreamConfigTasks(
127127
cfg.filePatchDir,
128128
cfg.rejectsDir,
129129
cfg.featurePatchDir,
130+
cfg.additionalAts,
130131
base,
131132
gitFilePatches,
132133
filterPatches,
133134
cfg.outputDir.path,
134135
)
136+
tasks.setupUpstream()
137+
return tasks
135138
}
136139

137140
private fun createBaseFromRepo(cfg: UpstreamConfig.RepoPatchSet): Provider<Directory> {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* paperweight is a Gradle plugin for the PaperMC project.
3+
*
4+
* Copyright (c) 2023 Kyle Wood (DenWav)
5+
* Contributors
6+
*
7+
* This library is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU Lesser General Public
9+
* License as published by the Free Software Foundation;
10+
* version 2.1 only, no later versions.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20+
* USA
21+
*/
22+
23+
package io.papermc.paperweight.core.tasks
24+
25+
import io.papermc.paperweight.core.util.ApplySourceATs
26+
import io.papermc.paperweight.tasks.*
27+
import io.papermc.paperweight.util.*
28+
import kotlin.io.path.*
29+
import org.eclipse.jgit.api.Git
30+
import org.eclipse.jgit.lib.PersonIdent
31+
import org.gradle.api.file.DirectoryProperty
32+
import org.gradle.api.file.RegularFileProperty
33+
import org.gradle.api.provider.Property
34+
import org.gradle.api.tasks.Input
35+
import org.gradle.api.tasks.InputDirectory
36+
import org.gradle.api.tasks.InputFile
37+
import org.gradle.api.tasks.Nested
38+
import org.gradle.api.tasks.Optional
39+
import org.gradle.api.tasks.OutputDirectory
40+
import org.gradle.api.tasks.TaskAction
41+
import org.gradle.kotlin.dsl.*
42+
43+
abstract class SetupForkUpstreamSources : JavaLauncherTask() {
44+
45+
@get:InputDirectory
46+
abstract val inputDir: DirectoryProperty
47+
48+
@get:OutputDirectory
49+
abstract val outputDir: DirectoryProperty
50+
51+
@get:Nested
52+
val ats: ApplySourceATs = objects.newInstance()
53+
54+
@get:InputFile
55+
@get:Optional
56+
abstract val atFile: RegularFileProperty
57+
58+
@get:Input
59+
abstract val identifier: Property<String>
60+
61+
@TaskAction
62+
fun run() {
63+
val out = outputDir.path.cleanDir()
64+
inputDir.path.copyRecursivelyTo(out)
65+
66+
val git = Git.open(outputDir.path.toFile())
67+
68+
if (atFile.isPresent && atFile.path.readText().isNotBlank()) {
69+
println("Applying access transformers...")
70+
ats.run(
71+
launcher.get(),
72+
inputDir.path,
73+
outputDir.path,
74+
atFile.path,
75+
temporaryDir.toPath(),
76+
)
77+
commitAndTag(git, "ATs", "${identifier.get()} ATs")
78+
}
79+
val ident = PersonIdent("base", "noreply+automated@papermc.io")
80+
git.tagDelete().setTags("base").call()
81+
git.tag().setName("base").setTagger(ident).setSigned(false).call()
82+
83+
git.close()
84+
}
85+
}

0 commit comments

Comments
 (0)