# HG changeset patch # User cin # Date 2025-11-26 21:14:18 # Node ID 8e57f0a2d4defce161edcd65f0c3a41c93f40bd6 # Parent 5a3f85261d98f33535c375ceb3fde05df55fe1a1 Refactoring, removed GenericSourceSetOutput. diff --git a/.vscode/settings.json b/.vscode/settings.json --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "java.configuration.updateBuildConfiguration": "automatic", "java.compile.nullAnalysis.mode": "automatic", "cSpell.words": [ - "implab" + "implab", + "rawtypes" ] } \ No newline at end of file diff --git a/common/src/main/java/org/implab/gradle/common/utils/Extensions.java b/common/src/main/java/org/implab/gradle/common/core/gradle/Extensions.java rename from common/src/main/java/org/implab/gradle/common/utils/Extensions.java rename to common/src/main/java/org/implab/gradle/common/core/gradle/Extensions.java --- a/common/src/main/java/org/implab/gradle/common/utils/Extensions.java +++ b/common/src/main/java/org/implab/gradle/common/core/gradle/Extensions.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.gradle; import java.util.function.Consumer; diff --git a/common/src/main/java/org/implab/gradle/common/utils/Properties.java b/common/src/main/java/org/implab/gradle/common/core/gradle/Properties.java rename from common/src/main/java/org/implab/gradle/common/utils/Properties.java rename to common/src/main/java/org/implab/gradle/common/core/gradle/Properties.java --- a/common/src/main/java/org/implab/gradle/common/utils/Properties.java +++ b/common/src/main/java/org/implab/gradle/common/core/gradle/Properties.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.gradle; import java.util.HashMap; import java.util.Map; diff --git a/common/src/main/java/org/implab/gradle/common/tasks/TaskExtra.java b/common/src/main/java/org/implab/gradle/common/core/gradle/TaskExtra.java rename from common/src/main/java/org/implab/gradle/common/tasks/TaskExtra.java rename to common/src/main/java/org/implab/gradle/common/core/gradle/TaskExtra.java --- a/common/src/main/java/org/implab/gradle/common/tasks/TaskExtra.java +++ b/common/src/main/java/org/implab/gradle/common/core/gradle/TaskExtra.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.tasks; +package org.implab.gradle.common.core.gradle; import org.gradle.api.Project; import org.gradle.api.Task; diff --git a/common/src/main/java/org/implab/gradle/common/utils/Closures.java b/common/src/main/java/org/implab/gradle/common/core/lang/Closures.java rename from common/src/main/java/org/implab/gradle/common/utils/Closures.java rename to common/src/main/java/org/implab/gradle/common/core/lang/Closures.java --- a/common/src/main/java/org/implab/gradle/common/utils/Closures.java +++ b/common/src/main/java/org/implab/gradle/common/core/lang/Closures.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.lang; import groovy.lang.Closure; diff --git a/common/src/main/java/org/implab/gradle/common/utils/Exceptions.java b/common/src/main/java/org/implab/gradle/common/core/lang/Exceptions.java rename from common/src/main/java/org/implab/gradle/common/utils/Exceptions.java rename to common/src/main/java/org/implab/gradle/common/core/lang/Exceptions.java --- a/common/src/main/java/org/implab/gradle/common/utils/Exceptions.java +++ b/common/src/main/java/org/implab/gradle/common/core/lang/Exceptions.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.lang; import java.util.function.Consumer; import java.util.function.Function; @@ -12,7 +12,6 @@ public class Exceptions { * @param clazz * @throws E */ - @SuppressWarnings("unused") public static void mayThrow(Class clazz) throws E { } diff --git a/common/src/main/java/org/implab/gradle/common/utils/LazyValue.java b/common/src/main/java/org/implab/gradle/common/core/lang/LazyValue.java rename from common/src/main/java/org/implab/gradle/common/utils/LazyValue.java rename to common/src/main/java/org/implab/gradle/common/core/lang/LazyValue.java --- a/common/src/main/java/org/implab/gradle/common/utils/LazyValue.java +++ b/common/src/main/java/org/implab/gradle/common/core/lang/LazyValue.java @@ -1,10 +1,10 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.lang; -import java.util.concurrent.atomic.AtomicReference; +import java.util.Objects; import java.util.function.Supplier; public class LazyValue implements Supplier { - private final AtomicReference reference = new AtomicReference<>(); + private volatile T value; private final Supplier innerSupplier; @@ -14,16 +14,21 @@ public class LazyValue implements Sup @Override public T get() { - var t = reference.get(); - if (t != null) - return t; - return updateValue(); - } + var v = value; + if (v != null) { + return v; + } - private T updateValue() { - var v = innerSupplier.get(); - var t = reference.compareAndExchange(null, v); - return t != null ? t : v; + synchronized (this) { + v = value; + if (v == null) { + v = Objects.requireNonNull( + innerSupplier.get(), + "LazyValue supplier returned null"); + value = v; + } + return v; + } } } diff --git a/common/src/main/java/org/implab/gradle/common/utils/SemVersion.java b/common/src/main/java/org/implab/gradle/common/core/lang/SemVersion.java rename from common/src/main/java/org/implab/gradle/common/utils/SemVersion.java rename to common/src/main/java/org/implab/gradle/common/core/lang/SemVersion.java --- a/common/src/main/java/org/implab/gradle/common/utils/SemVersion.java +++ b/common/src/main/java/org/implab/gradle/common/core/lang/SemVersion.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.lang; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/common/src/main/java/org/implab/gradle/common/utils/Strings.java b/common/src/main/java/org/implab/gradle/common/core/lang/Strings.java rename from common/src/main/java/org/implab/gradle/common/utils/Strings.java rename to common/src/main/java/org/implab/gradle/common/core/lang/Strings.java --- a/common/src/main/java/org/implab/gradle/common/utils/Strings.java +++ b/common/src/main/java/org/implab/gradle/common/core/lang/Strings.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.lang; import java.util.regex.Pattern; diff --git a/common/src/main/java/org/implab/gradle/common/utils/Values.java b/common/src/main/java/org/implab/gradle/common/core/lang/Values.java rename from common/src/main/java/org/implab/gradle/common/utils/Values.java rename to common/src/main/java/org/implab/gradle/common/core/lang/Values.java --- a/common/src/main/java/org/implab/gradle/common/utils/Values.java +++ b/common/src/main/java/org/implab/gradle/common/core/lang/Values.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.lang; import java.text.MessageFormat; import java.util.Iterator; diff --git a/common/src/main/java/org/implab/gradle/common/utils/os/FreeBsd.java b/common/src/main/java/org/implab/gradle/common/core/os/FreeBsd.java rename from common/src/main/java/org/implab/gradle/common/utils/os/FreeBsd.java rename to common/src/main/java/org/implab/gradle/common/core/os/FreeBsd.java --- a/common/src/main/java/org/implab/gradle/common/utils/os/FreeBsd.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/FreeBsd.java @@ -1,8 +1,6 @@ -package org.implab.gradle.common.utils.os; +package org.implab.gradle.common.core.os; -import org.implab.gradle.common.utils.OperatingSystem; - -public class FreeBsd extends GenericSystem{ +class FreeBsd extends GenericSystem{ FreeBsd(String name, String version) { super(name, version); diff --git a/common/src/main/java/org/implab/gradle/common/utils/os/GenericSystem.java b/common/src/main/java/org/implab/gradle/common/core/os/GenericSystem.java rename from common/src/main/java/org/implab/gradle/common/utils/os/GenericSystem.java rename to common/src/main/java/org/implab/gradle/common/core/os/GenericSystem.java --- a/common/src/main/java/org/implab/gradle/common/utils/os/GenericSystem.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/GenericSystem.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.utils.os; +package org.implab.gradle.common.core.os; import java.io.File; import java.util.Arrays; @@ -7,8 +7,7 @@ import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Stream; -import org.implab.gradle.common.utils.OperatingSystem; -import org.implab.gradle.common.utils.Values; +import org.implab.gradle.common.core.lang.Values; class GenericSystem implements OperatingSystem { diff --git a/common/src/main/java/org/implab/gradle/common/utils/os/Linux.java b/common/src/main/java/org/implab/gradle/common/core/os/Linux.java rename from common/src/main/java/org/implab/gradle/common/utils/os/Linux.java rename to common/src/main/java/org/implab/gradle/common/core/os/Linux.java --- a/common/src/main/java/org/implab/gradle/common/utils/os/Linux.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/Linux.java @@ -1,8 +1,6 @@ -package org.implab.gradle.common.utils.os; +package org.implab.gradle.common.core.os; -import org.implab.gradle.common.utils.OperatingSystem; - -public class Linux extends GenericSystem { +class Linux extends GenericSystem { Linux(String name, String version) { super(name, version); diff --git a/common/src/main/java/org/implab/gradle/common/utils/os/MacOs.java b/common/src/main/java/org/implab/gradle/common/core/os/MacOs.java rename from common/src/main/java/org/implab/gradle/common/utils/os/MacOs.java rename to common/src/main/java/org/implab/gradle/common/core/os/MacOs.java --- a/common/src/main/java/org/implab/gradle/common/utils/os/MacOs.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/MacOs.java @@ -1,8 +1,6 @@ -package org.implab.gradle.common.utils.os; +package org.implab.gradle.common.core.os; -import org.implab.gradle.common.utils.OperatingSystem; - -public class MacOs extends GenericSystem { +class MacOs extends GenericSystem { MacOs(String name, String version) { super(name, version); diff --git a/common/src/main/java/org/implab/gradle/common/utils/OperatingSystem.java b/common/src/main/java/org/implab/gradle/common/core/os/OperatingSystem.java rename from common/src/main/java/org/implab/gradle/common/utils/OperatingSystem.java rename to common/src/main/java/org/implab/gradle/common/core/os/OperatingSystem.java --- a/common/src/main/java/org/implab/gradle/common/utils/OperatingSystem.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/OperatingSystem.java @@ -1,10 +1,8 @@ -package org.implab.gradle.common.utils; +package org.implab.gradle.common.core.os; import java.io.File; import java.util.Optional; -import org.implab.gradle.common.utils.os.SystemResolver; - public interface OperatingSystem { public static final String WINDOWS_FAMILY = "windows"; diff --git a/common/src/main/java/org/implab/gradle/common/utils/os/SystemResolver.java b/common/src/main/java/org/implab/gradle/common/core/os/SystemResolver.java rename from common/src/main/java/org/implab/gradle/common/utils/os/SystemResolver.java rename to common/src/main/java/org/implab/gradle/common/core/os/SystemResolver.java --- a/common/src/main/java/org/implab/gradle/common/utils/os/SystemResolver.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/SystemResolver.java @@ -1,9 +1,8 @@ -package org.implab.gradle.common.utils.os; +package org.implab.gradle.common.core.os; -import org.implab.gradle.common.utils.LazyValue; -import org.implab.gradle.common.utils.OperatingSystem; +import org.implab.gradle.common.core.lang.LazyValue; -public class SystemResolver { +class SystemResolver { private final static LazyValue current = new LazyValue<>(SystemResolver::resolveCurrent); diff --git a/common/src/main/java/org/implab/gradle/common/utils/os/Windows.java b/common/src/main/java/org/implab/gradle/common/core/os/Windows.java rename from common/src/main/java/org/implab/gradle/common/utils/os/Windows.java rename to common/src/main/java/org/implab/gradle/common/core/os/Windows.java --- a/common/src/main/java/org/implab/gradle/common/utils/os/Windows.java +++ b/common/src/main/java/org/implab/gradle/common/core/os/Windows.java @@ -1,11 +1,9 @@ -package org.implab.gradle.common.utils.os; +package org.implab.gradle.common.core.os; import java.io.File; import java.util.function.Function; import java.util.stream.Stream; -import org.implab.gradle.common.utils.OperatingSystem; - class Windows extends GenericSystem { private Stream exeSuffixes = Stream.of(".cmd", ".bat", ".exe"); diff --git a/common/src/main/java/org/implab/gradle/common/dsl/RedirectFromSpec.java b/common/src/main/java/org/implab/gradle/common/exec/dsl/RedirectFromSpec.java rename from common/src/main/java/org/implab/gradle/common/dsl/RedirectFromSpec.java rename to common/src/main/java/org/implab/gradle/common/exec/dsl/RedirectFromSpec.java --- a/common/src/main/java/org/implab/gradle/common/dsl/RedirectFromSpec.java +++ b/common/src/main/java/org/implab/gradle/common/exec/dsl/RedirectFromSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.dsl; +package org.implab.gradle.common.exec.dsl; import java.io.File; import java.io.InputStream; @@ -7,8 +7,8 @@ import java.util.function.Supplier; import org.gradle.api.provider.Provider; import org.gradle.util.Configurable; -import org.implab.gradle.common.exec.RedirectFrom; -import org.implab.gradle.common.utils.Closures; +import org.implab.gradle.common.core.lang.Closures; +import org.implab.gradle.common.exec.runtime.RedirectFrom; import groovy.lang.Closure; diff --git a/common/src/main/java/org/implab/gradle/common/dsl/RedirectToSpec.java b/common/src/main/java/org/implab/gradle/common/exec/dsl/RedirectToSpec.java rename from common/src/main/java/org/implab/gradle/common/dsl/RedirectToSpec.java rename to common/src/main/java/org/implab/gradle/common/exec/dsl/RedirectToSpec.java --- a/common/src/main/java/org/implab/gradle/common/dsl/RedirectToSpec.java +++ b/common/src/main/java/org/implab/gradle/common/exec/dsl/RedirectToSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.dsl; +package org.implab.gradle.common.exec.dsl; import java.io.File; import java.io.OutputStream; @@ -10,8 +10,8 @@ import org.eclipse.jdt.annotation.NonNul import org.eclipse.jdt.annotation.Nullable; import org.gradle.api.provider.Provider; import org.gradle.util.Configurable; -import org.implab.gradle.common.exec.RedirectTo; -import org.implab.gradle.common.utils.Closures; +import org.implab.gradle.common.core.lang.Closures; +import org.implab.gradle.common.exec.runtime.RedirectTo; import groovy.lang.Closure; diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskCommandSpecMixin.java b/common/src/main/java/org/implab/gradle/common/exec/dsl/TaskCommandSpecMixin.java rename from common/src/main/java/org/implab/gradle/common/dsl/TaskCommandSpecMixin.java rename to common/src/main/java/org/implab/gradle/common/exec/dsl/TaskCommandSpecMixin.java --- a/common/src/main/java/org/implab/gradle/common/dsl/TaskCommandSpecMixin.java +++ b/common/src/main/java/org/implab/gradle/common/exec/dsl/TaskCommandSpecMixin.java @@ -1,9 +1,9 @@ -package org.implab.gradle.common.dsl; +package org.implab.gradle.common.exec.dsl; import java.util.stream.Stream; import org.gradle.api.provider.ListProperty; -import org.implab.gradle.common.utils.Properties; +import org.implab.gradle.common.core.gradle.Properties; public interface TaskCommandSpecMixin { ListProperty getCommandLine(); diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskEnvSpecMixin.java b/common/src/main/java/org/implab/gradle/common/exec/dsl/TaskEnvSpecMixin.java rename from common/src/main/java/org/implab/gradle/common/dsl/TaskEnvSpecMixin.java rename to common/src/main/java/org/implab/gradle/common/exec/dsl/TaskEnvSpecMixin.java --- a/common/src/main/java/org/implab/gradle/common/dsl/TaskEnvSpecMixin.java +++ b/common/src/main/java/org/implab/gradle/common/exec/dsl/TaskEnvSpecMixin.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.dsl; +package org.implab.gradle.common.exec.dsl; import java.util.Map; @@ -6,8 +6,8 @@ import org.gradle.api.Action; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; -import org.implab.gradle.common.utils.Closures; -import org.implab.gradle.common.utils.Properties; +import org.implab.gradle.common.core.gradle.Properties; +import org.implab.gradle.common.core.lang.Closures; import groovy.lang.Closure; diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskPipeSpecMixin.java b/common/src/main/java/org/implab/gradle/common/exec/dsl/TaskPipeSpecMixin.java rename from common/src/main/java/org/implab/gradle/common/dsl/TaskPipeSpecMixin.java rename to common/src/main/java/org/implab/gradle/common/exec/dsl/TaskPipeSpecMixin.java --- a/common/src/main/java/org/implab/gradle/common/dsl/TaskPipeSpecMixin.java +++ b/common/src/main/java/org/implab/gradle/common/exec/dsl/TaskPipeSpecMixin.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.dsl; +package org.implab.gradle.common.exec.dsl; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/common/src/main/java/org/implab/gradle/common/exec/CommandArgumentsBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/model/CommandArgumentsBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/CommandArgumentsBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/model/CommandArgumentsBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/CommandArgumentsBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/model/CommandArgumentsBuilder.java @@ -1,11 +1,11 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.model; import static java.util.Objects.requireNonNull; import java.util.Optional; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.implab.gradle.common.utils.Values; +import org.implab.gradle.common.core.lang.Values; @NonNullByDefault public interface CommandArgumentsBuilder> { diff --git a/common/src/main/java/org/implab/gradle/common/exec/CommandBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/model/CommandBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/CommandBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/model/CommandBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/CommandBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/model/CommandBuilder.java @@ -1,9 +1,9 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.model; import java.io.File; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.implab.gradle.common.utils.Values; +import org.implab.gradle.common.core.lang.Values; /** Command builder interface, used to specify the executable and parameters */ @NonNullByDefault diff --git a/common/src/main/java/org/implab/gradle/common/exec/CommandSpec.java b/common/src/main/java/org/implab/gradle/common/exec/model/CommandSpec.java rename from common/src/main/java/org/implab/gradle/common/exec/CommandSpec.java rename to common/src/main/java/org/implab/gradle/common/exec/model/CommandSpec.java --- a/common/src/main/java/org/implab/gradle/common/exec/CommandSpec.java +++ b/common/src/main/java/org/implab/gradle/common/exec/model/CommandSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.model; import java.util.List; import java.util.stream.Stream; diff --git a/common/src/main/java/org/implab/gradle/common/exec/CommandSpecRecord.java b/common/src/main/java/org/implab/gradle/common/exec/model/CommandSpecRecord.java rename from common/src/main/java/org/implab/gradle/common/exec/CommandSpecRecord.java rename to common/src/main/java/org/implab/gradle/common/exec/model/CommandSpecRecord.java --- a/common/src/main/java/org/implab/gradle/common/exec/CommandSpecRecord.java +++ b/common/src/main/java/org/implab/gradle/common/exec/model/CommandSpecRecord.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.model; import java.util.List; diff --git a/common/src/main/java/org/implab/gradle/common/exec/EnvironmentSpec.java b/common/src/main/java/org/implab/gradle/common/exec/model/EnvironmentSpec.java rename from common/src/main/java/org/implab/gradle/common/exec/EnvironmentSpec.java rename to common/src/main/java/org/implab/gradle/common/exec/model/EnvironmentSpec.java --- a/common/src/main/java/org/implab/gradle/common/exec/EnvironmentSpec.java +++ b/common/src/main/java/org/implab/gradle/common/exec/model/EnvironmentSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.model; import java.io.File; import java.util.Map; diff --git a/common/src/main/java/org/implab/gradle/common/exec/PipeSpec.java b/common/src/main/java/org/implab/gradle/common/exec/model/PipeSpec.java rename from common/src/main/java/org/implab/gradle/common/exec/PipeSpec.java rename to common/src/main/java/org/implab/gradle/common/exec/model/PipeSpec.java --- a/common/src/main/java/org/implab/gradle/common/exec/PipeSpec.java +++ b/common/src/main/java/org/implab/gradle/common/exec/model/PipeSpec.java @@ -1,4 +1,7 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.model; + +import org.implab.gradle.common.exec.runtime.RedirectFrom; +import org.implab.gradle.common.exec.runtime.RedirectTo; import java.util.Optional; diff --git a/common/src/main/java/org/implab/gradle/common/exec/AbstractExecBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/AbstractExecBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/AbstractExecBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/AbstractExecBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/AbstractExecBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/AbstractExecBuilder.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.util.HashMap; import java.util.Map; @@ -7,6 +7,8 @@ import java.util.concurrent.CompletableF import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.implab.gradle.common.exec.model.EnvironmentSpec; +import org.implab.gradle.common.exec.model.PipeSpec; import java.io.File; import java.io.IOException; diff --git a/common/src/main/java/org/implab/gradle/common/exec/EchoExecBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/EchoExecBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/EchoExecBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/EchoExecBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/EchoExecBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/EchoExecBuilder.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -7,6 +7,9 @@ import java.util.concurrent.CompletableF import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.implab.gradle.common.exec.model.CommandSpec; +import org.implab.gradle.common.exec.model.EnvironmentSpec; +import org.implab.gradle.common.exec.model.PipeSpec; @NonNullByDefault class EchoExecBuilder extends AbstractExecBuilder { diff --git a/common/src/main/java/org/implab/gradle/common/exec/EnvironmentBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/EnvironmentBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/EnvironmentBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/EnvironmentBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/EnvironmentBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/EnvironmentBuilder.java @@ -1,10 +1,11 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.io.File; import java.util.Map; import java.util.Optional; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.implab.gradle.common.exec.model.EnvironmentSpec; @NonNullByDefault public interface EnvironmentBuilder { diff --git a/common/src/main/java/org/implab/gradle/common/exec/PipeBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/PipeBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/PipeBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/PipeBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/PipeBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/PipeBuilder.java @@ -1,8 +1,9 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.util.Optional; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.implab.gradle.common.exec.model.PipeSpec; @NonNullByDefault public interface PipeBuilder { diff --git a/common/src/main/java/org/implab/gradle/common/exec/RedirectFrom.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/RedirectFrom.java rename from common/src/main/java/org/implab/gradle/common/exec/RedirectFrom.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/RedirectFrom.java --- a/common/src/main/java/org/implab/gradle/common/exec/RedirectFrom.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/RedirectFrom.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.io.File; import java.io.FileInputStream; diff --git a/common/src/main/java/org/implab/gradle/common/exec/RedirectTo.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/RedirectTo.java rename from common/src/main/java/org/implab/gradle/common/exec/RedirectTo.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/RedirectTo.java --- a/common/src/main/java/org/implab/gradle/common/exec/RedirectTo.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/RedirectTo.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.io.File; import java.io.FileOutputStream; @@ -108,4 +108,4 @@ public interface RedirectTo { throw new IllegalArgumentException("The specified argument type isn't supported: " + output.getClass()); } } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/exec/Shell.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/Shell.java rename from common/src/main/java/org/implab/gradle/common/exec/Shell.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/Shell.java --- a/common/src/main/java/org/implab/gradle/common/exec/Shell.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/Shell.java @@ -1,6 +1,7 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.implab.gradle.common.exec.model.CommandSpec; @NonNullByDefault public interface Shell { diff --git a/common/src/main/java/org/implab/gradle/common/exec/ShellExec.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/ShellExec.java rename from common/src/main/java/org/implab/gradle/common/exec/ShellExec.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/ShellExec.java --- a/common/src/main/java/org/implab/gradle/common/exec/ShellExec.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/ShellExec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.io.IOException; import java.util.ArrayList; @@ -6,7 +6,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.implab.gradle.common.utils.Exceptions; +import org.implab.gradle.common.core.lang.Exceptions; @NonNullByDefault public interface ShellExec extends PipeBuilder, EnvironmentBuilder { diff --git a/common/src/main/java/org/implab/gradle/common/exec/ShellTool.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/ShellTool.java rename from common/src/main/java/org/implab/gradle/common/exec/ShellTool.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/ShellTool.java --- a/common/src/main/java/org/implab/gradle/common/exec/ShellTool.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/ShellTool.java @@ -1,7 +1,9 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import org.eclipse.jdt.annotation.NonNullByDefault; import org.gradle.api.Action; +import org.implab.gradle.common.exec.model.CommandArgumentsBuilder; +import org.implab.gradle.common.exec.model.CommandSpec; @NonNullByDefault public class ShellTool { diff --git a/common/src/main/java/org/implab/gradle/common/exec/SystemExecBuilder.java b/common/src/main/java/org/implab/gradle/common/exec/runtime/SystemExecBuilder.java rename from common/src/main/java/org/implab/gradle/common/exec/SystemExecBuilder.java rename to common/src/main/java/org/implab/gradle/common/exec/runtime/SystemExecBuilder.java --- a/common/src/main/java/org/implab/gradle/common/exec/SystemExecBuilder.java +++ b/common/src/main/java/org/implab/gradle/common/exec/runtime/SystemExecBuilder.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.exec.runtime; import java.io.IOException; import java.lang.ProcessBuilder.Redirect; @@ -6,6 +6,9 @@ import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.implab.gradle.common.exec.model.CommandSpec; +import org.implab.gradle.common.exec.model.EnvironmentSpec; +import org.implab.gradle.common.exec.model.PipeSpec; @NonNullByDefault class SystemExecBuilder extends AbstractExecBuilder { diff --git a/common/src/main/java/org/implab/gradle/common/tasks/AbstractShellExecTask.java b/common/src/main/java/org/implab/gradle/common/exec/tasks/AbstractShellExecTask.java rename from common/src/main/java/org/implab/gradle/common/tasks/AbstractShellExecTask.java rename to common/src/main/java/org/implab/gradle/common/exec/tasks/AbstractShellExecTask.java --- a/common/src/main/java/org/implab/gradle/common/tasks/AbstractShellExecTask.java +++ b/common/src/main/java/org/implab/gradle/common/exec/tasks/AbstractShellExecTask.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.tasks; +package org.implab.gradle.common.exec.tasks; import java.io.IOException; import java.util.Map; @@ -11,14 +11,14 @@ import org.gradle.api.provider.MapProper import org.gradle.api.provider.Property; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.TaskAction; -import org.implab.gradle.common.dsl.RedirectFromSpec; -import org.implab.gradle.common.dsl.RedirectToSpec; -import org.implab.gradle.common.dsl.TaskEnvSpecMixin; -import org.implab.gradle.common.dsl.TaskPipeSpecMixin; -import org.implab.gradle.common.exec.RedirectTo; -import org.implab.gradle.common.exec.ShellExec; -import org.implab.gradle.common.utils.Exceptions; -import org.implab.gradle.common.utils.Values; +import org.implab.gradle.common.core.lang.Exceptions; +import org.implab.gradle.common.core.lang.Values; +import org.implab.gradle.common.exec.dsl.RedirectFromSpec; +import org.implab.gradle.common.exec.dsl.RedirectToSpec; +import org.implab.gradle.common.exec.dsl.TaskEnvSpecMixin; +import org.implab.gradle.common.exec.dsl.TaskPipeSpecMixin; +import org.implab.gradle.common.exec.runtime.RedirectTo; +import org.implab.gradle.common.exec.runtime.ShellExec; public abstract class AbstractShellExecTask extends DefaultTask @@ -105,4 +105,4 @@ public abstract class AbstractShellExecT if (code != 0) throw new IOException(String.format("The process is terminated with code %s", code)); } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/tasks/ShellExecTask.java b/common/src/main/java/org/implab/gradle/common/exec/tasks/ShellExecTask.java rename from common/src/main/java/org/implab/gradle/common/tasks/ShellExecTask.java rename to common/src/main/java/org/implab/gradle/common/exec/tasks/ShellExecTask.java --- a/common/src/main/java/org/implab/gradle/common/tasks/ShellExecTask.java +++ b/common/src/main/java/org/implab/gradle/common/exec/tasks/ShellExecTask.java @@ -1,12 +1,12 @@ -package org.implab.gradle.common.tasks; +package org.implab.gradle.common.exec.tasks; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Internal; -import org.implab.gradle.common.dsl.TaskCommandSpecMixin; -import org.implab.gradle.common.exec.CommandSpec; -import org.implab.gradle.common.exec.Shell; -import org.implab.gradle.common.exec.ShellExec; +import org.implab.gradle.common.exec.dsl.TaskCommandSpecMixin; +import org.implab.gradle.common.exec.model.CommandSpec; +import org.implab.gradle.common.exec.runtime.Shell; +import org.implab.gradle.common.exec.runtime.ShellExec; public abstract class ShellExecTask extends AbstractShellExecTask diff --git a/common/src/main/java/org/implab/gradle/common/files/GenericSourceSetOutput.java b/common/src/main/java/org/implab/gradle/common/files/GenericSourceSetOutput.java deleted file mode 100644 --- a/common/src/main/java/org/implab/gradle/common/files/GenericSourceSetOutput.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.implab.gradle.common.files; - -import org.gradle.api.Action; -import org.gradle.api.Named; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.file.FileCollection; -import org.gradle.api.model.ObjectFactory; -import org.gradle.util.Configurable; -import org.implab.gradle.common.utils.Closures; - -import groovy.lang.Closure; - -/** Simple wrapper to add {@link Named} to {@link FileCollection} */ -public abstract class GenericSourceSetOutput - implements Named, Configurable { - - private final String name; - - private final ConfigurableFileCollection outputFileCollection; - - public GenericSourceSetOutput(String name, ObjectFactory objects) { - this.name = name; - outputFileCollection = objects.fileCollection(); - } - - public FileCollection getFileCollection() { - return outputFileCollection; - } - - @Override - public String getName() { - return name; - } - - @Override - public GenericSourceSetOutput configure(@SuppressWarnings("rawtypes") Closure cl) { - Closures.apply(cl, outputFileCollection); - return this; - } - - public GenericSourceSetOutput configure(Action cl) { - cl.execute(outputFileCollection); - return this; - } - -} diff --git a/common/src/main/java/org/implab/gradle/common/json/Json.java b/common/src/main/java/org/implab/gradle/common/json/core/Json.java rename from common/src/main/java/org/implab/gradle/common/json/Json.java rename to common/src/main/java/org/implab/gradle/common/json/core/Json.java --- a/common/src/main/java/org/implab/gradle/common/json/Json.java +++ b/common/src/main/java/org/implab/gradle/common/json/core/Json.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.core; import java.io.File; import java.io.IOException; @@ -6,7 +6,7 @@ import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; -import org.implab.gradle.common.utils.LazyValue; +import org.implab.gradle.common.core.lang.LazyValue; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/common/src/main/java/org/implab/gradle/common/json/MapImportSpec.java b/common/src/main/java/org/implab/gradle/common/json/core/MapImportSpec.java rename from common/src/main/java/org/implab/gradle/common/json/MapImportSpec.java rename to common/src/main/java/org/implab/gradle/common/json/core/MapImportSpec.java --- a/common/src/main/java/org/implab/gradle/common/json/MapImportSpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/core/MapImportSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.core; import java.util.Arrays; import java.util.LinkedHashSet; @@ -6,7 +6,7 @@ import java.util.Set; import java.util.function.Predicate; import org.gradle.api.Action; -import org.implab.gradle.common.utils.Closures; +import org.implab.gradle.common.core.lang.Closures; import groovy.lang.Closure; @@ -63,4 +63,4 @@ public class MapImportSpec { public static Predicate buildPredicate(Closure closure) { return buildPredicate(Closures.action(closure)); } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/json/DefaultJsonArraySpec.java b/common/src/main/java/org/implab/gradle/common/json/dsl/DefaultJsonArraySpec.java rename from common/src/main/java/org/implab/gradle/common/json/DefaultJsonArraySpec.java rename to common/src/main/java/org/implab/gradle/common/json/dsl/DefaultJsonArraySpec.java --- a/common/src/main/java/org/implab/gradle/common/json/DefaultJsonArraySpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/dsl/DefaultJsonArraySpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.dsl; import org.gradle.api.provider.Provider; @@ -26,4 +26,4 @@ public class DefaultJsonArraySpec implem public List toList() { return Collections.unmodifiableList(values); } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/json/DefaultJsonObjectSpec.java b/common/src/main/java/org/implab/gradle/common/json/dsl/DefaultJsonObjectSpec.java rename from common/src/main/java/org/implab/gradle/common/json/DefaultJsonObjectSpec.java rename to common/src/main/java/org/implab/gradle/common/json/dsl/DefaultJsonObjectSpec.java --- a/common/src/main/java/org/implab/gradle/common/json/DefaultJsonObjectSpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/dsl/DefaultJsonObjectSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.dsl; import org.gradle.api.provider.Provider; @@ -23,4 +23,4 @@ public class DefaultJsonObjectSpec imple public Map toMap() { return Collections.unmodifiableMap(values); } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/json/GroovyObjectSpec.java b/common/src/main/java/org/implab/gradle/common/json/dsl/GroovyObjectSpec.java rename from common/src/main/java/org/implab/gradle/common/json/GroovyObjectSpec.java rename to common/src/main/java/org/implab/gradle/common/json/dsl/GroovyObjectSpec.java --- a/common/src/main/java/org/implab/gradle/common/json/GroovyObjectSpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/dsl/GroovyObjectSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.dsl; import java.util.Arrays; diff --git a/common/src/main/java/org/implab/gradle/common/json/JsonArraySpec.java b/common/src/main/java/org/implab/gradle/common/json/dsl/JsonArraySpec.java rename from common/src/main/java/org/implab/gradle/common/json/JsonArraySpec.java rename to common/src/main/java/org/implab/gradle/common/json/dsl/JsonArraySpec.java --- a/common/src/main/java/org/implab/gradle/common/json/JsonArraySpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/dsl/JsonArraySpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.dsl; import org.gradle.api.Action; @@ -17,4 +17,4 @@ public interface JsonArraySpec { action.execute(child); add(child.toList()); } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/json/JsonMapSpec.java b/common/src/main/java/org/implab/gradle/common/json/dsl/JsonMapSpec.java rename from common/src/main/java/org/implab/gradle/common/json/JsonMapSpec.java rename to common/src/main/java/org/implab/gradle/common/json/dsl/JsonMapSpec.java --- a/common/src/main/java/org/implab/gradle/common/json/JsonMapSpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/dsl/JsonMapSpec.java @@ -1,10 +1,11 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.dsl; import java.io.File; import org.gradle.api.Action; import org.gradle.api.file.RegularFile; import org.gradle.api.provider.Provider; +import org.implab.gradle.common.json.core.MapImportSpec; public interface JsonMapSpec extends GroovyObjectSpec { void from(File file, Action action); diff --git a/common/src/main/java/org/implab/gradle/common/json/JsonObjectSpec.java b/common/src/main/java/org/implab/gradle/common/json/dsl/JsonObjectSpec.java rename from common/src/main/java/org/implab/gradle/common/json/JsonObjectSpec.java rename to common/src/main/java/org/implab/gradle/common/json/dsl/JsonObjectSpec.java --- a/common/src/main/java/org/implab/gradle/common/json/JsonObjectSpec.java +++ b/common/src/main/java/org/implab/gradle/common/json/dsl/JsonObjectSpec.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.json; +package org.implab.gradle.common.json.dsl; import org.gradle.api.Action; @@ -17,4 +17,4 @@ public interface JsonObjectSpec { action.execute(child); set(key, child.toList()); } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/implab/gradle/common/tasks/WriteJson.java b/common/src/main/java/org/implab/gradle/common/json/tasks/WriteJson.java rename from common/src/main/java/org/implab/gradle/common/tasks/WriteJson.java rename to common/src/main/java/org/implab/gradle/common/json/tasks/WriteJson.java --- a/common/src/main/java/org/implab/gradle/common/tasks/WriteJson.java +++ b/common/src/main/java/org/implab/gradle/common/json/tasks/WriteJson.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common.tasks; +package org.implab.gradle.common.json.tasks; import java.util.LinkedHashMap; import java.util.Map; @@ -20,13 +20,12 @@ import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.SkipWhenEmpty; import org.gradle.api.tasks.TaskAction; -import org.implab.gradle.common.json.MapImportSpec; -import org.implab.gradle.common.json.Json; -import org.implab.gradle.common.json.JsonObjectSpec; -import org.implab.gradle.common.utils.Closures; -import org.implab.gradle.common.utils.Properties; +import org.implab.gradle.common.core.gradle.Properties; +import org.implab.gradle.common.core.lang.Closures; +import org.implab.gradle.common.json.core.Json; +import org.implab.gradle.common.json.core.MapImportSpec; +import org.implab.gradle.common.json.dsl.JsonObjectSpec; import groovy.lang.Closure; diff --git a/common/src/main/java/org/implab/gradle/common/files/GenericSourceSet.java b/common/src/main/java/org/implab/gradle/common/sources/GenericSourceSet.java rename from common/src/main/java/org/implab/gradle/common/files/GenericSourceSet.java rename to common/src/main/java/org/implab/gradle/common/sources/GenericSourceSet.java --- a/common/src/main/java/org/implab/gradle/common/files/GenericSourceSet.java +++ b/common/src/main/java/org/implab/gradle/common/sources/GenericSourceSet.java @@ -1,39 +1,61 @@ -package org.implab.gradle.common.files; +package org.implab.gradle.common.sources; import java.io.File; import java.nio.file.Paths; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.Callable; +import java.util.function.Function; import java.util.stream.Collectors; import javax.inject.Inject; +import org.gradle.api.InvalidUserDataException; import org.gradle.api.Named; import org.gradle.api.NamedDomainObjectContainer; +import org.gradle.api.Task; +import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.FileCollection; import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.SourceDirectorySet; -import org.gradle.api.logging.Logger; -import org.gradle.api.logging.Logging; import org.gradle.api.model.ObjectFactory; +import org.gradle.api.tasks.TaskProvider; import org.gradle.util.Configurable; -import org.implab.gradle.common.utils.Closures; +import org.implab.gradle.common.core.lang.Closures; import groovy.lang.Closure; +/** + * A configurable source set abstraction with named output roles. + * + *

