Cleanup default classpaths for Clojure/ClojureScript and make them more configurable by ajoberstar · Pull Request #173 · clojurephant/clojurephant · GitHub
Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions docs/modules/ROOT/pages/faq.adoc
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pluginManagement {
id("org.ajoberstar.reckon") version("0.16.1")
id("com.diffplug.spotless") version("6.7.2")

id("dev.clojurephant.clojure") version("0.7.0-alpha.1")
id("dev.clojurephant.clojure") version("0.7.0-alpha.3")
id("org.ajoberstar.stutter") version("0.7.1")
id("com.gradle.plugin-publish") version("1.0.0")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
(testing "with Java code that depends on Clojure code in different source sets, compilation succeeds"
(gradle/with-project "MixedClojureJavaTest"
(let [result (gradle/build "clean" "compileJava")]
(gradle/verify-task-outcome result ":compilePreClojure" :success)
(gradle/verify-task-outcome result ":compileClojure" :success)
(gradle/verify-task-outcome result ":compileJava" :success)
(gradle/verify-compilation-with-aot "src/pre/clojure" "build/clojure/pre")
(gradle/verify-compilation-with-aot "src/main/clojure" "build/clojure/main")
(is (every? #(-> % .getFileName str (str/ends-with? ".class")) (gradle/file-tree "build/classes/java/main")))))))

(deftest clojure-depends-on-java
Expand Down
26 changes: 13 additions & 13 deletions src/compatTest/clojure/dev/clojurephant/compat_test/repl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@
(let [result (gradle/build-and-fail "clojureRepl")]
(gradle/verify-task-outcome result ":clojureRepl" :failed)
(gradle/verify-task-outcome result ":compileJava" :success :no-source)
(gradle/verify-task-outcome result ":compileTestJava" :success :no-source)
(gradle/verify-task-outcome result ":compileDevJava" :success :no-source)
(gradle/verify-task-outcome result ":checkDevClojure" :success)
(gradle/verify-task-outcome result ":checkClojure" :skipped)
(gradle/verify-task-outcome result ":checkTestClojure" :skipped)
(gradle/verify-task-outcome result ":compileClojure" :skipped)
(gradle/verify-task-outcome result ":compileTestClojure" :skipped)
(gradle/verify-task-outcome result ":compileDevClojure" :skipped)))))
(gradle/verify-task-outcome result ":compileTestJava" nil)
(gradle/verify-task-outcome result ":compileDevJava" nil)
(gradle/verify-task-outcome result ":checkDevClojure" nil)
(gradle/verify-task-outcome result ":checkClojure" nil)
(gradle/verify-task-outcome result ":checkTestClojure" nil)
(gradle/verify-task-outcome result ":compileClojure" nil)
(gradle/verify-task-outcome result ":compileTestClojure" nil)
(gradle/verify-task-outcome result ":compileDevClojure" nil)))))

(deftest task-dependencies-cljs
(testing "No ClojureScript compiles happen when REPL is requested, but other languages are compiled"
Expand All @@ -91,11 +91,11 @@
(let [result (gradle/build-and-fail "clojureRepl")]
(gradle/verify-task-outcome result ":clojureRepl" :failed)
(gradle/verify-task-outcome result ":compileJava" :success :no-source)
(gradle/verify-task-outcome result ":compileTestJava" :success :no-source)
(gradle/verify-task-outcome result ":compileDevJava" :success :no-source)
(gradle/verify-task-outcome result ":compileClojureScript" :skipped)
(gradle/verify-task-outcome result ":compileTestClojureScript" :skipped)
(gradle/verify-task-outcome result ":compileDevClojureScript" :skipped)))))
(gradle/verify-task-outcome result ":compileTestJava" nil)
(gradle/verify-task-outcome result ":compileDevJava" nil)
(gradle/verify-task-outcome result ":compileClojureScript" nil)
(gradle/verify-task-outcome result ":compileTestClojureScript" nil)
(gradle/verify-task-outcome result ":compileDevClojureScript" nil)))))


(deftest no-compile-output-on-classpath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
:up-to-date TaskOutcome/UP_TO_DATE})

