From 7da1b929d6d90391529986610d1783d4a5a59641 Mon Sep 17 00:00:00 2001 From: Eleanor Joslin Date: Fri, 28 Nov 2025 16:18:58 +0000 Subject: [PATCH 1/4] Refactor BndPlugin to remove fields. Signed-off-by: Eleanor Joslin --- .../main/java/aQute/bnd/gradle/BndPlugin.java | 222 ++++++++++-------- 1 file changed, 118 insertions(+), 104 deletions(-) diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java index 2b3dc1b12b..a92e8cb2b2 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java @@ -55,7 +55,6 @@ import org.gradle.api.file.FileCollection; import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.SourceDirectorySet; -import org.gradle.api.internal.plugins.DslObject; import org.gradle.api.logging.Logger; import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.BasePluginExtension; @@ -66,6 +65,7 @@ import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; +import org.gradle.api.provider.ProviderFactory; import org.gradle.api.publish.plugins.PublishingPlugin; import org.gradle.api.tasks.ClasspathNormalizer; import org.gradle.api.tasks.Delete; @@ -82,6 +82,8 @@ import org.gradle.process.CommandLineArgumentProvider; import org.slf4j.LoggerFactory; +import javax.inject.Inject; + /** * BndPlugin for Gradle. *

@@ -98,10 +100,6 @@ public class BndPlugin implements Plugin { * Name of the plugin. */ public static final String PLUGINID = "biz.aQute.bnd"; - private Project project; - private Project workspace; - private ObjectFactory objects; - private aQute.bnd.build.Project bndProject; /** * Default public constructor. @@ -114,10 +112,9 @@ public BndPlugin() {} @Override public void apply(Project project) { try { - this.project = project; - Project workspace = this.workspace = project.getParent(); + Project workspace = project.getParent(); ProjectLayout layout = project.getLayout(); - ObjectFactory objects = this.objects = project.getObjects(); + ObjectFactory objects = project.getObjects(); TaskContainer tasks = project.getTasks(); if (project.getPluginManager() .hasPlugin(BndBuilderPlugin.PLUGINID)) { @@ -129,7 +126,8 @@ public void apply(Project project) { + BndBuilderPlugin.PLUGINID + "\" plugin?"); } Workspace bndWorkspace = BndWorkspacePlugin.getBndWorkspace(workspace); - aQute.bnd.build.Project bndProject = this.bndProject = bndWorkspace.getProject(project.getName()); + aQute.bnd.build.Project bndProject = bndWorkspace.getProject(project.getName()); + PluginApplicationHelper helper = new PluginApplicationHelper(workspace, bndProject, project.getProviders(), objects); if (Objects.isNull(bndProject)) { throw new GradleException(String.format("Unable to load bnd project %s from workspace %s", project.getName(), workspace.getLayout() @@ -137,7 +135,7 @@ public void apply(Project project) { } bndProject.prepare(); if (!bndProject.isValid()) { - checkErrors(project.getLogger()); + helper.checkErrors(project.getLogger()); throw new GradleException(String.format("Project %s is not a valid bnd project", bndProject.getName())); } BndPluginExtension extension = project.getExtensions() @@ -200,14 +198,14 @@ public void apply(Project project) { .withPropertyName("generateInputs"); /* bnd can include from -dependson */ t.getInputs() - .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) + .files(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); /* * Workspace and project configuration changes should * trigger task */ t.getInputs() - .files(bndConfiguration()) + .files(helper.bndConfiguration()) .withPathSensitivity(RELATIVE) .withPropertyName("bndConfiguration") .normalizeLineEndings(); @@ -225,7 +223,7 @@ public void execute(Task tt) { } catch (Exception e) { throw new GradleException(String.format("Project %s failed to generate", bndProject.getName()), e); } - checkErrors(tt.getLogger()); + helper.checkErrors(tt.getLogger()); } }); })); @@ -375,10 +373,10 @@ public void execute(Task tt) { .set("allSrcDirs", allSrcDirs); /* Set up dependencies */ DependencyHandler dependencies = project.getDependencies(); - dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, pathFiles(bndProject.getBuildpath())); + dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, helper.pathFiles(bndProject.getBuildpath())); dependencies.add(JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME, objects.fileCollection() .from(bndProject.getSrcOutput())); - dependencies.add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, pathFiles(bndProject.getTestpath())); + dependencies.add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, helper.pathFiles(bndProject.getTestpath())); dependencies.add(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME, objects.fileCollection() .from(bndProject.getTestOutput())); /* Set up compile tasks */ @@ -446,7 +444,7 @@ public void execute(Task tt) { @Override public void execute(Task tt) { Logger logger = tt.getLogger(); - checkErrors(logger); + helper.checkErrors(logger); if (logger.isInfoEnabled()) { logger.info("Compile to {}", unwrapFile(t.getDestinationDirectory())); if (t.getOptions() @@ -527,14 +525,14 @@ public void execute(Task tt) { .withPropertyName("buildpath"); /* bnd can include from -dependson */ t.getInputs() - .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) + .files(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); /* * Workspace and project configuration changes should * trigger jar task */ t.getInputs() - .files(bndConfiguration()) + .files(helper.bndConfiguration()) .withPathSensitivity(RELATIVE) .withPropertyName("bndConfiguration") .normalizeLineEndings(); @@ -561,7 +559,7 @@ public void execute(Task tt) { throw new GradleException( String.format("Project %s failed to build", bndProject.getName()), e); } - checkErrors(tt.getLogger()); + helper.checkErrors(tt.getLogger()); if (Objects.nonNull(built)) { tt.getLogger() .info("Generated bundles: {}", (Object) built); @@ -573,13 +571,13 @@ public void execute(Task tt) { TaskProvider jarDependencies = tasks.register("jarDependencies", t -> { t.setDescription("Jar all projects this project depends on."); t.setGroup(LifecycleBasePlugin.BUILD_GROUP); - t.dependsOn(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)); + t.dependsOn(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)); }); TaskProvider buildDependencies = tasks.register("buildDependencies", t -> { t.setDescription("Assembles and tests all projects this project depends on."); t.setGroup(LifecycleBasePlugin.BUILD_GROUP); - t.dependsOn(getTestDependencies(JavaBasePlugin.BUILD_NEEDED_TASK_NAME)); + t.dependsOn(helper.getTestDependencies(JavaBasePlugin.BUILD_NEEDED_TASK_NAME)); }); TaskProvider buildNeeded = tasks.named(JavaBasePlugin.BUILD_NEEDED_TASK_NAME, t -> { @@ -587,7 +585,7 @@ public void execute(Task tt) { }); TaskProvider buildDependents = tasks.named(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, t -> { - t.dependsOn(getDependents(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME)); + t.dependsOn(helper.getDependents(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME)); }); TaskProvider release = tasks.register("release", t -> { @@ -607,7 +605,7 @@ public void execute(Task tt) { throw new GradleException( String.format("Project %s failed to release", bndProject.getName()), e); } - checkErrors(tt.getLogger()); + helper.checkErrors(tt.getLogger()); } }); }); @@ -615,7 +613,7 @@ public void execute(Task tt) { TaskProvider releaseDependencies = tasks.register("releaseDependencies", t -> { t.setDescription("Release all projects this project depends on."); t.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP); - t.dependsOn(getBuildDependencies("releaseNeeded")); + t.dependsOn(helper.getBuildDependencies("releaseNeeded")); }); TaskProvider releaseNeeded = tasks.register("releaseNeeded", t -> { @@ -628,12 +626,12 @@ public void execute(Task tt) { t.setEnabled(!bndProject.is(Constants.NOJUNIT) && !bndProject.is("no.junit")); /* tests can depend upon jars from -dependson */ t.getInputs() - .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) + .files(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); t.doFirst("checkErrors", new Action<>() { @Override public void execute(Task tt) { - checkErrors(tt.getLogger(), t.getIgnoreFailures()); + helper.checkErrors(tt.getLogger(), t.getIgnoreFailures()); } }); }); @@ -658,7 +656,7 @@ public void execute(Task tt) { TaskProvider checkDependencies = tasks.register("checkDependencies", t -> { t.setDescription("Runs all checks on all projects this project depends on."); t.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP); - t.dependsOn(getTestDependencies("checkNeeded")); + t.dependsOn(helper.getTestDependencies("checkNeeded")); }); TaskProvider checkNeeded = tasks.register("checkNeeded", t -> { @@ -679,7 +677,7 @@ public void execute(Task tt) { TaskProvider cleanDependencies = tasks.register("cleanDependencies", t -> { t.setDescription("Cleans all projects this project depends on."); t.setGroup(LifecycleBasePlugin.BUILD_GROUP); - t.dependsOn(getTestDependencies("cleanNeeded")); + t.dependsOn(helper.getTestDependencies("cleanNeeded")); }); TaskProvider cleanNeeded = tasks.register("cleanNeeded", t -> { @@ -837,7 +835,7 @@ public void execute(Task tt) { } System.out.print(f.toString()); } - checkErrors(tt.getLogger(), true); + helper.checkErrors(tt.getLogger(), true); } }); }); @@ -860,7 +858,7 @@ public void execute(Task tt) { f.format("%n"); System.out.print(f.toString()); } - checkErrors(tt.getLogger(), true); + helper.checkErrors(tt.getLogger(), true); } }); }); @@ -888,55 +886,109 @@ public void execute(Task tt) { } } - private Provider>> getTasks(Collection projects, - String taskName) { - return project.provider(() -> projects.stream() - .map(p -> workspace.project(p.getName()) - .getTasks() - .named(taskName)) - .collect(toList())); - } + private static class PluginApplicationHelper { - private ConfigurableFileCollection pathFiles(Collection path) { - return objects.fileCollection() - .from(decontainer(path)) - .builtBy(getTasks(path.stream() - .filter(c -> c.getType() == TYPE.PROJECT) - .map(Container::getProject) - .collect(toList()), JavaPlugin.JAR_TASK_NAME)); - } + private final Project workspace; + private final aQute.bnd.build.Project bndProject; + private final ProviderFactory providers; + private final ObjectFactory objects; - private Provider>> getBuildDependencies(String taskName) { - try { - return getTasks(bndProject.getBuildDependencies(), taskName); - } catch (Exception e) { - throw Exceptions.duck(e); + public PluginApplicationHelper(Project workspace, aQute.bnd.build.Project bndProject, ProviderFactory providers, ObjectFactory objects) { + this.workspace = workspace; + this.bndProject = bndProject; + this.providers = providers; + this.objects = objects; } - } - private Provider>> getTestDependencies(String taskName) { - try { - return getTasks(bndProject.getTestDependencies(), taskName); - } catch (Exception e) { - throw Exceptions.duck(e); + private Provider>> getTasks(Collection projects, + String taskName) { + return providers.provider(() -> projects.stream() + .map(p -> workspace.project(p.getName()) + .getTasks() + .named(taskName)) + .collect(toList())); } - } - private Provider>> getDependents(String taskName) { - try { - return getTasks(bndProject.getDependents(), taskName); - } catch (Exception e) { - throw Exceptions.duck(e); + private ConfigurableFileCollection pathFiles(Collection path) { + return objects.fileCollection() + .from(decontainer(path)) + .builtBy(getTasks(path.stream() + .filter(c -> c.getType() == TYPE.PROJECT) + .map(Container::getProject) + .collect(toList()), JavaPlugin.JAR_TASK_NAME)); + } + + private Provider>> getBuildDependencies(String taskName) { + try { + return getTasks(bndProject.getBuildDependencies(), taskName); + } catch (Exception e) { + throw Exceptions.duck(e); + } + } + + private Provider>> getTestDependencies(String taskName) { + try { + return getTasks(bndProject.getTestDependencies(), taskName); + } catch (Exception e) { + throw Exceptions.duck(e); + } + } + + private Provider>> getDependents(String taskName) { + try { + return getTasks(bndProject.getDependents(), taskName); + } catch (Exception e) { + throw Exceptions.duck(e); + } + } + + private ConfigurableFileCollection bndConfiguration() { + Workspace bndWorkspace = bndProject.getWorkspace(); + return objects.fileCollection() + .from(bndWorkspace.getPropertiesFile(), bndWorkspace.getIncluded(), bndProject.getPropertiesFile(), + bndProject.getIncluded()); + } + + private void checkErrors(Logger logger) { + checkProjectErrors(bndProject, logger, false); + } + + private void checkErrors(Logger logger, boolean ignoreFailures) { + checkProjectErrors(bndProject, logger, ignoreFailures); + } + + private void checkProjectErrors(aQute.bnd.build.Project p, Logger logger, boolean ignoreFailures) { + p.getInfo(p.getWorkspace(), p.getWorkspace() + .getBase() + .getName() + .concat(" :")); + boolean failed = !ignoreFailures && !p.isOk(); + int errorCount = p.getErrors() + .size(); + logReport(p, logger); + p.clear(); + if (failed) { + String str; + if (errorCount == 1) { + str = "%s has errors, one error was reported"; + } else if (errorCount > 1) { + str = "%s has errors, %s errors were reported"; + } else { + str = "%s has errors even though no errors were reported"; + } + throw new GradleException(String.format(str, p.getName(), errorCount)); + } } + } - private List decontainer(Collection path) { + private static List decontainer(Collection path) { return path.stream() .map(Container::getFile) .collect(toList()); } - private > CommandLineArgumentProvider argProvider(Optional provider) { + private static > CommandLineArgumentProvider argProvider(Optional provider) { return new CommandLineArgumentProvider() { @SuppressWarnings("unchecked") @Override @@ -946,45 +998,7 @@ public Iterable asArguments() { }; } - private ConfigurableFileCollection bndConfiguration() { - Workspace bndWorkspace = bndProject.getWorkspace(); - return objects.fileCollection() - .from(bndWorkspace.getPropertiesFile(), bndWorkspace.getIncluded(), bndProject.getPropertiesFile(), - bndProject.getIncluded()); - } - - private void checkErrors(Logger logger) { - checkProjectErrors(bndProject, logger, false); - } - - private void checkErrors(Logger logger, boolean ignoreFailures) { - checkProjectErrors(bndProject, logger, ignoreFailures); - } - - private void checkProjectErrors(aQute.bnd.build.Project p, Logger logger, boolean ignoreFailures) { - p.getInfo(p.getWorkspace(), p.getWorkspace() - .getBase() - .getName() - .concat(" :")); - boolean failed = !ignoreFailures && !p.isOk(); - int errorCount = p.getErrors() - .size(); - logReport(p, logger); - p.clear(); - if (failed) { - String str; - if (errorCount == 1) { - str = "%s has errors, one error was reported"; - } else if (errorCount > 1) { - str = "%s has errors, %s errors were reported"; - } else { - str = "%s has errors even though no errors were reported"; - } - throw new GradleException(String.format(str, p.getName(), errorCount)); - } - } - - private Optional optional(String value) { + private static Optional optional(String value) { return Optional.ofNullable(value).filter(Strings::notEmpty); } From ac9e9ccba783cc7d148c9f85e82072b0c1793d50 Mon Sep 17 00:00:00 2001 From: Eleanor Joslin Date: Fri, 28 Nov 2025 16:45:14 +0000 Subject: [PATCH 2/4] Move all the plugin application logic into the helper. Signed-off-by: Eleanor Joslin --- .../main/java/aQute/bnd/gradle/BndPlugin.java | 102 ++++++++++-------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java index a92e8cb2b2..114fdfef75 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java @@ -113,9 +113,6 @@ public BndPlugin() {} public void apply(Project project) { try { Project workspace = project.getParent(); - ProjectLayout layout = project.getLayout(); - ObjectFactory objects = project.getObjects(); - TaskContainer tasks = project.getTasks(); if (project.getPluginManager() .hasPlugin(BndBuilderPlugin.PLUGINID)) { throw new GradleException("Project already has \"" + BndBuilderPlugin.PLUGINID + "\" plugin applied."); @@ -127,7 +124,34 @@ public void apply(Project project) { } Workspace bndWorkspace = BndWorkspacePlugin.getBndWorkspace(workspace); aQute.bnd.build.Project bndProject = bndWorkspace.getProject(project.getName()); - PluginApplicationHelper helper = new PluginApplicationHelper(workspace, bndProject, project.getProviders(), objects); + PluginApplicationHelper helper = new PluginApplicationHelper(project, workspace, bndProject); + helper.doApplyPlugin(); + } catch (Exception e) { + throw Exceptions.duck(e); + } + } + + private static class PluginApplicationHelper { + + private final Project project; + private final Project workspace; + private final aQute.bnd.build.Project bndProject; + private final ProviderFactory providers; + private final ObjectFactory objects; + private final TaskContainer tasks; + private final ProjectLayout layout; + + public PluginApplicationHelper(Project project, Project workspace, aQute.bnd.build.Project bndProject) { + this.project = project; + this.workspace = workspace; + this.bndProject = bndProject; + this.providers = project.getProviders(); + this.objects = project.getObjects(); + this.tasks = project.getTasks(); + this.layout = project.getLayout(); + } + + public void doApplyPlugin() throws Exception { if (Objects.isNull(bndProject)) { throw new GradleException(String.format("Unable to load bnd project %s from workspace %s", project.getName(), workspace.getLayout() @@ -135,7 +159,7 @@ public void apply(Project project) { } bndProject.prepare(); if (!bndProject.isValid()) { - helper.checkErrors(project.getLogger()); + checkErrors(project.getLogger()); throw new GradleException(String.format("Project %s is not a valid bnd project", bndProject.getName())); } BndPluginExtension extension = project.getExtensions() @@ -198,14 +222,14 @@ public void apply(Project project) { .withPropertyName("generateInputs"); /* bnd can include from -dependson */ t.getInputs() - .files(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) + .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); /* * Workspace and project configuration changes should * trigger task */ t.getInputs() - .files(helper.bndConfiguration()) + .files(bndConfiguration()) .withPathSensitivity(RELATIVE) .withPropertyName("bndConfiguration") .normalizeLineEndings(); @@ -223,7 +247,7 @@ public void execute(Task tt) { } catch (Exception e) { throw new GradleException(String.format("Project %s failed to generate", bndProject.getName()), e); } - helper.checkErrors(tt.getLogger()); + checkErrors(tt.getLogger()); } }); })); @@ -373,10 +397,10 @@ public void execute(Task tt) { .set("allSrcDirs", allSrcDirs); /* Set up dependencies */ DependencyHandler dependencies = project.getDependencies(); - dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, helper.pathFiles(bndProject.getBuildpath())); + dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, pathFiles(bndProject.getBuildpath())); dependencies.add(JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME, objects.fileCollection() .from(bndProject.getSrcOutput())); - dependencies.add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, helper.pathFiles(bndProject.getTestpath())); + dependencies.add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, pathFiles(bndProject.getTestpath())); dependencies.add(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME, objects.fileCollection() .from(bndProject.getTestOutput())); /* Set up compile tasks */ @@ -407,7 +431,7 @@ public void execute(Task tt) { options.getRelease() .convention(project.provider(() -> { if (supportsRelease.getOrElse(Boolean.valueOf(JavaVersion.current() - .isJava9Compatible())) + .isJava9Compatible())) .booleanValue()) { JavaVersion sourceVersion = JavaVersion.toVersion(javacSource.get()); JavaVersion targetVersion = JavaVersion.toVersion(javacTarget.get()); @@ -444,7 +468,7 @@ public void execute(Task tt) { @Override public void execute(Task tt) { Logger logger = tt.getLogger(); - helper.checkErrors(logger); + checkErrors(logger); if (logger.isInfoEnabled()) { logger.info("Compile to {}", unwrapFile(t.getDestinationDirectory())); if (t.getOptions() @@ -452,8 +476,8 @@ public void execute(Task tt) { .isPresent()) { logger.info("--release {} {}", unwrap(t.getOptions() .getRelease()), Strings.join(" ", - t.getOptions() - .getAllCompilerArgs())); + t.getOptions() + .getAllCompilerArgs())); } else { logger.info("-source {} -target {} {}", t.getSourceCompatibility(), t.getTargetCompatibility(), Strings.join(" ", t.getOptions() @@ -525,14 +549,14 @@ public void execute(Task tt) { .withPropertyName("buildpath"); /* bnd can include from -dependson */ t.getInputs() - .files(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) + .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); /* * Workspace and project configuration changes should * trigger jar task */ t.getInputs() - .files(helper.bndConfiguration()) + .files(bndConfiguration()) .withPathSensitivity(RELATIVE) .withPropertyName("bndConfiguration") .normalizeLineEndings(); @@ -559,7 +583,7 @@ public void execute(Task tt) { throw new GradleException( String.format("Project %s failed to build", bndProject.getName()), e); } - helper.checkErrors(tt.getLogger()); + checkErrors(tt.getLogger()); if (Objects.nonNull(built)) { tt.getLogger() .info("Generated bundles: {}", (Object) built); @@ -571,13 +595,13 @@ public void execute(Task tt) { TaskProvider jarDependencies = tasks.register("jarDependencies", t -> { t.setDescription("Jar all projects this project depends on."); t.setGroup(LifecycleBasePlugin.BUILD_GROUP); - t.dependsOn(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)); + t.dependsOn(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)); }); TaskProvider buildDependencies = tasks.register("buildDependencies", t -> { t.setDescription("Assembles and tests all projects this project depends on."); t.setGroup(LifecycleBasePlugin.BUILD_GROUP); - t.dependsOn(helper.getTestDependencies(JavaBasePlugin.BUILD_NEEDED_TASK_NAME)); + t.dependsOn(getTestDependencies(JavaBasePlugin.BUILD_NEEDED_TASK_NAME)); }); TaskProvider buildNeeded = tasks.named(JavaBasePlugin.BUILD_NEEDED_TASK_NAME, t -> { @@ -585,7 +609,7 @@ public void execute(Task tt) { }); TaskProvider buildDependents = tasks.named(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, t -> { - t.dependsOn(helper.getDependents(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME)); + t.dependsOn(getDependents(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME)); }); TaskProvider release = tasks.register("release", t -> { @@ -605,7 +629,7 @@ public void execute(Task tt) { throw new GradleException( String.format("Project %s failed to release", bndProject.getName()), e); } - helper.checkErrors(tt.getLogger()); + checkErrors(tt.getLogger()); } }); }); @@ -613,7 +637,7 @@ public void execute(Task tt) { TaskProvider releaseDependencies = tasks.register("releaseDependencies", t -> { t.setDescription("Release all projects this project depends on."); t.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP); - t.dependsOn(helper.getBuildDependencies("releaseNeeded")); + t.dependsOn(getBuildDependencies("releaseNeeded")); }); TaskProvider releaseNeeded = tasks.register("releaseNeeded", t -> { @@ -626,12 +650,12 @@ public void execute(Task tt) { t.setEnabled(!bndProject.is(Constants.NOJUNIT) && !bndProject.is("no.junit")); /* tests can depend upon jars from -dependson */ t.getInputs() - .files(helper.getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) + .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); t.doFirst("checkErrors", new Action<>() { @Override public void execute(Task tt) { - helper.checkErrors(tt.getLogger(), t.getIgnoreFailures()); + checkErrors(tt.getLogger(), t.getIgnoreFailures()); } }); }); @@ -656,7 +680,7 @@ public void execute(Task tt) { TaskProvider checkDependencies = tasks.register("checkDependencies", t -> { t.setDescription("Runs all checks on all projects this project depends on."); t.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP); - t.dependsOn(helper.getTestDependencies("checkNeeded")); + t.dependsOn(getTestDependencies("checkNeeded")); }); TaskProvider checkNeeded = tasks.register("checkNeeded", t -> { @@ -668,7 +692,7 @@ public void execute(Task tt) { TaskProvider clean = tasks.named(LifecycleBasePlugin.CLEAN_TASK_NAME, Delete.class, t -> { t.setDescription("Cleans the build and compiler output directories of this project."); t.delete(layout.getBuildDirectory(), sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) - .getOutput(), + .getOutput(), sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME) .getOutput()); generate.ifPresent(t::delete); @@ -677,7 +701,7 @@ public void execute(Task tt) { TaskProvider cleanDependencies = tasks.register("cleanDependencies", t -> { t.setDescription("Cleans all projects this project depends on."); t.setGroup(LifecycleBasePlugin.BUILD_GROUP); - t.dependsOn(helper.getTestDependencies("cleanNeeded")); + t.dependsOn(getTestDependencies("cleanNeeded")); }); TaskProvider cleanNeeded = tasks.register("cleanNeeded", t -> { @@ -815,8 +839,8 @@ public void execute(Task tt) { } f.format("project.deliverables: %s%n", deliverables.getFiles()); String executable = Optional.ofNullable(compileJava.getOptions() - .getForkOptions() - .getExecutable()) + .getForkOptions() + .getExecutable()) .orElseGet(() -> compileJava.getJavaCompiler() .map(javaCompiler -> IO.absolutePath(unwrapFile(javaCompiler.getExecutablePath()))) .getOrElse("javac")); @@ -835,7 +859,7 @@ public void execute(Task tt) { } System.out.print(f.toString()); } - helper.checkErrors(tt.getLogger(), true); + checkErrors(tt.getLogger(), true); } }); }); @@ -858,7 +882,7 @@ public void execute(Task tt) { f.format("%n"); System.out.print(f.toString()); } - helper.checkErrors(tt.getLogger(), true); + checkErrors(tt.getLogger(), true); } }); }); @@ -881,23 +905,7 @@ public void execute(Task tt) { .dir(resource) .withPropertyName(category))); }); - } catch (Exception e) { - throw Exceptions.duck(e); - } - } - - private static class PluginApplicationHelper { - private final Project workspace; - private final aQute.bnd.build.Project bndProject; - private final ProviderFactory providers; - private final ObjectFactory objects; - - public PluginApplicationHelper(Project workspace, aQute.bnd.build.Project bndProject, ProviderFactory providers, ObjectFactory objects) { - this.workspace = workspace; - this.bndProject = bndProject; - this.providers = providers; - this.objects = objects; } private Provider>> getTasks(Collection projects, From 7437b4cfdf6458c521598e5d6a4b85747ed4e2a9 Mon Sep 17 00:00:00 2001 From: Eleanor Joslin Date: Fri, 28 Nov 2025 17:01:51 +0000 Subject: [PATCH 3/4] Enable the configuration cache in BndPlugin tests. Signed-off-by: Eleanor Joslin --- .../aQute/bnd/gradle/TestBndPlugin.groovy | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBndPlugin.groovy b/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBndPlugin.groovy index 99eb695a46..c1f0bab56f 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBndPlugin.groovy +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBndPlugin.groovy @@ -37,7 +37,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "build", "release") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "build", "release") .forwardOutput() .build() @@ -89,7 +89,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "echo", "bndproperties", ":tasks") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "echo", "bndproperties", ":tasks") .forwardOutput() .build() @@ -108,7 +108,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--continue", ":test.simple:resolve", ":test.simple:resolve2") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--continue", ":test.simple:resolve", ":test.simple:resolve2") .forwardOutput() .buildAndFail() @@ -176,7 +176,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--continue", ":test.simple:export", ":test.simple:runbundles", ":test.simple:export2", ":test.simple:export3") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--continue", ":test.simple:export", ":test.simple:runbundles", ":test.simple:export2", ":test.simple:export3") .forwardOutput() .build() @@ -233,7 +233,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", ":tasks") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", ":tasks") .forwardOutput() .build() @@ -250,7 +250,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "build", "release") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "build", "release") .forwardOutput() .build() @@ -297,7 +297,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "build", "release") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "build", "release") .forwardOutput() .build() @@ -344,7 +344,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "build", "release") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "build", "release") .forwardOutput() .build() @@ -396,7 +396,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "check", "--exclude-task", "testrun.testOSGi2") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "check", "--exclude-task", "testrun.testOSGi2") .forwardOutput() .build() @@ -435,7 +435,7 @@ class TestBndPlugin extends Specification { when: result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "testrun.testOSGi2") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "testrun.testOSGi2") .forwardOutput() .buildAndFail() @@ -445,7 +445,7 @@ class TestBndPlugin extends Specification { when: result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "testrun.testOSGi2", "--tests=test.simple.Test") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "testrun.testOSGi2", "--tests=test.simple.Test") .forwardOutput() .build() @@ -455,7 +455,7 @@ class TestBndPlugin extends Specification { when: result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "testrun.testOSGi2", "--tests=test.simple.ProjectNameTest") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "testrun.testOSGi2", "--tests=test.simple.ProjectNameTest") .forwardOutput() .build() @@ -474,7 +474,7 @@ class TestBndPlugin extends Specification { when: def result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "build", "release") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "build", "release") .forwardOutput() .build() @@ -505,7 +505,7 @@ class TestBndPlugin extends Specification { when: result = TestHelper.getGradleRunner() .withProjectDir(testProjectDir) - .withArguments("-Pbnd_plugin=${pluginClasspath}", "--parallel", "--stacktrace", "--debug", "clean") + .withArguments("-Pbnd_plugin=${pluginClasspath}", "--configuration-cache", "--parallel", "--stacktrace", "--debug", "clean") .forwardOutput() .build() From 63170001296ea24f32d408745d12c3b7664279e8 Mon Sep 17 00:00:00 2001 From: Eleanor Joslin Date: Sat, 29 Nov 2025 00:32:24 +0000 Subject: [PATCH 4/4] Make task actions compatible with configuration cache. Extract them to static classes to prevent them holding onto anything they shouldn't. Signed-off-by: Eleanor Joslin --- .../main/java/aQute/bnd/gradle/BndPlugin.java | 464 ++++++++++-------- .../aQute/bnd/gradle/BndWorkspacePlugin.java | 7 +- 2 files changed, 268 insertions(+), 203 deletions(-) diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java index 114fdfef75..b93ea12267 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java @@ -6,6 +6,7 @@ import static aQute.bnd.gradle.BndUtils.sourceSets; import static aQute.bnd.gradle.BndUtils.unwrap; import static aQute.bnd.gradle.BndUtils.unwrapFile; +import static aQute.bnd.osgi.Processor.getScheduledExecutor; import static aQute.bnd.osgi.Processor.isTrue; import static aQute.bnd.osgi.Processor.removeDuplicateMarker; import static java.lang.invoke.MethodHandles.publicLookup; @@ -80,10 +81,9 @@ import org.gradle.api.tasks.testing.AbstractTestTask; import org.gradle.language.base.plugins.LifecycleBasePlugin; import org.gradle.process.CommandLineArgumentProvider; +import org.jetbrains.annotations.NotNull; import org.slf4j.LoggerFactory; -import javax.inject.Inject; - /** * BndPlugin for Gradle. *

@@ -131,6 +131,230 @@ public void apply(Project project) { } } + /** + * {@link Action} that gives access to a Bnd project without retaining references to it. + * This helps with configuration cache compatibility. + */ + private static abstract class BndProjectUsingTaskAction implements Action { + + @Override + public final void execute(final Task t) { + // This project has had BndPlugin applied to it, so Bnd objects must already exist. + Project project = t.getProject(); + Project workspace = project.getParent(); + Workspace bndWorkspace = (Workspace) workspace.findProperty(BndWorkspacePlugin.BND_WORKSPACE_PROPERTY); + aQute.bnd.build.Project bndProject = bndWorkspace.getProject(project.getName()); + execute(t, bndProject); + } + + protected abstract void execute(Task task, aQute.bnd.build.Project bndProject); + } + + /** + * Action for the "generate" task. + */ + private static final class GenerateTaskAction extends BndProjectUsingTaskAction { + @Override + public void execute(Task tt, aQute.bnd.build.Project bndProject) { + try { + bndProject.getGenerate() + .generate(false); + } catch (Exception e) { + throw new GradleException(String.format("Project %s failed to generate", bndProject.getName()), e); + } + checkProjectErrors(bndProject, tt.getLogger()); + } + } + + /** + * Action for the "jar" task. + */ + private static final class JarTaskBuildAction extends BndProjectUsingTaskAction { + @Override + public void execute(Task tt, aQute.bnd.build.Project bndProject) { + File[] built; + try { + built = bndProject.build(); + if (Objects.nonNull(built)) { + long now = System.currentTimeMillis(); + for (File f : built) { + f.setLastModified(now); + } + } + } catch (Exception e) { + throw new GradleException( + String.format("Project %s failed to build", bndProject.getName()), e); + } + checkProjectErrors(bndProject, tt.getLogger()); + if (Objects.nonNull(built)) { + tt.getLogger() + .info("Generated bundles: {}", (Object) built); + } + } + } + + /** + * Action for the "release" task. + */ + private static final class ReleaseTaskAction extends BndProjectUsingTaskAction { + @Override + public void execute(Task tt, aQute.bnd.build.Project bndProject) { + try { + bndProject.release(); + } catch (Exception e) { + throw new GradleException( + String.format("Project %s failed to release", bndProject.getName()), e); + } + checkProjectErrors(bndProject, tt.getLogger()); + } + } + + /** + * Action for the "echo" task. + */ + private static final class EchoTaskAction extends BndProjectUsingTaskAction { + @Override + protected void execute(final Task task, final aQute.bnd.build.Project bndProject) { + final Project project = task.getProject(); + final Project workspace = project.getParent(); + final ProjectLayout layout = project.getLayout(); + final SourceSetContainer sourceSets = sourceSets(project); + final JavaCompile compileJava = unwrap(project.getTasks().named(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile.class)); + final JavaCompile compileTestJava = unwrap( + project.getTasks().named(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME, JavaCompile.class)); + final ObjectFactory objects = project.getObjects(); + final FileCollection deliverables = getDeliverables(project); + final Optional javacProfile = optional(bndProject.getProperty("javac.profile")); + try (Formatter f = new Formatter()) { + f.format("------------------------------------------------------------%n"); + f.format("Project %s // Bnd version %s%n", project.getName(), About.getBndVersion()); + f.format("------------------------------------------------------------%n"); + f.format("%n"); + f.format("project.workspace: %s%n", workspace.getLayout() + .getProjectDirectory()); + f.format("project.name: %s%n", project.getName()); + f.format("project.dir: %s%n", layout.getProjectDirectory()); + f.format("target: %s%n", unwrap(layout.getBuildDirectory())); + f.format("project.dependson: %s%n", bndProject.getDependson()); + f.format("project.sourcepath: %s%n", + sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) + .getAllSource() + .getSourceDirectories() + .getAsPath()); + f.format("project.output: %s%n", unwrap(compileJava.getDestinationDirectory())); + f.format("project.buildpath: %s%n", compileJava.getClasspath() + .getAsPath()); + f.format("project.allsourcepath: %s%n", objects.fileCollection().from(bndProject.getAllsourcepath()).getAsPath()); + f.format("project.testsrc: %s%n", + sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME) + .getAllSource() + .getSourceDirectories() + .getAsPath()); + f.format("project.testoutput: %s%n", unwrap(compileTestJava.getDestinationDirectory())); + f.format("project.testpath: %s%n", compileTestJava.getClasspath() + .getAsPath()); + if (Objects.nonNull(compileJava.getOptions() + .getBootstrapClasspath())) { + f.format("project.bootclasspath: %s%n", compileJava.getOptions() + .getBootstrapClasspath() + .getAsPath()); + } + f.format("project.deliverables: %s%n", deliverables.getFiles()); + String executable = Optional.ofNullable(compileJava.getOptions() + .getForkOptions() + .getExecutable()) + .orElseGet(() -> compileJava.getJavaCompiler() + .map(javaCompiler -> IO.absolutePath(unwrapFile(javaCompiler.getExecutablePath()))) + .getOrElse("javac")); + f.format("javac: %s%n", executable); + if (compileJava.getOptions() + .getRelease() + .isPresent()) { + f.format("--release: %s%n", unwrap(compileJava.getOptions() + .getRelease())); + } else { + f.format("-source: %s%n", compileJava.getSourceCompatibility()); + f.format("-target: %s%n", compileJava.getTargetCompatibility()); + } + if (javacProfile.isPresent()) { + f.format("-profile: %s%n", javacProfile.get()); + } + System.out.print(f.toString()); + } + catch (Exception e) { + throw new RuntimeException(e); + } + checkProjectErrors(bndProject, task.getLogger(), true); + } + } + + /** + * Action for the "bndproperties" task. + */ + private static final class BndpropertiesTaskAction extends BndProjectUsingTaskAction { + @Override + protected void execute(final Task task, final aQute.bnd.build.Project bndProject) { + try (Formatter f = new Formatter()) { + f.format("------------------------------------------------------------%n"); + f.format("Project %s // Bnd version %s%n", task.getProject().getName(), About.getBndVersion()); + f.format("------------------------------------------------------------%n"); + f.format("%n"); + bndProject.getPropertyKeys(true) + .stream() + .sorted() + .forEachOrdered(key -> f.format("%s: %s%n", key, bndProject.getProperty(key, ""))); + f.format("%n"); + System.out.print(f.toString()); + } + checkProjectErrors(bndProject, task.getLogger(), true); + } + } + + /** + * Action for a {@link JavaCompile} task. + */ + private static final class JavaCompileCheckErrorsAction extends BndProjectUsingTaskAction { + @Override + protected void execute(final Task task, final aQute.bnd.build.Project bndProject) { + final JavaCompile t = (JavaCompile) task; + Logger logger = t.getLogger(); + checkProjectErrors(bndProject, logger); + if (logger.isInfoEnabled()) { + logger.info("Compile to {}", unwrapFile(t.getDestinationDirectory())); + if (t.getOptions() + .getRelease() + .isPresent()) { + logger.info("--release {} {}", unwrap(t.getOptions() + .getRelease()), Strings.join(" ", + t.getOptions() + .getAllCompilerArgs())); + } else { + logger.info("-source {} -target {} {}", t.getSourceCompatibility(), + t.getTargetCompatibility(), Strings.join(" ", t.getOptions() + .getAllCompilerArgs())); + } + logger.info("-classpath {}", t.getClasspath() + .getAsPath()); + if (Objects.nonNull(t.getOptions() + .getBootstrapClasspath())) { + logger.info("-bootclasspath {}", t.getOptions() + .getBootstrapClasspath() + .getAsPath()); + } + } + } + } + + /** + * Action for an {@link AbstractTestTask}. + */ + private static final class TestCheckErrorsAction extends BndProjectUsingTaskAction { + @Override + protected void execute(final Task tt, final aQute.bnd.build.Project bndProject) { + checkProjectErrors(bndProject, tt.getLogger(), ((AbstractTestTask) tt).getIgnoreFailures()); + } + } + private static class PluginApplicationHelper { private final Project project; @@ -159,7 +383,7 @@ public void doApplyPlugin() throws Exception { } bndProject.prepare(); if (!bndProject.isValid()) { - checkErrors(project.getLogger()); + checkProjectErrors(bndProject, project.getLogger()); throw new GradleException(String.format("Project %s is not a valid bnd project", bndProject.getName())); } BndPluginExtension extension = project.getExtensions() @@ -204,9 +428,7 @@ public void doApplyPlugin() throws Exception { cpa -> cpa.builtBy(JavaPlugin.JAR_TASK_NAME)); } }); - FileCollection deliverables = configurations.getByName(JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME) - .getArtifacts() - .getFiles(); + FileCollection deliverables = getDeliverables(project); /* Set up Bnd generate support */ Optional> generate = bndProject.getGenerate() @@ -238,18 +460,7 @@ public void doApplyPlugin() throws Exception { .dirs(bndProject.getGenerate() .getOutputDirs()) .withPropertyName("generateOutputs"); - t.doLast("generate", new Action<>() { - @Override - public void execute(Task tt) { - try { - bndProject.getGenerate() - .generate(false); - } catch (Exception e) { - throw new GradleException(String.format("Project %s failed to generate", bndProject.getName()), e); - } - checkErrors(tt.getLogger()); - } - }); + t.doLast("generate", new GenerateTaskAction()); })); Optional> generateInputAction = generate.map(generateTask -> t -> { t.getInputs() @@ -464,36 +675,7 @@ public void execute(Task tt) { } options.getCompilerArgumentProviders() .add(argProvider(javacProfile.map(profile -> Arrays.asList("-profile", profile)))); - t.doFirst("checkErrors", new Action<>() { - @Override - public void execute(Task tt) { - Logger logger = tt.getLogger(); - checkErrors(logger); - if (logger.isInfoEnabled()) { - logger.info("Compile to {}", unwrapFile(t.getDestinationDirectory())); - if (t.getOptions() - .getRelease() - .isPresent()) { - logger.info("--release {} {}", unwrap(t.getOptions() - .getRelease()), Strings.join(" ", - t.getOptions() - .getAllCompilerArgs())); - } else { - logger.info("-source {} -target {} {}", t.getSourceCompatibility(), - t.getTargetCompatibility(), Strings.join(" ", t.getOptions() - .getAllCompilerArgs())); - } - logger.info("-classpath {}", t.getClasspath() - .getAsPath()); - if (Objects.nonNull(t.getOptions() - .getBootstrapClasspath())) { - logger.info("-bootclasspath {}", t.getOptions() - .getBootstrapClasspath() - .getAsPath()); - } - } - } - }); + t.doFirst("checkErrors", new JavaCompileCheckErrorsAction()); }); TaskProvider jar = tasks.named(JavaPlugin.JAR_TASK_NAME, AbstractArchiveTask.class, @@ -567,29 +749,7 @@ public void execute(Task tt) { .file(layout.getBuildDirectory() .file(Constants.BUILDFILES)) .withPropertyName("buildfiles"); - t.doLast("build", new Action<>() { - @Override - public void execute(Task tt) { - File[] built; - try { - built = bndProject.build(); - if (Objects.nonNull(built)) { - long now = System.currentTimeMillis(); - for (File f : built) { - f.setLastModified(now); - } - } - } catch (Exception e) { - throw new GradleException( - String.format("Project %s failed to build", bndProject.getName()), e); - } - checkErrors(tt.getLogger()); - if (Objects.nonNull(built)) { - tt.getLogger() - .info("Generated bundles: {}", (Object) built); - } - } - }); + t.doLast("build", new JarTaskBuildAction()); }); TaskProvider jarDependencies = tasks.register("jarDependencies", t -> { @@ -620,18 +780,7 @@ public void execute(Task tt) { t.getInputs() .files(jar) .withPropertyName(jar.getName()); - t.doLast("release", new Action<>() { - @Override - public void execute(Task tt) { - try { - bndProject.release(); - } catch (Exception e) { - throw new GradleException( - String.format("Project %s failed to release", bndProject.getName()), e); - } - checkErrors(tt.getLogger()); - } - }); + t.doLast("release", new ReleaseTaskAction()); }); TaskProvider releaseDependencies = tasks.register("releaseDependencies", t -> { @@ -652,12 +801,7 @@ public void execute(Task tt) { t.getInputs() .files(getBuildDependencies(JavaPlugin.JAR_TASK_NAME)) .withPropertyName("buildDependencies"); - t.doFirst("checkErrors", new Action<>() { - @Override - public void execute(Task tt) { - checkErrors(tt.getLogger(), t.getIgnoreFailures()); - } - }); + t.doFirst("checkErrors", new TestCheckErrorsAction()); }); TaskProvider testOSGi = tasks.register("testOSGi", TestOSGi.class, t -> { @@ -793,98 +937,16 @@ public void execute(Task tt) { }); }); - Collection dependson = bndProject.getDependson(); TaskProvider echo = tasks.register("echo", t -> { t.setDescription("Displays the bnd project information."); t.setGroup(HelpTasksPlugin.HELP_GROUP); - JavaCompile compileJava = unwrap(tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile.class)); - JavaCompile compileTestJava = unwrap( - tasks.named(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME, JavaCompile.class)); - t.doLast("echo", new Action<>() { - @Override - public void execute(Task tt) { - try (Formatter f = new Formatter()) { - f.format("------------------------------------------------------------%n"); - f.format("Project %s // Bnd version %s%n", project.getName(), About.getBndVersion()); - f.format("------------------------------------------------------------%n"); - f.format("%n"); - f.format("project.workspace: %s%n", workspace.getLayout() - .getProjectDirectory()); - f.format("project.name: %s%n", project.getName()); - f.format("project.dir: %s%n", layout.getProjectDirectory()); - f.format("target: %s%n", unwrap(layout.getBuildDirectory())); - f.format("project.dependson: %s%n", dependson); - f.format("project.sourcepath: %s%n", - sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) - .getAllSource() - .getSourceDirectories() - .getAsPath()); - f.format("project.output: %s%n", unwrap(compileJava.getDestinationDirectory())); - f.format("project.buildpath: %s%n", compileJava.getClasspath() - .getAsPath()); - f.format("project.allsourcepath: %s%n", allSrcDirs.getAsPath()); - f.format("project.testsrc: %s%n", - sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME) - .getAllSource() - .getSourceDirectories() - .getAsPath()); - f.format("project.testoutput: %s%n", unwrap(compileTestJava.getDestinationDirectory())); - f.format("project.testpath: %s%n", compileTestJava.getClasspath() - .getAsPath()); - if (Objects.nonNull(compileJava.getOptions() - .getBootstrapClasspath())) { - f.format("project.bootclasspath: %s%n", compileJava.getOptions() - .getBootstrapClasspath() - .getAsPath()); - } - f.format("project.deliverables: %s%n", deliverables.getFiles()); - String executable = Optional.ofNullable(compileJava.getOptions() - .getForkOptions() - .getExecutable()) - .orElseGet(() -> compileJava.getJavaCompiler() - .map(javaCompiler -> IO.absolutePath(unwrapFile(javaCompiler.getExecutablePath()))) - .getOrElse("javac")); - f.format("javac: %s%n", executable); - if (compileJava.getOptions() - .getRelease() - .isPresent()) { - f.format("--release: %s%n", unwrap(compileJava.getOptions() - .getRelease())); - } else { - f.format("-source: %s%n", compileJava.getSourceCompatibility()); - f.format("-target: %s%n", compileJava.getTargetCompatibility()); - } - if (javacProfile.isPresent()) { - f.format("-profile: %s%n", javacProfile.get()); - } - System.out.print(f.toString()); - } - checkErrors(tt.getLogger(), true); - } - }); + t.doLast("echo", new EchoTaskAction()); }); TaskProvider bndproperties = tasks.register("bndproperties", t -> { t.setDescription("Displays the bnd properties."); t.setGroup(HelpTasksPlugin.HELP_GROUP); - t.doLast("bndproperties", new Action<>() { - @Override - public void execute(Task tt) { - try (Formatter f = new Formatter()) { - f.format("------------------------------------------------------------%n"); - f.format("Project %s // Bnd version %s%n", project.getName(), About.getBndVersion()); - f.format("------------------------------------------------------------%n"); - f.format("%n"); - bndProject.getPropertyKeys(true) - .stream() - .sorted() - .forEachOrdered(key -> f.format("%s: %s%n", key, bndProject.getProperty(key, ""))); - f.format("%n"); - System.out.print(f.toString()); - } - checkErrors(tt.getLogger(), true); - } - }); + t.doLast("bndproperties", new BndpropertiesTaskAction()); }); // Depend upon an output dir to avoid parallel task execution. @@ -957,37 +1019,39 @@ private ConfigurableFileCollection bndConfiguration() { bndProject.getIncluded()); } - private void checkErrors(Logger logger) { - checkProjectErrors(bndProject, logger, false); - } + } - private void checkErrors(Logger logger, boolean ignoreFailures) { - checkProjectErrors(bndProject, logger, ignoreFailures); - } + private static FileCollection getDeliverables(Project project) { + return project.getConfigurations().getByName(JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME) + .getArtifacts() + .getFiles(); + } - private void checkProjectErrors(aQute.bnd.build.Project p, Logger logger, boolean ignoreFailures) { - p.getInfo(p.getWorkspace(), p.getWorkspace() - .getBase() - .getName() - .concat(" :")); - boolean failed = !ignoreFailures && !p.isOk(); - int errorCount = p.getErrors() - .size(); - logReport(p, logger); - p.clear(); - if (failed) { - String str; - if (errorCount == 1) { - str = "%s has errors, one error was reported"; - } else if (errorCount > 1) { - str = "%s has errors, %s errors were reported"; - } else { - str = "%s has errors even though no errors were reported"; - } - throw new GradleException(String.format(str, p.getName(), errorCount)); + private static void checkProjectErrors(aQute.bnd.build.Project p, Logger logger) { + checkProjectErrors(p, logger, false); + } + + private static void checkProjectErrors(aQute.bnd.build.Project p, Logger logger, boolean ignoreFailures) { + p.getInfo(p.getWorkspace(), p.getWorkspace() + .getBase() + .getName() + .concat(" :")); + boolean failed = !ignoreFailures && !p.isOk(); + int errorCount = p.getErrors() + .size(); + logReport(p, logger); + p.clear(); + if (failed) { + String str; + if (errorCount == 1) { + str = "%s has errors, one error was reported"; + } else if (errorCount > 1) { + str = "%s has errors, %s errors were reported"; + } else { + str = "%s has errors even though no errors were reported"; } + throw new GradleException(String.format(str, p.getName(), errorCount)); } - } private static List decontainer(Collection path) { diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndWorkspacePlugin.java b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndWorkspacePlugin.java index cda339e1a6..38f52ef255 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndWorkspacePlugin.java +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndWorkspacePlugin.java @@ -48,6 +48,7 @@ public class BndWorkspacePlugin implements Plugin { private static final Pattern OPTION_P = Pattern.compile("--(?