+ * Each instance aggregates multiple {@link SourceDirectorySet source sets} + * under a shared name and exposes typed outputs that must be declared up front. + * Default locations are {@code src/} for sources and + * {@code build/} for outputs, both of which can be customized via the + * exposed {@link DirectoryProperty} setters. + *

+ * + *

+ * Outputs are grouped by roles to make task wiring explicit. A role must be + * declared with {@link #declareRoles(String, String...)} (or the synonym + * {@link #declareOutputs(String, String...)}) before files can be registered + * against it. Attempting to register or retrieve an undeclared role results in + * {@link InvalidUserDataException}. + *

+ */ public abstract class GenericSourceSet implements Named, Configurable { - private final Logger logger = Logging.getLogger(GenericSourceSet.class); - private final String name; private final NamedDomainObjectContainer sourceDirectorySets; - private final NamedDomainObjectContainer outputs; + private final Map outputs; private final FileCollection allOutputs; @@ -41,7 +63,7 @@ public abstract class GenericSourceSet private final ObjectFactory objects; - private final Set declaredOutputs = new HashSet<>(); + private final Set declaredRoles = new HashSet<>(); @Inject public GenericSourceSet(String name, ObjectFactory objects, ProjectLayout layout) { @@ -52,14 +74,12 @@ public abstract class GenericSourceSet SourceDirectorySet.class, this::createSourceDirectorySet); - outputs = objects.domainObjectContainer(GenericSourceSetOutput.class); + outputs = new LinkedHashMap<>(); allSourceDirectories = objects.fileCollection().from(sourceDirectoriesProvider()); allOutputs = objects.fileCollection().from(outputsProvider()); - outputs.addRule("Register a declared set on demand", this::registerOutputOnDemand); - getSourceSetDir().convention(layout .getProjectDirectory() .dir(Paths.get("src", name).toString())); @@ -74,57 +94,109 @@ public abstract class GenericSourceSet return name; } + /** + * Base directory for this source set. Defaults to {@code src/} under + * the project directory. + */ public abstract DirectoryProperty getSourceSetDir(); + /** + * Base directory for outputs of this source set. Defaults to + * {@code build/}. + */ public abstract DirectoryProperty getOutputsDir(); + /** + * The container of {@link SourceDirectorySet} instances that belong to this + * logical source set. + */ public NamedDomainObjectContainer getSets() { return sourceDirectorySets; } - public NamedDomainObjectContainer getOutputs() { - return outputs; - } - + /** + * All registered outputs grouped across roles. + */ public FileCollection getAllOutputs() { return allOutputs; } + /** + * All source directories from every contained {@link SourceDirectorySet}. + */ public FileCollection getAllSourceDirectories() { return allSourceDirectories; } - public FileCollection output(String name) { - return getOutputs().getAt(name).getFileCollection(); + /** + * Returns the file collection for the specified output role, creating it + * if necessary. + * + * @throws InvalidUserDataException if the role was not declared + */ + public ConfigurableFileCollection output(String name) { + requireDeclaredRole(name); + return outputs.computeIfAbsent(name, key -> objects.fileCollection()); } - public void declareOutputs(String name, String... extra) { - declaredOutputs.add(Objects.requireNonNull(name, "declareOutputs: The output name cannot be null")); + /** + * Declares allowed output roles. Roles must be declared before registering + * files under them. + */ + public void declareRoles(String name, String... extra) { + declaredRoles.add(Objects.requireNonNull(name, "declareRoles: The output name cannot be null")); for (var x : extra) - declaredOutputs.add(Objects.requireNonNull(x, "declareOutputs: The output name cannot be null")); + declaredRoles.add(Objects.requireNonNull(x, "declareRoles: The output name cannot be null")); } - @Override - public GenericSourceSet configure(@SuppressWarnings("rawtypes") Closure configure) { - Closures.apply(configure, this); - return this; + /** + * Alias for {@link #declareRoles(String, String...)} kept for DSL clarity. + */ + public void declareOutputs(String name, String... extra) { + declareRoles(name, extra); + } + + /** + * Registers files produced elsewhere under the given role. + */ + public void registerOutput(String name, Object... files) { + output(name).from(files); } - private void registerOutputOnDemand(String outputName) { - logger.info("SourceSet '{}': registerOutputOnDemand '{}'", name, outputName); + /** + * Registers output files produced by a task, using a mapper to extract the + * output from the task. The task will be added as a build dependency of this + * output. + */ + public void registerOutput(String name, TaskProvider task, + Function mapper) { + output(name).from(task.map(mapper::apply)) + .builtBy(task); + } - if (declaredOutputs.contains(outputName)) - outputs.register(outputName); + /** + * Applies a Groovy closure to this source set, enabling DSL-style + * configuration. + */ + @Override + public GenericSourceSet configure(Closure configure) { + Closures.apply(configure, this); + return this; } private SourceDirectorySet createSourceDirectorySet(String name) { return objects.sourceDirectorySet(name, name); } + private void requireDeclaredRole(String roleName) { + if (!declaredRoles.contains(roleName)) { + throw new InvalidUserDataException( + "Output role '" + roleName + "' is not declared for source set '" + name + "'"); + } + } + private Callable> outputsProvider() { - return () -> outputs.stream() - .map(GenericSourceSetOutput::getFileCollection) - .toList(); + return () -> outputs.values().stream().toList(); } private Callable> sourceDirectoriesProvider() { diff --git a/common/src/main/java/org/implab/gradle/common/SourcesPlugin.java b/common/src/main/java/org/implab/gradle/common/sources/SourcesPlugin.java rename from common/src/main/java/org/implab/gradle/common/SourcesPlugin.java rename to common/src/main/java/org/implab/gradle/common/sources/SourcesPlugin.java --- a/common/src/main/java/org/implab/gradle/common/SourcesPlugin.java +++ b/common/src/main/java/org/implab/gradle/common/sources/SourcesPlugin.java @@ -1,4 +1,4 @@ -package org.implab.gradle.common; +package org.implab.gradle.common.sources; import org.gradle.api.Action; import org.gradle.api.Plugin; @@ -10,8 +10,7 @@ import org.gradle.api.tasks.Delete; import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.TaskProvider; import org.gradle.language.base.plugins.LifecycleBasePlugin; -import org.implab.gradle.common.files.GenericSourceSet; -import org.implab.gradle.common.utils.Strings; +import org.implab.gradle.common.core.lang.Strings; /** * This plugin creates a {@code sources} extension which is