(defn verify-task-outcome [result name & outcomes]
(let [allowed-outcomes (into #{} (map task-outcomes) outcomes)
(let [allowed-outcomes (into #{} (comp (map task-outcomes)
(filter identity))
outcomes)
actual-outcome (some-> result (.task name) .getOutcome)]
(is (get allowed-outcomes actual-outcome) (str "Task " name " did not result in one of " outcomes))))
(if (seq allowed-outcomes)
(is (get allowed-outcomes actual-outcome) (str "Task " name " did not result in one of " outcomes))
(is (nil? actual-outcome) (str "Task " name " did not result in one of " outcomes)))))
21 changes: 5 additions & 16 deletions src/compatTest/projects/MixedClojureJavaTest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,17 @@ repositories {
mavenLocal()
}

sourceSets {
pre
main.compileClasspath += files(compilePreClojure)
}

configurations {
preImplementation.extendsFrom implementation
}

dependencies {
implementation 'org.clojure:clojure:1.10.3'
}

jar {
from sourceSets.pre.output
}

clojure.builds {
pre {
aotAll()
}
main {
classpath.from = sourceSets.main.compileClasspath + tasks.named(sourceSets.main.processResourcesTaskName)
aotAll()
}
}

tasks.named('compileJava') {
classpath += files(sourceSets.main.clojure.classesDirectory)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@

import javax.inject.Inject;

import dev.clojurephant.plugin.clojure.internal.DefaultClojureSourceSet;
import dev.clojurephant.plugin.clojure.tasks.ClojureCheck;
import dev.clojurephant.plugin.clojure.tasks.ClojureCompile;
import dev.clojurephant.plugin.clojure.tasks.ClojureSourceSet;
import dev.clojurephant.plugin.common.internal.ClojureCommonBasePlugin;
import dev.clojurephant.plugin.common.internal.Namespaces;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.plugins.DslObject;
import org.gradle.api.file.SourceDirectorySet;
import org.gradle.api.internal.tasks.DefaultSourceSetOutput;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider;

public class ClojureBasePlugin implements Plugin<Project> {
private final ObjectFactory objects;
Expand All @@ -34,57 +33,63 @@ public ClojureBasePlugin(ObjectFactory objects) {
public void apply(Project project) {
project.getPluginManager().apply(ClojureCommonBasePlugin.class);
ClojureExtension extension = project.getExtensions().create("clojure", ClojureExtension.class);
configureSourceSetDefaults(project, extension);
configureBuildDefaults(project, extension);
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
configureSourceSetDefaults(project, sourceSets, extension);
configureBuildDefaults(project, sourceSets, extension);
configureCheckDefaults(project.getTasks());
}

private void configureSourceSetDefaults(Project project, ClojureExtension extension) {
project.getExtensions().getByType(SourceSetContainer.class).all(sourceSet -> {
ClojureSourceSet clojureSourceSet = new DefaultClojureSourceSet("clojure", objects);
new DslObject(sourceSet).getConvention().getPlugins().put("clojure", clojureSourceSet);
private void configureSourceSetDefaults(Project project, SourceSetContainer sourceSets, ClojureExtension extension) {
sourceSets.all(sourceSet -> {
// every source set gets clojure source, following same convention as Java/Groovy
SourceDirectorySet clojureSource = objects.sourceDirectorySet(sourceSet.getName(), sourceSet.getName());
clojureSource.srcDir(String.format("src/%s/clojure", sourceSet.getName()));
clojureSource.getFilter().include(Namespaces.CLOJURE_PATTERNS);

// make the sources available on the source set
sourceSet.getExtensions().add("clojure", clojureSource);

clojureSourceSet.getClojure().srcDir(String.format("src/%s/clojure", sourceSet.getName()));
clojureSourceSet.getClojure().getFilter().include(Namespaces.CLOJURE_PATTERNS);
// in case the clojure source overlaps with the resources source
sourceSet.getResources().getFilter().exclude(element -> clojureSourceSet.getClojure().contains(element.getFile()));
sourceSet.getAllSource().source(clojureSourceSet.getClojure());
sourceSet.getResources().getFilter().exclude(element -> clojureSource.contains(element.getFile()));

ClojureBuild build = extension.getBuilds().create(sourceSet.getName());
// ensure that clojure is considered part of full source of source set
sourceSet.getAllSource().source(clojureSource);

ClojureSourceSet clojure = (ClojureSourceSet) new DslObject(sourceSet).getConvention().getPlugins().get("clojure");
build.getSourceRoots().from(clojure.getClojure().getSourceDirectories());
// every source set gets a default clojure build
ClojureBuild build = extension.getBuilds().create(sourceSet.getName());
build.getSourceRoots().from(clojureSource.getSourceDirectories());
clojureSource.getDestinationDirectory().set(build.getOutputDir());

build.getClasspath()
.from(build.getSourceRoots())
.from(project.provider(() -> sourceSet.getCompileClasspath()))
.from(project.getTasks().named(sourceSet.getCompileJavaTaskName()))
// depend on compiled Java by default
.from(project.files(sourceSet.getJava().getClassesDirectory()))
// depend on processed resources by default
.from(project.getTasks().named(sourceSet.getProcessResourcesTaskName()));

project.getTasks().named(sourceSet.getClassesTaskName(), task -> {
task.dependsOn(build.getTaskName("compile"));
task.dependsOn(build.getTaskName("check"));
});

Provider<FileCollection> output = project.provider(() -> {
if (build.isCompilerConfigured()) {
return project.files(build.getOutputDir());
} else {
return clojureSourceSet.getClojure().getSourceDirectories();
return build.getSourceRoots();
}
});

((DefaultSourceSetOutput) sourceSet.getOutput()).getClassesDirs().from(output);
project.getTasks().getByName(sourceSet.getClassesTaskName()).dependsOn(build.getTaskName("compile"));
project.getTasks().getByName(sourceSet.getClassesTaskName()).dependsOn(build.getTaskName("check"));

project.getTasks().named(sourceSet.getClassesTaskName(), task -> {
task.dependsOn(build.getTaskName("compile"));
task.dependsOn(build.getTaskName("check"));
});
});
}

private void configureBuildDefaults(Project project, ClojureExtension extension) {
private void configureBuildDefaults(Project project, SourceSetContainer sourceSets, ClojureExtension extension) {
extension.getRootOutputDir().set(project.getLayout().getBuildDirectory().dir("clojure"));

extension.getBuilds().configureEach(build -> {
build.getOutputDir().convention(extension.getRootOutputDir().dir(build.getName()));

build.getReflection().convention(ClojureCheck.REFLECTION_SILENT);
build.getCompiler().getDirectLinking().convention(false);
build.getCompiler().getDisableLocalsClearing().convention(false);
Expand All @@ -94,20 +99,29 @@ private void configureBuildDefaults(Project project, ClojureExtension extension)
project.getTasks().register(checkTaskName, ClojureCheck.class, task -> {
task.setDescription(String.format("Checks the Clojure source for the %s build.", build.getName()));
task.setSource(build.getSourceTree());
task.getClasspath().from(build.getSourceRoots());
task.getClasspath().from(build.getClasspath());
task.getReflection().set(build.getReflection());
task.getNamespaces().set(build.getCheckNamespaces());
});

String compileTaskName = build.getTaskName("compile");
project.getTasks().register(compileTaskName, ClojureCompile.class, task -> {
TaskProvider<ClojureCompile> compileTask = project.getTasks().register(compileTaskName, ClojureCompile.class, task -> {
task.setDescription(String.format("Compiles the Clojure source for the %s build.", build.getName()));
task.getDestinationDir().set(build.getOutputDir());
task.setSource(build.getSourceTree());
task.getClasspath().from(build.getSourceRoots());
task.getClasspath().from(build.getClasspath());
task.getOptions().set(build.getCompiler());
task.getNamespaces().set(build.getAotNamespaces());
});

// wire SourceDirectorySet properties per https://github.com/gradle/gradle/issues/11333
SourceSet sourceSet = sourceSets.findByName(build.getName());
if (sourceSet != null) {
SourceDirectorySet source = (SourceDirectorySet) sourceSet.getExtensions().getByName("clojure");
source.compiledBy(compileTask, ClojureCompile::getDestinationDir);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.Set;

import dev.clojurephant.plugin.clojure.tasks.ClojureCompileOptions;
import dev.clojurephant.plugin.clojure.tasks.ClojureSourceSet;
import dev.clojurephant.plugin.common.internal.Namespaces;
import org.apache.commons.text.WordUtils;
import org.gradle.api.Action;
Expand Down

This file was deleted.

This file was deleted.

Loading