# HG changeset patch # User cin # Date 2024-06-08 00:45:24 # Node ID 0570d8f0a5a8f78d57aedbf56383d99f66a1bfb3 # Parent e91c2403acf8f1e0e8774fb3975971bc58354d83 WIP Added task traits diff --git a/common/src/main/java/org/implab/gradle/common/ProjectMixin.java b/common/src/main/java/org/implab/gradle/common/ProjectMixin.java --- a/common/src/main/java/org/implab/gradle/common/ProjectMixin.java +++ b/common/src/main/java/org/implab/gradle/common/ProjectMixin.java @@ -9,17 +9,19 @@ import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.Directory; -import org.gradle.api.tasks.TaskProvider; +import org.implab.gradle.common.dsl.TaskSpec; +import org.implab.gradle.common.dsl.TasksMixin; import org.implab.gradle.common.utils.ExtraProps; /** Project configuration traits */ -public interface ProjectMixin { +public interface ProjectMixin extends TasksMixin { @Inject Project getProject(); - /** registers the new task */ - default TaskProvider task(String name, Class clazz, Action configure) { - return getProject().getTasks().register(name, clazz, configure); + @Override + default TaskSpec task(String name, Class clazz) { + var provider = getProject().getTasks().register(name, clazz); + return new TaskSpec<>(provider); } /** Registers the new configuration */ diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskGroup.java b/common/src/main/java/org/implab/gradle/common/dsl/TaskGroup.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/dsl/TaskGroup.java @@ -0,0 +1,25 @@ +package org.implab.gradle.common.dsl; + +import java.util.Objects; + +import org.gradle.api.Task; +import org.gradle.api.tasks.TaskContainer; + +public abstract class TaskGroup implements TasksMixin { + private final String groupName; + + protected abstract TaskContainer tasks(); + + public TaskGroup(String name) { + Objects.requireNonNull(name, "The group name is required"); + this.groupName = name; + } + + @Override + public TaskSpec task(String taskName, Class clazz) { + var provider = tasks().register(taskName, clazz); + provider.configure(t -> t.setGroup(groupName)); + return new TaskSpec<>(provider); + } + +} diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskReference.java b/common/src/main/java/org/implab/gradle/common/dsl/TaskReference.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/dsl/TaskReference.java @@ -0,0 +1,22 @@ +package org.implab.gradle.common.dsl; + +import org.gradle.api.Buildable; +import org.gradle.api.tasks.TaskProvider; + +public interface TaskReference { + + Object reference(); + + public static TaskReference named(String name) { + return () -> name; + } + + public static TaskReference provider(TaskProvider provider) { + return () -> provider; + } + + public static TaskReference buildable(Buildable dependency) { + return () -> dependency; + } + +} diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java b/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java @@ -0,0 +1,54 @@ +package org.implab.gradle.common.dsl; + +import java.util.stream.Stream; + +import org.gradle.api.Action; +import org.gradle.api.Task; +import org.gradle.api.tasks.TaskProvider; + +public class TaskSpec implements TaskReference { + private final TaskProvider taskProvider; + + public TaskSpec(TaskProvider taskProvider) { + this.taskProvider = taskProvider; + } + + public TaskSpec configure(Action configure) { + taskProvider.configure(configure); + return this; + } + + public TaskSpec dependsOn(TaskReference... other) { + taskProvider.configure(t -> t.dependsOn(references(other))); + return this; + } + + public TaskSpec finalizedBy(TaskReference... other) { + taskProvider.configure(t -> t.finalizedBy(references(other))); + return this; + } + + public TaskSpec mustRunAfter(TaskReference... other) { + taskProvider.configure(t -> t.mustRunAfter(references(other))); + return this; + } + + public TaskSpec doLast(Action action) { + taskProvider.configure(t -> t.doLast(self -> action.execute(t))); + return this; + } + + public TaskSpec doFirst(Action action) { + taskProvider.configure(t -> t.doFirst(self -> action.execute(t))); + return this; + } + + @Override + public Object reference() { + return taskProvider; + } + + private static Object[] references(TaskReference[] other) { + return Stream.of(other).map(TaskReference::reference).toArray(Object[]::new); + } +} diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TasksMixin.java b/common/src/main/java/org/implab/gradle/common/dsl/TasksMixin.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/dsl/TasksMixin.java @@ -0,0 +1,12 @@ +package org.implab.gradle.common.dsl; + +import org.gradle.api.Task; + +public interface TasksMixin { + + default TaskSpec task(String name) { + return task(name, Task.class); + } + + TaskSpec task(String name, Class clazz); +} diff --git a/common/src/main/java/org/implab/gradle/common/tasks/TaskExtra.java b/common/src/main/java/org/implab/gradle/common/tasks/TaskExtra.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/tasks/TaskExtra.java @@ -0,0 +1,29 @@ +package org.implab.gradle.common.tasks; + +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.logging.Logger; +import org.gradle.api.specs.Spec; +import org.gradle.api.tasks.Internal; + +/** Task methods available by default, this interface is used by mixins to + * interact with their task. + */ +public interface TaskExtra { + @Internal + Project getProject(); + + void onlyIf(Spec spec); + + @Internal + Logger getLogger(); + + default void onlyIfReason(String skipReason, Spec spec) { + onlyIf(self -> { + var satisfied = spec.isSatisfiedBy(self); + if (!satisfied) + getLogger().info("SKIP: {}", skipReason); + return satisfied; + }); + } +} diff --git a/common/src/main/java/org/implab/gradle/common/utils/Configurations.java b/common/src/main/java/org/implab/gradle/common/utils/Configurations.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/utils/Configurations.java @@ -0,0 +1,24 @@ +package org.implab.gradle.common.utils; + +import org.gradle.api.Action; +import org.gradle.api.artifacts.Configuration; + +public final class Configurations { + + public static final Action RESOLVABLE = Configurations::resolvable; + + public static final Action CONSUMABLE = Configurations::consumable; + + private Configurations() { + } + + private static void resolvable(Configuration configuration) { + configuration.setCanBeResolved(true); + configuration.setCanBeConsumed(false); + } + + private static void consumable(Configuration configuration) { + configuration.setCanBeResolved(false); + configuration.setCanBeConsumed(true); + } +} diff --git a/common/src/main/java/org/implab/gradle/common/utils/Strings.java b/common/src/main/java/org/implab/gradle/common/utils/Strings.java new file mode 100644 --- /dev/null +++ b/common/src/main/java/org/implab/gradle/common/utils/Strings.java @@ -0,0 +1,14 @@ +package org.implab.gradle.common.utils; + +import java.util.regex.Pattern; + +public class Strings { + + private static final Pattern firstLetter = Pattern.compile("^\\w"); + + public static String capitalize(String string) { + if (string == null || string.length() == 0) + return ""; + return firstLetter.matcher(string).replaceFirst(m -> m.group().toUpperCase()); + } +}