Skip to content

Commit f8f7dfe

Browse files
committed
Support bundles, keep provider dependencies lazy
Version bumped to 3.0.0 due to the heavily breaking binary and API changes. This was necessarily to progress ForgeGradle 7's development.
1 parent da41885 commit f8f7dfe

File tree

4 files changed

+76
-25
lines changed

4 files changed

+76
-25
lines changed

at-gradle/src/main/java/net/minecraftforge/accesstransformers/gradle/AccessTransformersContainer.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.File;
2525
import java.util.Arrays;
2626
import java.util.function.Function;
27+
import java.util.function.UnaryOperator;
2728

2829
/// Represents a container of dependencies that will be access transformed.
2930
///
@@ -83,7 +84,7 @@ default Dependency dep(Object dependencyNotation, Action<? super Dependency> act
8384
/// @param dependencyNotation The dependency (notation)
8485
/// @return The dependency to be transformed
8586
default Dependency dep(Object dependencyNotation) {
86-
return this.dep(dependencyNotation, Closures.empty(this));
87+
return this.dep(dependencyNotation, Closures.<Dependency>unaryOperator(this, UnaryOperator.identity()));
8788
}
8889

8990
/// Queues the given dependency to be transformed by AccessTransformers.
@@ -92,30 +93,28 @@ default Dependency dep(Object dependencyNotation) {
9293
/// @param closure A configuring closure for the dependency
9394
/// @return The dependency to be transformed
9495
@SuppressWarnings("rawtypes") // public-facing closure
95-
default Dependency dep(
96+
Provider<?> dep(
9697
Provider<?> dependencyNotation,
9798
@DelegatesTo(Dependency.class)
9899
@ClosureParams(value = SimpleType.class, options = "org.gradle.api.artifacts.Dependency")
99100
Closure closure
100-
) {
101-
return this.dep(dependencyNotation.get(), closure);
102-
}
101+
);
103102

104103
/// Queues the given dependency to be transformed by AccessTransformers.
105104
///
106105
/// @param dependencyNotation The dependency (notation)
107106
/// @param action A configuring action for the dependency
108107
/// @return The dependency to be transformed
109-
default Dependency dep(Provider<?> dependencyNotation, Action<? super Dependency> action) {
108+
default Provider<?> dep(Provider<?> dependencyNotation, Action<? super Dependency> action) {
110109
return this.dep(dependencyNotation, Closures.action(this, action));
111110
}
112111

113112
/// Queues the given dependency to be transformed by AccessTransformers.
114113
///
115114
/// @param dependencyNotation The dependency (notation)
116115
/// @return The dependency to be transformed
117-
default Dependency dep(Provider<?> dependencyNotation) {
118-
return this.dep(dependencyNotation, Closures.empty(this));
116+
default Provider<?> dep(Provider<?> dependencyNotation) {
117+
return this.dep(dependencyNotation, Closures.<Dependency>unaryOperator(this, UnaryOperator.identity()));
119118
}
120119

121120
/// Queues the given dependency to be transformed by AccessTransformers.
@@ -124,7 +123,7 @@ default Dependency dep(Provider<?> dependencyNotation) {
124123
/// @param closure A configuring closure for the dependency
125124
/// @return The dependency to be transformed
126125
@SuppressWarnings("rawtypes") // public-facing closure
127-
default Dependency dep(
126+
default Provider<?> dep(
128127
ProviderConvertible<?> dependencyNotation,
129128
@DelegatesTo(Dependency.class)
130129
@ClosureParams(value = SimpleType.class, options = "org.gradle.api.artifacts.Dependency")
@@ -138,16 +137,16 @@ default Dependency dep(
138137
/// @param dependencyNotation The dependency (notation)
139138
/// @param action A configuring action for the dependency
140139
/// @return The dependency to be transformed
141-
default Dependency dep(ProviderConvertible<?> dependencyNotation, Action<? super Dependency> action) {
140+
default Provider<?> dep(ProviderConvertible<?> dependencyNotation, Action<? super Dependency> action) {
142141
return this.dep(dependencyNotation, Closures.action(this, action));
143142
}
144143

145144
/// Queues the given dependency to be transformed by AccessTransformers.
146145
///
147146
/// @param dependencyNotation The dependency (notation)
148147
/// @return The dependency to be transformed
149-
default Dependency dep(ProviderConvertible<?> dependencyNotation) {
150-
return this.dep(dependencyNotation, Closures.empty(this));
148+
default Provider<?> dep(ProviderConvertible<?> dependencyNotation) {
149+
return this.dep(dependencyNotation, Closures.<Dependency>unaryOperator(this, UnaryOperator.identity()));
151150
}
152151

153152
/// When initially registering an AccessTransformers container, the consumer must define key information regarding
@@ -203,7 +202,7 @@ default void setClasspath(
203202
///
204203
/// @param dependencyNotation The dependency (notation) to use
205204
default void setClasspath(Object dependencyNotation) {
206-
this.setClasspath(dependencyNotation, Closures.empty(this));
205+
this.setClasspath(dependencyNotation, Closures.<Dependency>unaryOperator(this, UnaryOperator.identity()));
207206
}
208207

209208
/// Sets the dependency to use as the classpath for AccessTransformers.
@@ -235,7 +234,7 @@ default void setClasspath(
235234
///
236235
/// @param dependencyNotation The dependency (notation) to use
237236
default void setClasspath(Provider<?> dependencyNotation) {
238-
this.setClasspath(dependencyNotation, Closures.empty(this));
237+
this.setClasspath(dependencyNotation, Closures.<Dependency>unaryOperator(this, UnaryOperator.identity()));
239238
}
240239

241240
/// Sets the dependency to use as the classpath for AccessTransformers.
@@ -267,7 +266,7 @@ default void setClasspath(
267266
///
268267
/// @param dependencyNotation The dependency (notation) to use
269268
default void setClasspath(ProviderConvertible<?> dependencyNotation) {
270-
this.setClasspath(dependencyNotation, Closures.empty(this));
269+
this.setClasspath(dependencyNotation, Closures.<Dependency>unaryOperator(this, UnaryOperator.identity()));
271270
}
272271

273272
/// Sets the main class to invoke when running AccessTransformers.

at-gradle/src/main/java/net/minecraftforge/accesstransformers/gradle/AccessTransformersContainerImpl.java

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
import groovy.transform.stc.ClosureParams;
1010
import groovy.transform.stc.SimpleType;
1111
import net.minecraftforge.gradleutils.shared.Closures;
12+
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
1213
import org.gradle.api.Action;
1314
import org.gradle.api.PathValidation;
1415
import org.gradle.api.Project;
1516
import org.gradle.api.artifacts.Dependency;
17+
import org.gradle.api.artifacts.ExternalModuleDependencyBundle;
18+
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
1619
import org.gradle.api.artifacts.dsl.DependencyHandler;
1720
import org.gradle.api.artifacts.type.ArtifactTypeDefinition;
1821
import org.gradle.api.attributes.Attribute;
@@ -31,6 +34,8 @@
3134

3235
import javax.inject.Inject;
3336
import java.io.File;
37+
import java.io.Serial;
38+
import java.util.ArrayList;
3439
import java.util.Objects;
3540

3641
abstract class AccessTransformersContainerImpl implements AccessTransformersContainerInternal {
@@ -42,6 +47,7 @@ abstract class AccessTransformersContainerImpl implements AccessTransformersCont
4247
private final OptionsImpl options;
4348

4449
protected abstract @Inject ObjectFactory getObjects();
50+
protected abstract @Inject ProviderFactory getProviders();
4551

4652
@Inject
4753
public AccessTransformersContainerImpl(
@@ -107,20 +113,56 @@ public void options(Action<? super AccessTransformersContainer.Options> action)
107113
}
108114

109115
@Override
110-
@SuppressWarnings("rawtypes") // public-facing closure
116+
@SuppressWarnings("rawtypes")
111117
public Dependency dep(
112118
Object dependencyNotation,
113119
@DelegatesTo(Dependency.class)
114120
@ClosureParams(value = SimpleType.class, options = "org.gradle.api.artifacts.Dependency")
115121
Closure closure
116122
) {
117-
var dependency = project.getDependencies().create(dependencyNotation, closure);
118-
if (dependency instanceof HasConfigurableAttributes<?>) {
119-
((HasConfigurableAttributes<?>) dependency).attributes(a -> a.attribute(this.attribute, true));
123+
return this.project.getDependencies().create(dependencyNotation, closure.compose(Closures.<Dependency>unaryOperator(dependency -> {
124+
if (dependency instanceof HasConfigurableAttributes<?> d) {
125+
d.attributes(a -> a.attribute(this.attribute, true));
126+
} else {
127+
this.problems.reportIllegalTargetDependency(dependency);
128+
}
129+
130+
return dependency;
131+
})));
132+
}
133+
134+
@Override
135+
@SuppressWarnings("rawtypes")
136+
public Provider<?> dep(
137+
Provider<?> dependencyNotation,
138+
@DelegatesTo(Dependency.class)
139+
@ClosureParams(value = SimpleType.class, options = "org.gradle.api.artifacts.Dependency")
140+
Closure closure
141+
) {
142+
if (dependencyNotation.isPresent() && dependencyNotation.get() instanceof ExternalModuleDependencyBundle bundle) {
143+
// this provider MUST return ExternalModuleDependencyBundle
144+
// The only way to coerce the type of it is to use a property, since we can set the type manually on creation.
145+
// ProviderInternal#getType uses the generic argument to determine what type it is.
146+
// Provider#map and #flatMap do NOT preserve the resultant type, which fucks with adding bundles to configurations.
147+
return this.getObjects().property(ExternalModuleDependencyBundle.class).value(this.getProviders().provider(
148+
() -> DefaultGroovyMethods.collect(
149+
bundle,
150+
new MappedExternalModuleDependencyBundle(),
151+
Closures.unaryOperator(d -> (MinimalExternalModuleDependency) this.dep(d, closure))
152+
)
153+
));
120154
} else {
121-
this.problems.reportIllegalTargetDependency(dependency);
155+
// Rationale: single dependencies may have additional data that must be calculated at configuration time
156+
// The most obvious example being usage of DependencyHandler#variantOf.
157+
// If the dependency isn't created immediately, that information is lost when copying the base dependency (i don't know why)
158+
// It's a rather negligible performance hit and FG6 was already doing this anyway, so it's not a big deal.
159+
// Still going to return a Provider<?> though, since we also handle bundles in this method
160+
return this.getObjects().property(Dependency.class).value(dependencyNotation.map(d -> this.dep(d, closure)));
122161
}
123-
return dependency;
162+
}
163+
164+
private static class MappedExternalModuleDependencyBundle extends ArrayList<MinimalExternalModuleDependency> implements ExternalModuleDependencyBundle {
165+
private static final @Serial long serialVersionUID = -5641567719847374245L;
124166
}
125167

126168
static abstract class OptionsImpl implements AccessTransformersContainerInternal.Options {

at-gradle/src/main/java/net/minecraftforge/accesstransformers/gradle/AccessTransformersExtensionImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.gradle.api.Project;
1313
import org.gradle.api.artifacts.Dependency;
1414
import org.gradle.api.attributes.Attribute;
15+
import org.gradle.api.provider.Provider;
1516
import org.jetbrains.annotations.Nullable;
1617

1718
import javax.inject.Inject;
@@ -63,4 +64,15 @@ public Dependency dep(
6364
) {
6465
return this.getContainer().dep(dependencyNotation, closure);
6566
}
67+
68+
@Override
69+
@SuppressWarnings("rawtypes") // public-facing closure
70+
public Provider<?> dep(
71+
Provider<?> dependencyNotation,
72+
@DelegatesTo(Dependency.class)
73+
@ClosureParams(value = SimpleType.class, options = "org.gradle.api.artifacts.Dependency")
74+
Closure closure
75+
) {
76+
return this.getContainer().dep(dependencyNotation, closure);
77+
}
6678
}

at-gradle/src/main/java/net/minecraftforge/accesstransformers/gradle/Constants.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44
*/
55
package net.minecraftforge.accesstransformers.gradle;
66

7-
import java.util.Arrays;
8-
import java.util.Collections;
97
import java.util.List;
108

119
final class Constants {
1210
private Constants() { }
1311

14-
static final List<String> AT_DEFAULT_ARGS = Collections.unmodifiableList(Arrays.asList(
12+
static final List<String> AT_DEFAULT_ARGS = List.of(
1513
"--inJar", "{inJar}",
1614
"--atFile", "{atFile}",
1715
"--outJar", "{outJar}",
1816
"--logFile", "{logFile}"
19-
));
17+
);
2018
}

0 commit comments

Comments
 (0)