Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Gradle plugin: get routes via dedicated configurations to make the pl…
…ugin IP-safe
  • Loading branch information
ov7a committed Sep 16, 2026
commit 389fdce0a28c36d190d627e13e532afe667bc3f0
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
*/
package play.gradle.plugin;

import static org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE;
import static org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE;
import static org.gradle.api.plugins.JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME;
import static play.gradle.internal.Utils.filterProjectComponents;
import static play.gradle.internal.Utils.getDefaultPlayVersion;
import static play.gradle.internal.Utils.isGradleVersionLessThan;
import static play.gradle.internal.Utils.isPlayJava;
import static play.gradle.internal.Utils.isPlayProject;
import static play.gradle.internal.Utils.javaPluginExtension;
Expand All @@ -14,14 +17,16 @@
import static play.gradle.plugin.PlayPlugin.DEFAULT_SCALA_VERSION;
import static play.gradle.plugin.PlayPlugin.PLAY_GROUP_ID;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.gradle.api.Incubating;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.attributes.Attribute;
import org.gradle.api.attributes.Category;
import org.gradle.api.attributes.Usage;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.SourceDirectorySet;
import org.gradle.api.internal.tasks.DefaultSourceSet;
Expand All @@ -38,6 +43,13 @@ public class PlayRoutesPlugin implements Plugin<Project> {

public static final String ROUTES_SOURCE_NAME = "routes";

public static final String PLAY_ROUTES_USAGE = "play-routes";

public static final Attribute<String> SOURCE_SET_ATTRIBUTE =
Attribute.of("org.playframework.routes.sourceset", String.class);

private static final List<String> ROUTES_SOURCE_INCLUDES = List.of("routes", "*.routes");

private static final List<String> DEFAULT_SCALA_IMPORTS = List.of("controllers.Assets.Asset");

private static final List<String> DEFAULT_JAVA_IMPORTS =
Expand Down Expand Up @@ -120,18 +132,71 @@ private void configureSourceSetDefaults(
.all(
(sourceSet) -> {
SourceDirectorySet routesSource = createRoutesSourceDirectorySet(sourceSet);
createRoutesElementsConfiguration(project, sourceSet, routesSource);
Configuration aggregateRoutes =
createAggregateRoutesConfiguration(project, sourceSet);
TaskProvider<RoutesCompile> routesCompileTask =
createRoutesCompileTask(project, sourceSet, routesSource, routesConfiguration);
createRoutesCompileTask(
project, sourceSet, routesSource, routesConfiguration, aggregateRoutes);

scalaSourceDirectorySet(sourceSet).srcDir(routesCompileTask);
});
}

private void createRoutesElementsConfiguration(
final Project project, final SourceSet sourceSet, final SourceDirectorySet routesSource) {
Configuration conf =
project.getConfigurations().create(sourceSet.getTaskName(null, "playRoutesElements"));
conf.setDescription("Routes sources of the " + sourceSet.getName() + " source set.");
conf.setVisible(false);
conf.setCanBeConsumed(true);
conf.setCanBeResolved(false);
conf.getAttributes()
.attribute(USAGE_ATTRIBUTE, objectFactory.named(Usage.class, PLAY_ROUTES_USAGE))
.attribute(CATEGORY_ATTRIBUTE, objectFactory.named(Category.class, Category.LIBRARY))
.attribute(SOURCE_SET_ATTRIBUTE, sourceSet.getName());
// Source directories can still be added while the build script is evaluated
if (isGradleVersionLessThan("7.4")) {
// Publishing a lazily computed set of artifacts is not supported in Gradle < 7.4
project.afterEvaluate(
evaluated ->
routesSource.getSrcDirs().forEach(srcDir -> conf.getOutgoing().artifact(srcDir)));
} else {
conf.getOutgoing().artifacts(project.provider(routesSource::getSrcDirs));
}
}

private Configuration createAggregateRoutesConfiguration(
final Project project, final SourceSet sourceSet) {
Configuration conf =
project.getConfigurations().create(sourceSet.getTaskName(null, "playAggregateRoutes"));
conf.setDescription(
"Routes sources aggregated into the " + sourceSet.getName() + " source set.");
conf.setVisible(false);
conf.setCanBeConsumed(false);
conf.setCanBeResolved(true);
conf.setTransitive(false);
conf.getAttributes()
.attribute(USAGE_ATTRIBUTE, objectFactory.named(Usage.class, PLAY_ROUTES_USAGE))
.attribute(CATEGORY_ATTRIBUTE, objectFactory.named(Category.class, Category.LIBRARY))
.attribute(SOURCE_SET_ATTRIBUTE, sourceSet.getName());
conf.withDependencies(
dependencies ->
playExtension(project)
.getRoutes()
.getAggregateReverseRoutes()
.get()
.forEach(
aggregated -> dependencies.add(project.getDependencies().create(aggregated))));
return conf;
}

private TaskProvider<RoutesCompile> createRoutesCompileTask(
final Project project,
final SourceSet sourceSet,
SourceDirectorySet routesSource,
final Configuration routesConfiguration) {
final Configuration routesConfiguration,
final Configuration aggregateRoutes) {
return project
.getTasks()
.register(
Expand All @@ -142,14 +207,14 @@ private TaskProvider<RoutesCompile> createRoutesCompileTask(
routesCompile.setDescription("Compiles the " + routesSource + ".");
routesCompile.getRoutesCompilerClasspath().setFrom(routesConfiguration);
routesCompile.getSource().setFrom(routesSource);
var routesSources = new ArrayList<SourceDirectorySet>();
for (Project p : playExtension.getRoutes().getAggregateReverseRoutes().get()) {
var a = javaPluginExtension(p).getSourceSets().getByName(sourceSet.getName());
var projectRoutesSource =
(SourceDirectorySet) a.getExtensions().findByName(ROUTES_SOURCE_NAME);
if (projectRoutesSource != null) routesSources.add(projectRoutesSource);
}
routesCompile.getAggregateSource().setFrom(routesSources);
routesCompile
.getAggregateSource()
.setFrom(
aggregateRoutes
.getIncoming()
.getFiles()
.getAsFileTree()
.matching(pattern -> pattern.include(ROUTES_SOURCE_INCLUDES)));
routesCompile
.getGenerateReverseRouter()
.convention(playExtension.getRoutes().getGenerateReverseRouter());
Expand Down Expand Up @@ -177,7 +242,7 @@ private SourceDirectorySet createRoutesSourceDirectorySet(SourceSet sourceSet) {
SourceDirectorySet routesSource =
objectFactory.sourceDirectorySet(ROUTES_SOURCE_NAME, displayName + " Play Routes source");
routesSource.setSrcDirs(sourceSet.getResources().getSrcDirs());
routesSource.include("routes", "*.routes");
routesSource.include(ROUTES_SOURCE_INCLUDES);
sourceSet.getExtensions().add(SourceDirectorySet.class, ROUTES_SOURCE_NAME, routesSource);
return routesSource;
}
Expand Down