So here is an example of the DSL fragment:
jakartaTransformation {
...
dependencyResolutions {
dependencySubstitution {
substitute module( project.jpa ) with module( project.jakartaJpa )
substitute module( project.jta ) with module( project.jakartaJta )
}
}
shadow('org.hibernate.orm:hibernate-core:6.0.0.Alpha7') {
runTests( 'org.hibernate.orm:hibernate-core:6.0.0.Alpha7:tests' ) {
include 'org/hibernate/orm/test/**'
}
}
}
The extension registered under jakartaTransformation
is (short-form):
interface TransformerSpec {
void dependencyResolutions(Closure config);
void dependencyResolutions(Action<ResolutionStrategy> config);
void shadow(Object shadowSource, Closure config);
void shadow(Object shadowSource, Action<ShadowSpec> config);
}
interface ShadowSpec {
void runTests(Object testsDependencyNotation, Action<ShadowTestSpec> config);
void runTests(Object testsDependencyNotation, Closure config);
}
The shadow
and runTests
blocks each create a detached configuration. But as you can see, they are created at a time when I no longer have reference to the substitutions.
Now granted, I could do this (which is effectively the same):
jakartaTransformation {
...
shadow('org.hibernate.orm:hibernate-core:6.0.0.Alpha7') {
dependencyResolutions {
dependencySubstitution {
substitute module( project.jpa ) with module( project.jakartaJpa )
substitute module( project.jta ) with module( project.jakartaJta )
}
}
runTests( 'org.hibernate.orm:hibernate-core:6.0.0.Alpha7:tests' ) {
include 'org/hibernate/orm/test/**'
dependencyResolutions {
dependencySubstitution {
substitute module( project.jpa ) with module( project.jakartaJpa )
substitute module( project.jta ) with module( project.jakartaJta )
}
}
}
}
}
Though hopefully you can see why I’d rather refactor that into commonality.
The only option I could come up with so far was to keep the substitution Closure/Action around to use later:
class TransformerSpecImpl implements TransformerSpec {
...
private final List<Substitutions> substitutions = new ArrayList<>();
@Override
public void dependencyResolutions(Closure config) {
project.getConfigurations().all(
(configuration) -> ConfigureUtil.configure( config, configuration.getResolutionStrategy() )
);
substitutions.add(
(resolutionStrategy) -> ConfigureUtil.configure( config, resolutionStrategy )
);
}
public void applyDependencyResolutionStrategy(Configuration configuration) {
for ( Substitutions substitution : substitutions ) {
substitution.applySubstitutions( configuration.getResolutionStrategy() );
}
}
...
@FunctionalInterface
public interface Substitutions {
void applySubstitutions(ResolutionStrategy resolutionStrategy);
}
}
Later, when creating the detached Configurations I can access these substitutions
and apply them:
sourceDependencyConfiguration = getProject().getConfigurations().detachedConfiguration( ... );
applyDependencyResolutionStrategy( sourceDependencyConfiguration );
It works. Just not sure whether holding on to those Closures/Actions references has negative side effects. Hence my questions