diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index a33be5e..75731e4 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -17,7 +17,6 @@ gradlePlugin { id = 'GroowtAntlrPlugin' implementationClass = 'groowt.gradle.antlr.GroowtAntlrPlugin' } - } } diff --git a/cli/build.gradle b/cli/build.gradle new file mode 100644 index 0000000..9393df6 --- /dev/null +++ b/cli/build.gradle @@ -0,0 +1,28 @@ +plugins { + id 'GroowtConventions' + id 'application' + id 'com.jessebrault.jbarchiva' version '0.1.0' + id 'maven-publish' +} + +group = 'groowt' +version = '0.1.0' + +application { + mainClass = 'groowt.cli.GroowtCli' +} + +tasks.named('jar', Jar) { + manifest { + attributes('Main-Class': 'groowt.cli.GroowtCli') + } +} + +publishing { + publications { + create('groowtCli', MavenPublication) { + artifactId = 'groowt-cli' + from components.java + } + } +} diff --git a/cli/src/main/java/groowt/cli/GroowtCli.java b/cli/src/main/java/groowt/cli/GroowtCli.java new file mode 100644 index 0000000..637b106 --- /dev/null +++ b/cli/src/main/java/groowt/cli/GroowtCli.java @@ -0,0 +1,9 @@ +package groowt.cli; + +public class GroowtCli { + + public static void main(String[] args) { + System.out.println("Hello from Groowt!"); + } + +} diff --git a/groowt-gradle/build.gradle b/groowt-gradle/build.gradle new file mode 100644 index 0000000..7730b26 --- /dev/null +++ b/groowt-gradle/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'java-gradle-plugin' + id 'com.jessebrault.jbarchiva' version '0.1.0' + id 'maven-publish' +} + +group = 'groowt' +version = '0.1.0' + +repositories { + mavenCentral() +} + +dependencies { + implementation libs.groovy +} + +gradlePlugin { + plugins { + groowtGradle { + id = 'groowt-gradle' + implementationClass = 'groowt.gradle.GroowtGradlePlugin' + } + } +} + +publishing { + publications { + groowtGradlePlugin(MavenPublication) { + artifactId = 'groowt-gradle' + from components.java + } + } +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/DefaultGroowtExtension.java b/groowt-gradle/src/main/java/groowt/gradle/DefaultGroowtExtension.java new file mode 100644 index 0000000..fedd3ab --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/DefaultGroowtExtension.java @@ -0,0 +1,23 @@ +package groowt.gradle; + +import org.gradle.api.internal.tasks.DefaultSourceSetContainer; +import org.gradle.api.tasks.SourceSetContainer; +import org.gradle.api.model.ObjectFactory; + +import javax.inject.Inject; + +public class DefaultGroowtExtension implements GroowtExtension { + + private final SourceSetContainer sourceSets; + + @Inject + public DefaultGroowtExtension(ObjectFactory objectFactory) { + this.sourceSets = objectFactory.newInstance(DefaultSourceSetContainer.class); + } + + @Override + public SourceSetContainer getSourceSets() { + return this.sourceSets; + } + +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/DefaultTemplateSourceDirectorySet.java b/groowt-gradle/src/main/java/groowt/gradle/DefaultTemplateSourceDirectorySet.java new file mode 100644 index 0000000..657fb54 --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/DefaultTemplateSourceDirectorySet.java @@ -0,0 +1,19 @@ +package groowt.gradle; + +import org.gradle.api.file.SourceDirectorySet; +import org.gradle.api.internal.file.DefaultSourceDirectorySet; +import org.gradle.api.internal.tasks.TaskDependencyFactory; + +import javax.inject.Inject; + +public class DefaultTemplateSourceDirectorySet extends DefaultSourceDirectorySet implements TemplateSourceDirectorySet { + + @Inject + public DefaultTemplateSourceDirectorySet( + SourceDirectorySet delegate, + TaskDependencyFactory taskDependencyFactory + ) { + super(delegate, taskDependencyFactory); + } + +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/DefaultTemplateSourceSet.java b/groowt-gradle/src/main/java/groowt/gradle/DefaultTemplateSourceSet.java new file mode 100644 index 0000000..8cb34d8 --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/DefaultTemplateSourceSet.java @@ -0,0 +1,58 @@ +package groowt.gradle; + +import groovy.lang.Closure; +import org.gradle.api.Action; +import org.gradle.api.file.SourceDirectorySet; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.reflect.HasPublicType; +import org.gradle.api.reflect.TypeOf; +import org.gradle.util.internal.ConfigureUtil; + +import javax.inject.Inject; + +public class DefaultTemplateSourceSet implements TemplateSourceSet, HasPublicType { + + private final TemplateSourceDirectorySet templateSourceDirectorySet; + private final SourceDirectorySet allTemplates; + + @Inject + public DefaultTemplateSourceSet(ObjectFactory objectFactory, String name, String displayName) { + this.templateSourceDirectorySet = objectFactory.newInstance( + DefaultTemplateSourceDirectorySet.class, + objectFactory.sourceDirectorySet(name, displayName + " ComponentTemplate sources") + ); + this.templateSourceDirectorySet.getFilter().include("**/*.wvc", "**/*.gst"); + this.allTemplates = objectFactory.sourceDirectorySet("all" + name, displayName + " ComponentTemplate sources"); + this.allTemplates.source(this.templateSourceDirectorySet); + this.allTemplates.getFilter().include("**/*.wvc", "**/*.gst"); + } + + @Override + public TypeOf getPublicType() { + return TypeOf.typeOf(TemplateSourceSet.class); + } + + @Override + public TemplateSourceDirectorySet getTemplates() { + return this.templateSourceDirectorySet; + } + + @Override + public TemplateSourceSet templates(Action action) { + action.execute(this.templateSourceDirectorySet); + return this; + } + + @SuppressWarnings("rawtypes") + @Override + public TemplateSourceSet templates(Closure closure) { + ConfigureUtil.configure(closure, this.templateSourceDirectorySet); + return this; + } + + @Override + public SourceDirectorySet getAllTemplates() { + return this.allTemplates; + } + +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/GroowtExtension.java b/groowt-gradle/src/main/java/groowt/gradle/GroowtExtension.java new file mode 100644 index 0000000..a793e7b --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/GroowtExtension.java @@ -0,0 +1,7 @@ +package groowt.gradle; + +import org.gradle.api.tasks.SourceSetContainer; + +public interface GroowtExtension { + SourceSetContainer getSourceSets(); +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/GroowtGradlePlugin.java b/groowt-gradle/src/main/java/groowt/gradle/GroowtGradlePlugin.java new file mode 100644 index 0000000..70cd492 --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/GroowtGradlePlugin.java @@ -0,0 +1,76 @@ +package groowt.gradle; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.file.FileCollection; +import org.gradle.api.internal.tasks.DefaultSourceSet; +import org.gradle.api.plugins.GroovyPlugin; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.SourceSetContainer; + +import static org.gradle.api.internal.lambdas.SerializableLambdas.spec; + +public class GroowtGradlePlugin implements Plugin { + + @Override + public void apply(Project project) { + // Apply java and groovy plugins, if not done already + final var pluginManager = project.getPluginManager(); + pluginManager.apply(JavaPlugin.class); + pluginManager.apply(GroovyPlugin.class); + + // Create our groowt configuration for storing the groowt dependencies + final Provider groowtConfigurationProvider = project.getConfigurations() + .register("groowt", configuration -> { + configuration.setCanBeConsumed(false); + configuration.setCanBeResolved(true); + }); + + // Create groowt extension and source sets. + final GroowtExtension groowtExtension = project.getExtensions().create( + GroowtExtension.class, + "groowt", + DefaultGroowtExtension.class + ); + + final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class); + final SourceSetContainer javaSourceSets = javaExtension.getSourceSets(); + + // data resources, such as texts, json files, sqlite-databases, etc. + javaSourceSets.getByName("main", mainSourceSet -> { + mainSourceSet.getResources().srcDir("src/data"); + }); + + // TODO: figure out how we can set the compile behavior for all of these. + javaSourceSets.forEach(sourceSet -> { + final TemplateSourceSet templateSourceSet = project.getObjects().newInstance( + DefaultTemplateSourceSet.class, + "wvc", + ((DefaultSourceSet) sourceSet).getDisplayName() + ); + final TemplateSourceDirectorySet templateSourceDirectorySet = templateSourceSet.getTemplates(); + sourceSet.getExtensions().add( + TemplateSourceDirectorySet.class, + "templates", + templateSourceDirectorySet + ); + templateSourceDirectorySet.srcDir("src/" + sourceSet.getName() + "/templates"); + + // Explicitly capture only a FileCollection in the lambda below for compatibility with configuration-cache. + @SuppressWarnings("UnnecessaryLocalVariable") + final FileCollection templateSourceFiles = templateSourceDirectorySet; + sourceSet.getResources().getFilter().exclude( + spec(element -> templateSourceFiles.contains(element.getFile())) + ); + sourceSet.getAllJava().source(templateSourceDirectorySet); + sourceSet.getAllSource().source(templateSourceDirectorySet); + }); + + // create init task + project.getTasks().create("groowtInit", GroowtInitTask.class, groowtConfigurationProvider); + } + +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/GroowtInitTask.java b/groowt-gradle/src/main/java/groowt/gradle/GroowtInitTask.java new file mode 100644 index 0000000..52ca988 --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/GroowtInitTask.java @@ -0,0 +1,95 @@ +package groowt.gradle; + +import org.gradle.api.DefaultTask; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.TaskAction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import java.io.*; +import java.util.Set; + +public class GroowtInitTask extends DefaultTask { + + private static final Logger logger = LoggerFactory.getLogger(GroowtInitTask.class); + + private static final Set srcDirsToMake = Set.of("groovy", "templates"); + + private final Provider groowtConfigurationProvider; + private final File binDir; + private final File groowtDir; + + @Inject + public GroowtInitTask(Project project, Provider groowtConfigurationProvider) { + this.groowtConfigurationProvider = groowtConfigurationProvider; + this.binDir = new File(project.getRootDir(), "bin"); + this.groowtDir = new File(project.getRootDir(), "groowt"); + } + + protected void createBin() throws IOException { + //noinspection ResultOfMethodCallIgnored + this.binDir.mkdirs(); + final var groowtFile = new File(this.binDir, "groowt"); + try (final InputStream bootstrapInputStream = this.getClass().getResourceAsStream("groowt")) { + if (bootstrapInputStream != null) { + try (final OutputStream bootstrapOutputStream = new FileOutputStream(groowtFile)) { + bootstrapInputStream.transferTo(bootstrapOutputStream); + } + if (!groowtFile.setExecutable(true)) { + logger.warn("Could not set bin/groowt to executable; you will have to do this yourself."); + } + } else { + throw new RuntimeException("Could not find groowt shell script."); + } + } + } + + protected void createGroowtFolder() throws IOException { + //noinspection ResultOfMethodCallIgnored + this.groowtDir.mkdirs(); + final var groowtConfiguration = this.groowtConfigurationProvider.get(); + final Set groowtCliFiles = groowtConfiguration.files(dependency -> { + final var group = dependency.getGroup(); + if (group == null || !group.equals("groowt")) { + return false; + } else { + return dependency.getName().equals("groowt-cli"); + } + }); + final File groowtCliJarFile = groowtCliFiles.stream() + .filter(file -> file.getName().endsWith(".jar")) + .findFirst() + .orElseThrow(() -> new RuntimeException("Could not find groowt-cli jar file.")); + final File groowtCliJarOutputFile = new File(this.groowtDir, "groowt-cli.jar"); + try (final InputStream groowtCliJarInputStream = new FileInputStream(groowtCliJarFile)) { + try (final OutputStream groowtCliJarOutputStream = new FileOutputStream(groowtCliJarOutputFile)) { + groowtCliJarInputStream.transferTo(groowtCliJarOutputStream); + } + } + } + + protected void createSrcDirs() { + final var javaPluginExtension = this.getProject().getExtensions().getByType(JavaPluginExtension.class); + javaPluginExtension.getSourceSets().forEach(sourceSet -> { + final var srcDirs = sourceSet.getAllSource().getSrcDirs(); + srcDirs.forEach(srcDir -> { + if (!sourceSet.getName().contains("test") && srcDirsToMake.contains(srcDir.getName())) { + //noinspection ResultOfMethodCallIgnored + srcDir.mkdirs(); + } + }); + }); + } + + @TaskAction + public void doInit() throws IOException { + this.createBin(); + this.createGroowtFolder(); + this.createSrcDirs(); + } + +} diff --git a/groowt-gradle/src/main/java/groowt/gradle/TemplateSourceDirectorySet.java b/groowt-gradle/src/main/java/groowt/gradle/TemplateSourceDirectorySet.java new file mode 100644 index 0000000..6c6e63d --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/TemplateSourceDirectorySet.java @@ -0,0 +1,5 @@ +package groowt.gradle; + +import org.gradle.api.file.SourceDirectorySet; + +public interface TemplateSourceDirectorySet extends SourceDirectorySet {} diff --git a/groowt-gradle/src/main/java/groowt/gradle/TemplateSourceSet.java b/groowt-gradle/src/main/java/groowt/gradle/TemplateSourceSet.java new file mode 100644 index 0000000..125f54e --- /dev/null +++ b/groowt-gradle/src/main/java/groowt/gradle/TemplateSourceSet.java @@ -0,0 +1,18 @@ +package groowt.gradle; + +import groovy.lang.Closure; +import org.gradle.api.Action; +import org.gradle.api.file.SourceDirectorySet; + +public interface TemplateSourceSet { + + TemplateSourceDirectorySet getTemplates(); + + SourceDirectorySet getAllTemplates(); + + TemplateSourceSet templates(Action action); + + @SuppressWarnings("rawtypes") + TemplateSourceSet templates(Closure closure); + +} diff --git a/groowt-gradle/src/main/resources/groowt/gradle/groowt b/groowt-gradle/src/main/resources/groowt/gradle/groowt new file mode 100644 index 0000000..3951170 --- /dev/null +++ b/groowt-gradle/src/main/resources/groowt/gradle/groowt @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +java -jar groowt/groowt-cli.jar "$@" diff --git a/settings.gradle b/settings.gradle index 63c3821..478c991 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,10 +2,32 @@ pluginManagement { plugins { id 'org.jetbrains.kotlin.jvm' version '1.9.23' } + + repositories { + mavenCentral() + maven { + url 'https://archiva.jessebrault.com/repository/internal/' + + credentials { + username System.getenv('JBARCHIVA_USERNAME') + password System.getenv('JBARCHIVA_PASSWORD') + } + } + maven { + url 'https://archiva.jessebrault.com/repository/snapshots/' + + credentials { + username System.getenv('JBARCHIVA_USERNAME') + password System.getenv('JBARCHIVA_PASSWORD') + } + } + } } rootProject.name = 'groowt' -include 'views', 'view-components', 'web-views' + +include 'cli', 'groowt-gradle', 'views', 'view-components', 'web-views' + file('util').eachDir { include it.name project(":$it.name").projectDir = it