From 41ff5851086aaa76123d56257c78e1fbaa622524 Mon Sep 17 00:00:00 2001 From: Scott Murphy Heiberg Date: Tue, 30 Jul 2024 14:06:26 -0700 Subject: [PATCH 1/7] Make Gradle 8.9 compatable --- .../plugin/web/gsp/GspCompileOptions.groovy | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy index d093490f..eb46ea30 100644 --- a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy +++ b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy @@ -1,22 +1,30 @@ package org.grails.gradle.plugin.web.gsp +import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.Input import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.compile.AbstractOptions import org.gradle.api.tasks.compile.BaseForkOptions import org.gradle.api.tasks.compile.GroovyForkOptions +import javax.inject.Inject; /** -* Presents the Compile Options used by the {@llink GroovyPageForkCompileTask} -* -* @author David Estes -* @since 4.0 -*/ -class GspCompileOptions implements Serializable { + * Presents the Compile Options used by the {@llink GroovyPageForkCompileTask} + * + * @author David Estes + * @since 4.0 + */ +class GspCompileOptions extends AbstractOptions { private static final long serialVersionUID = 0L; @Input - String encoding = "UTF-8" + String encoding = "UTF-8" + + @Inject + protected ObjectFactory getObjectFactory() { + throw new UnsupportedOperationException(); + } @Nested - GroovyForkOptions forkOptions = new GroovyForkOptions() + GroovyForkOptions forkOptions = getObjectFactory().newInstance(GroovyForkOptions.class) } \ No newline at end of file From 59ef00e2c9bb7ebc0a961bef03c6f44c522a0316 Mon Sep 17 00:00:00 2001 From: Scott Murphy Date: Tue, 30 Jul 2024 14:30:46 -0700 Subject: [PATCH 2/7] Revert "Make Gradle 8.9 compatable" --- .../plugin/web/gsp/GspCompileOptions.groovy | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy index eb46ea30..d093490f 100644 --- a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy +++ b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy @@ -1,30 +1,22 @@ package org.grails.gradle.plugin.web.gsp -import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.Input import org.gradle.api.tasks.Nested -import org.gradle.api.tasks.compile.AbstractOptions import org.gradle.api.tasks.compile.BaseForkOptions import org.gradle.api.tasks.compile.GroovyForkOptions -import javax.inject.Inject; /** - * Presents the Compile Options used by the {@llink GroovyPageForkCompileTask} - * - * @author David Estes - * @since 4.0 - */ -class GspCompileOptions extends AbstractOptions { +* Presents the Compile Options used by the {@llink GroovyPageForkCompileTask} +* +* @author David Estes +* @since 4.0 +*/ +class GspCompileOptions implements Serializable { private static final long serialVersionUID = 0L; @Input - String encoding = "UTF-8" - - @Inject - protected ObjectFactory getObjectFactory() { - throw new UnsupportedOperationException(); - } + String encoding = "UTF-8" @Nested - GroovyForkOptions forkOptions = getObjectFactory().newInstance(GroovyForkOptions.class) + GroovyForkOptions forkOptions = new GroovyForkOptions() } \ No newline at end of file From 5c5966d049d1b47fb49bd4064c5d767af9b20cff Mon Sep 17 00:00:00 2001 From: David Estes Date: Wed, 24 Jul 2024 19:17:52 -0400 Subject: [PATCH 3/7] removing no longer in use compile task for gsp as the forked version has been the standard for a while now --- .../web/gsp/GroovyPageCompileTask.groovy | 78 ------------------- 1 file changed, 78 deletions(-) delete mode 100644 src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageCompileTask.groovy diff --git a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageCompileTask.groovy b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageCompileTask.groovy deleted file mode 100644 index f66786df..00000000 --- a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageCompileTask.groovy +++ /dev/null @@ -1,78 +0,0 @@ -package org.grails.gradle.plugin.web.gsp - -import groovy.transform.CompileDynamic -import groovy.transform.CompileStatic -import org.gradle.api.Project -import org.gradle.api.internal.project.IsolatedAntBuilder -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.compile.AbstractCompile - -/** - * A task for compiling GSPs - * - * @author Graeme Rocher - * @since 3.0 - */ -@CompileStatic -class GroovyPageCompileTask extends AbstractCompile { - - @Input - @Optional - String packagename - - @Input - @Optional - String serverpath - - @InputDirectory - File srcDir - - @Override - void setSource(Object source) { - try { - srcDir = project.file(source) - if(srcDir.exists() && !srcDir.isDirectory()) { - throw new IllegalArgumentException("The source for GSP compilation must be a single directory, but was $source") - } - super.setSource(source) - } catch (e) { - throw new IllegalArgumentException("The source for GSP compilation must be a single directory, but was $source") - } - } - - @TaskAction - @CompileDynamic - protected void execute() { - - def compileTask = this - Project gradleProject = project - def antBuilder = gradleProject.services.get(IsolatedAntBuilder) - String packagename = packagename ?: project.name - String serverpath = serverpath ?: "/" - - antBuilder.withClasspath(classpath).execute { - taskdef(name: 'gspc', classname: 'org.grails.web.pages.GroovyPageCompilerTask') - def dest = compileTask.destinationDir - def tmpdir = new File(gradleProject.buildDir, "gsptmp") - dest.mkdirs() - - gspc(destdir: dest, - srcdir: compileTask.srcDir, - packagename: packagename, - serverpath: serverpath, - tmpdir: tmpdir) { - delegate.configs { - pathelement(path: gradleProject.file('grails-app/conf/application.yml').absolutePath) - pathelement(path: gradleProject.file('grails-app/conf/application.groovy').absolutePath) - } - delegate.classpath { - pathelement(path: dest.absolutePath) - pathelement(path: compileTask.classpath.asPath) - } - } - } - } -} From 0601350db5d5bdbd5b743f234705ba35405cd1a8 Mon Sep 17 00:00:00 2001 From: Scott Murphy Date: Wed, 31 Jul 2024 10:11:20 -0700 Subject: [PATCH 4/7] Revert "Drop dependency `grails-shell` (#287)" This reverts commit 7a97dd3ca44fccda21b7bfdfb2ae8c4aac15c36a. --- build.gradle | 13 ++ .../profiles/GrailsProfileGradlePlugin.groovy | 170 ++++++++++++++++ .../GrailsProfilePublishGradlePlugin.groovy | 112 ++++++++++ .../profiles/tasks/ProfileCompilerTask.groovy | 192 ++++++++++++++++++ 4 files changed, 487 insertions(+) create mode 100644 src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy create mode 100644 src/main/groovy/org/grails/gradle/plugin/profiles/internal/GrailsProfilePublishGradlePlugin.groovy create mode 100644 src/main/groovy/org/grails/gradle/plugin/profiles/tasks/ProfileCompilerTask.groovy diff --git a/build.gradle b/build.gradle index 86a42ea2..24c09bd3 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.bmuschko:gradle-nexus-plugin:2.3.1" implementation "org.grails:grails-bootstrap:$grailsVersion" implementation "org.grails:grails-gradle-model:$grailsVersion" + implementation "org.grails:grails-shell:$grailsVersion" implementation "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion" implementation "io.spring.gradle:dependency-management-plugin:1.1.4" } @@ -113,6 +114,12 @@ gradlePlugin { id = 'org.grails.grails-plugin' implementationClass = 'org.grails.gradle.plugin.core.GrailsPluginGradlePlugin' } + grailsProfile { + displayName = "Grails Profile Gradle Plugin" + description = 'A plugin that is capable of compiling a Grails profile into a JAR file for distribution' + id = 'org.grails.grails-profile' + implementationClass = 'org.grails.gradle.plugin.profiles.GrailsProfileGradlePlugin' + } grailsWeb { displayName = "Grails Web Gradle Plugin" description = 'Adds web specific extensions' @@ -125,6 +132,12 @@ gradlePlugin { id = 'org.grails.internal.grails-plugin-publish' implementationClass = 'org.grails.gradle.plugin.publishing.internal.GrailsCentralPublishGradlePlugin' } + grailsProfilePublish { + displayName = "Grails Profile Publish Plugin" + description = 'A plugin for publishing profiles' + id = 'org.grails.internal.grails-profile-publish' + implementationClass = 'org.grails.gradle.plugin.profiles.internal.GrailsProfilePublishGradlePlugin' + } } } diff --git a/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy b/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy new file mode 100644 index 00000000..570a9bb0 --- /dev/null +++ b/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy @@ -0,0 +1,170 @@ +/* + * Copyright 2015 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.grails.gradle.plugin.profiles + +import grails.io.IOUtils +import grails.util.BuildSettings +import groovy.transform.CompileStatic +import org.apache.tools.ant.DirectoryScanner +import org.gradle.api.Action +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.DependencyResolveDetails +import org.gradle.api.file.CopySpec +import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact +import org.gradle.api.plugins.BasePlugin +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.bundling.Jar +import org.grails.cli.profile.commands.script.GroovyScriptCommand +import org.grails.gradle.plugin.profiles.tasks.ProfileCompilerTask + + +import static org.gradle.api.plugins.BasePlugin.* + +/** + * A plugin that is capable of compiling a Grails profile into a JAR file for distribution + * + * @author Graeme Rocher + * @since 3.1 + */ +@CompileStatic +class GrailsProfileGradlePlugin implements Plugin { + + static final String CONFIGURATION_NAME = 'grails' + + public static final String RUNTIME_CONFIGURATION = "profileRuntimeOnly" + + @Override + void apply(Project project) { + project.getPluginManager().apply(BasePlugin.class) + project.configurations.create(CONFIGURATION_NAME) + def profileConfiguration = project.configurations.create(RUNTIME_CONFIGURATION) + + profileConfiguration.resolutionStrategy.eachDependency { + DependencyResolveDetails details = (DependencyResolveDetails)it + def requested = details.requested + def group = requested.group + def version = requested.version + + if(!group || !version) { + group = group ?: "org.grails.profiles" + version = version ?: BuildSettings.grailsVersion + + details.useTarget(group: group, name: requested.name,version:version) + } + } + + def profileYml = project.file("profile.yml") + + def commandsDir = project.file("commands") + def resourcesDir = new File(project.buildDir, "resources/profile") + def templatesDir = project.file("templates") + def skeletonsDir = project.file("skeleton") + def featuresDir = project.file("features") + + def spec1 = project.copySpec { CopySpec spec -> + spec.from(commandsDir) + spec.exclude("*.groovy") + spec.into("commands") + } + def spec2 = project.copySpec { CopySpec spec -> + spec.from(templatesDir) + spec.into("templates") + } + def spec4 = project.copySpec { CopySpec spec -> + spec.from(featuresDir) + spec.into("features") + } + def spec3 = project.copySpec { CopySpec spec -> + spec.from(skeletonsDir) + spec.into("skeleton") + } + + def processResources = project.tasks.create("processResources", Copy, (Action){ Copy c -> + c.with(spec1, spec2, spec3, spec4) + c.into(new File(resourcesDir, "/META-INF/grails-profile")) + + c.doFirst { + for(String file in DirectoryScanner.defaultExcludes) { + DirectoryScanner.removeDefaultExclude(file) + } + } + c.doLast { + DirectoryScanner.resetDefaultExcludes() + } + }) + + def classsesDir = new File(project.buildDir, "classes/profile") + def compileTask = project.tasks.create("compileProfile", ProfileCompilerTask, (Action) { ProfileCompilerTask task -> + task.destinationDir = classsesDir + task.source = commandsDir + task.config = profileYml + if(templatesDir.exists()) { + task.templatesDir = templatesDir + } + task.classpath = project.configurations.getByName(RUNTIME_CONFIGURATION) + project.files(IOUtils.findJarFile(GroovyScriptCommand)) + }) + + def jarTask = project.tasks.create("jar", Jar, (Action) { Jar jar -> + jar.dependsOn(processResources, compileTask) + jar.from(resourcesDir) + jar.from(classsesDir) + jar.destinationDir = new File(project.buildDir, "libs") + jar.setDescription("Assembles a jar archive containing the profile classes.") + jar.setGroup(BUILD_GROUP) + + ArchivePublishArtifact jarArtifact = new ArchivePublishArtifact(jar) + project.artifacts.add(CONFIGURATION_NAME, jarArtifact) + + jar.doFirst { + for(String file in DirectoryScanner.defaultExcludes) { + DirectoryScanner.removeDefaultExclude(file) + } + } + jar.doLast { + DirectoryScanner.resetDefaultExcludes() + } + }) + + project.tasks.create("sourcesJar", Jar, (Action) { Jar jar -> + jar.from(commandsDir) + if(profileYml.exists()) { + jar.from(profileYml) + } + jar.from(templatesDir) { CopySpec spec -> + spec.into("templates") + } + jar.from(skeletonsDir) { CopySpec spec -> + spec.into("skeleton") + } + jar.archiveClassifier.set("sources") + jar.destinationDirectory.set(new File(project.buildDir, "libs")) + jar.setDescription("Assembles a jar archive containing the profile sources.") + jar.setGroup(BUILD_GROUP) + + jar.doFirst { + for(String file in DirectoryScanner.defaultExcludes) { + DirectoryScanner.removeDefaultExclude(file) + } + } + jar.doLast { + DirectoryScanner.resetDefaultExcludes() + } + }) + project.tasks.findByName("assemble").dependsOn jarTask + + } +} diff --git a/src/main/groovy/org/grails/gradle/plugin/profiles/internal/GrailsProfilePublishGradlePlugin.groovy b/src/main/groovy/org/grails/gradle/plugin/profiles/internal/GrailsProfilePublishGradlePlugin.groovy new file mode 100644 index 00000000..9e7389b2 --- /dev/null +++ b/src/main/groovy/org/grails/gradle/plugin/profiles/internal/GrailsProfilePublishGradlePlugin.groovy @@ -0,0 +1,112 @@ +/* + * Copyright 2015 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.grails.gradle.plugin.profiles.internal + + +import groovy.transform.CompileStatic +import org.gradle.api.Action +import org.gradle.api.Project +import org.gradle.api.XmlProvider +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.DependencySet +import org.gradle.api.artifacts.SelfResolvingDependency +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.bundling.Jar +import org.grails.gradle.plugin.profiles.GrailsProfileGradlePlugin +import org.grails.gradle.plugin.publishing.internal.GrailsCentralPublishGradlePlugin + +import java.nio.file.Files + +import static org.gradle.api.plugins.BasePlugin.BUILD_GROUP + +/** + * A plugin for publishing profiles + * + * @author Graeme Rocher + * @since 3.1 + */ +@CompileStatic +class GrailsProfilePublishGradlePlugin extends GrailsCentralPublishGradlePlugin { + + @Override + void apply(Project project) { + super.apply(project) + final File tempReadmeForJavadoc = Files.createTempFile("README", "txt").toFile() + tempReadmeForJavadoc << "https://central.sonatype.org/publish/requirements/#supply-javadoc-and-sources" + project.tasks.create("javadocJar", Jar, (Action) { Jar jar -> + jar.from(tempReadmeForJavadoc) + jar.archiveClassifier.set("javadoc") + jar.destinationDirectory.set(new File(project.buildDir, "libs")) + jar.setDescription("Assembles a jar archive containing the profile javadoc.") + jar.setGroup(BUILD_GROUP) + }) + } + + @Override + protected String getDefaultGrailsCentralReleaseRepo() { + "https://repo.grails.org/grails/libs-releases-local" + } + + @Override + protected String getDefaultGrailsCentralSnapshotRepo() { + "https://repo.grails.org/grails/libs-snapshots-local" + } + + @Override + protected Map getDefaultExtraArtifact(Project project) { + [source: "${project.buildDir}/classes/profile/META-INF/grails-profile/profile.yml".toString(), + classifier: defaultClassifier, + extension : 'yml'] + } + + @Override + protected String getDefaultClassifier() { + 'profile' + } + + @Override + protected String getDefaultRepo() { + 'profiles' + } + + @Override + protected void doAddArtefact(Project project, MavenPublication publication) { + publication.artifact(project.tasks.findByName("jar")) + publication.pom(new Action() { + @Override + void execute(org.gradle.api.publish.maven.MavenPom mavenPom) { + mavenPom.withXml(new Action() { + @Override + void execute(XmlProvider xml) { + Node dependenciesNode = xml.asNode().appendNode('dependencies') + + DependencySet dependencySet = project.configurations[GrailsProfileGradlePlugin.RUNTIME_CONFIGURATION].allDependencies + + for (Dependency dependency : dependencySet) { + if (! (dependency instanceof SelfResolvingDependency)) { + Node dependencyNode = dependenciesNode.appendNode('dependency') + dependencyNode.appendNode('groupId', dependency.group) + dependencyNode.appendNode('artifactId', dependency.name) + dependencyNode.appendNode('version', dependency.version) + dependencyNode.appendNode('scope', GrailsProfileGradlePlugin.RUNTIME_CONFIGURATION) + } + } + } + }) + } + }) + } +} diff --git a/src/main/groovy/org/grails/gradle/plugin/profiles/tasks/ProfileCompilerTask.groovy b/src/main/groovy/org/grails/gradle/plugin/profiles/tasks/ProfileCompilerTask.groovy new file mode 100644 index 00000000..7f26fe80 --- /dev/null +++ b/src/main/groovy/org/grails/gradle/plugin/profiles/tasks/ProfileCompilerTask.groovy @@ -0,0 +1,192 @@ +/* + * Copyright 2015 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.grails.gradle.plugin.profiles.tasks + +import groovy.transform.CompileStatic +import org.codehaus.groovy.control.CompilationUnit +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer +import org.codehaus.groovy.control.customizers.ImportCustomizer +import org.gradle.api.artifacts.Dependency +import org.gradle.api.file.FileTree +import org.gradle.api.file.FileVisitDetails +import org.gradle.api.tasks.* +import org.gradle.api.tasks.compile.AbstractCompile +import org.grails.cli.profile.commands.script.GroovyScriptCommand +import org.grails.cli.profile.commands.script.GroovyScriptCommandTransform +import org.grails.gradle.plugin.profiles.GrailsProfileGradlePlugin +import org.yaml.snakeyaml.DumperOptions +import org.yaml.snakeyaml.LoaderOptions +import org.yaml.snakeyaml.Yaml +import org.yaml.snakeyaml.constructor.SafeConstructor +import org.yaml.snakeyaml.representer.Representer + +/** + * Compiles the classes for a profile + * + * @author Graeme Rocher + * @since 3.1 + */ +@CompileStatic +class ProfileCompilerTask extends AbstractCompile { + + public static final String DEFAULT_COMPATIBILITY = "1.8" + public static final String PROFILE_NAME = "name" + public static final String PROFILE_COMMANDS = "commands" + + ProfileCompilerTask() { + setSourceCompatibility(DEFAULT_COMPATIBILITY) + setTargetCompatibility(DEFAULT_COMPATIBILITY) + + } + + @InputFile + @Optional + File config + + @OutputFile + File profileFile + + @InputDirectory + @Optional + File templatesDir + + @Override + @InputFiles + FileTree getSource() { + return (super.getSource() + project.files(config)).asFileTree + } + + @Override + void setDestinationDir(File destinationDir) { + profileFile = new File(destinationDir, "META-INF/grails-profile/profile.yml") + super.setDestinationDir(destinationDir) + } + + @TaskAction + void execute() { + + boolean profileYmlExists = config?.exists() + + def options = new DumperOptions() + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK) + def yaml = new Yaml(new SafeConstructor(new LoaderOptions()), new Representer(options), options) + Map profileData + if (profileYmlExists) { + profileData = (Map) config.withReader { BufferedReader r -> + yaml.load(r) + } + } else { + profileData = new LinkedHashMap() + } + + profileData.put(PROFILE_NAME, project.name) + + profileFile.parentFile.mkdirs() + + + if (!profileData.containsKey("extends")) { + List dependencies = [] + project.configurations.getByName(GrailsProfileGradlePlugin.RUNTIME_CONFIGURATION).allDependencies.all() { Dependency d -> + dependencies.add("${d.group}:${d.name}:${d.version}".toString()) + } + profileData.put("extends", dependencies.join(',')) + } + + def groovySourceFiles = getSource().files.findAll() { File f -> + f.name.endsWith('.groovy') + } as File[] + def ymlSourceFiles = getSource().files.findAll() { File f -> + f.name.endsWith('.yml') && f.name != 'profile.yml' + } as File[] + + Map commandNames = [:] + for (File f in groovySourceFiles) { + def fn = f.name + commandNames.put(fn - '.groovy', fn) + } + for (File f in ymlSourceFiles) { + def fn = f.name + commandNames.put(fn - '.yml', fn) + } + + if (commandNames) { + profileData.put(PROFILE_COMMANDS, commandNames) + } + + if (profileYmlExists) { + def parentDir = config.parentFile.canonicalFile + def featureDirs = new File(parentDir, "features").listFiles({ File f -> f.isDirectory() && !f.name.startsWith('.') } as FileFilter) + if (featureDirs) { + Map map = (Map) profileData.get("features") + if (map == null) { + map = [:] + profileData.put("features", map) + } + List featureNames = [] + for (f in featureDirs) { + featureNames.add f.name + } + if (featureNames) { + map.put("provided", featureNames) + } + profileData.put("features", map) + } + } + + + List templates = [] + if (templatesDir?.exists()) { + project.fileTree(templatesDir).visit { FileVisitDetails f -> + if (!f.isDirectory() && !f.name.startsWith('.')) { + templates.add f.relativePath.pathString + } + } + } + + if (templates) { + profileData.put("templates", templates) + } + + profileFile.withWriter { BufferedWriter w -> + yaml.dump(profileData, w) + } + + if (groovySourceFiles) { + + CompilerConfiguration configuration = new CompilerConfiguration() + configuration.setScriptBaseClass(GroovyScriptCommand.name) + destinationDir.mkdirs() + configuration.setTargetDirectory(destinationDir) + + def importCustomizer = new ImportCustomizer() + importCustomizer.addStarImports("org.grails.cli.interactive.completers") + importCustomizer.addStarImports("grails.util") + importCustomizer.addStarImports("grails.codegen.model") + configuration.addCompilationCustomizers(importCustomizer, new ASTTransformationCustomizer(new GroovyScriptCommandTransform())) + + for (source in groovySourceFiles) { + + CompilationUnit compilationUnit = new CompilationUnit(configuration) + configuration.compilationCustomizers.clear() + configuration.compilationCustomizers.addAll(importCustomizer, new ASTTransformationCustomizer(new GroovyScriptCommandTransform())) + compilationUnit.addSource(source) + compilationUnit.compile() + } + } + } +} From 8ee9367c56bb0bec7eb6b954f040e006e74588cf Mon Sep 17 00:00:00 2001 From: Scott Murphy Heiberg Date: Wed, 7 Aug 2024 23:29:55 -0500 Subject: [PATCH 5/7] Link to Grails Snapshot version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 844b3427..fbb5a784 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ projectVersion=6.2.1-SNAPSHOT -grailsVersion=6.2.0 +grailsVersion=6.2.1-SNAPSHOT springBootVersion=2.7.18 org.gradle.caching=true From f1623f58b3cb743ccd196ad6a482f3066de52f3e Mon Sep 17 00:00:00 2001 From: James Fredley Date: Tue, 13 Aug 2024 16:17:13 -0400 Subject: [PATCH 6/7] Update to gradle 7 compatibility (#316) defaultExclude changes moved to settings.gradle in each grails profile project --- .../profiles/GrailsProfileGradlePlugin.groovy | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy b/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy index 570a9bb0..6776992a 100644 --- a/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy +++ b/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy @@ -18,7 +18,6 @@ package org.grails.gradle.plugin.profiles import grails.io.IOUtils import grails.util.BuildSettings import groovy.transform.CompileStatic -import org.apache.tools.ant.DirectoryScanner import org.gradle.api.Action import org.gradle.api.Plugin import org.gradle.api.Project @@ -96,15 +95,6 @@ class GrailsProfileGradlePlugin implements Plugin { def processResources = project.tasks.create("processResources", Copy, (Action){ Copy c -> c.with(spec1, spec2, spec3, spec4) c.into(new File(resourcesDir, "/META-INF/grails-profile")) - - c.doFirst { - for(String file in DirectoryScanner.defaultExcludes) { - DirectoryScanner.removeDefaultExclude(file) - } - } - c.doLast { - DirectoryScanner.resetDefaultExcludes() - } }) def classsesDir = new File(project.buildDir, "classes/profile") @@ -128,15 +118,6 @@ class GrailsProfileGradlePlugin implements Plugin { ArchivePublishArtifact jarArtifact = new ArchivePublishArtifact(jar) project.artifacts.add(CONFIGURATION_NAME, jarArtifact) - - jar.doFirst { - for(String file in DirectoryScanner.defaultExcludes) { - DirectoryScanner.removeDefaultExclude(file) - } - } - jar.doLast { - DirectoryScanner.resetDefaultExcludes() - } }) project.tasks.create("sourcesJar", Jar, (Action) { Jar jar -> @@ -155,14 +136,6 @@ class GrailsProfileGradlePlugin implements Plugin { jar.setDescription("Assembles a jar archive containing the profile sources.") jar.setGroup(BUILD_GROUP) - jar.doFirst { - for(String file in DirectoryScanner.defaultExcludes) { - DirectoryScanner.removeDefaultExclude(file) - } - } - jar.doLast { - DirectoryScanner.resetDefaultExcludes() - } }) project.tasks.findByName("assemble").dependsOn jarTask From a7cc754e1fc69ba33df8119518af4bb16b5ed07f Mon Sep 17 00:00:00 2001 From: Scott Murphy Heiberg Date: Thu, 15 Aug 2024 21:25:23 -0600 Subject: [PATCH 7/7] Gradle 8.10 compatibility --- .../web/gsp/GroovyPageForkCompileTask.groovy | 11 ++++++-- .../plugin/web/gsp/GspCompileOptions.groovy | 25 ++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageForkCompileTask.groovy b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageForkCompileTask.groovy index 043520f1..6d8cdc43 100644 --- a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageForkCompileTask.groovy +++ b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageForkCompileTask.groovy @@ -4,11 +4,13 @@ import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import org.gradle.api.Action import org.gradle.api.file.FileTree +import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.* import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.process.ExecResult import org.gradle.process.JavaExecSpec +import javax.inject.Inject import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths @@ -22,7 +24,7 @@ import java.nio.file.Paths * @since 4.0 */ @CompileStatic -class GroovyPageForkCompileTask extends AbstractCompile { +abstract class GroovyPageForkCompileTask extends AbstractCompile { @Input @Optional @@ -46,8 +48,13 @@ class GroovyPageForkCompileTask extends AbstractCompile { @Optional String serverpath + @Inject + protected ObjectFactory getObjectFactory() { + throw new UnsupportedOperationException(); + } + @Nested - GspCompileOptions compileOptions = new GspCompileOptions() + GspCompileOptions compileOptions = getObjectFactory().newInstance(GspCompileOptions.class) @Override @PathSensitive(PathSensitivity.RELATIVE) diff --git a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy index d093490f..a21376fb 100644 --- a/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy +++ b/src/main/groovy/org/grails/gradle/plugin/web/gsp/GspCompileOptions.groovy @@ -1,22 +1,29 @@ package org.grails.gradle.plugin.web.gsp +import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.Input import org.gradle.api.tasks.Nested -import org.gradle.api.tasks.compile.BaseForkOptions +import org.gradle.api.tasks.compile.AbstractOptions import org.gradle.api.tasks.compile.GroovyForkOptions +import javax.inject.Inject; /** -* Presents the Compile Options used by the {@llink GroovyPageForkCompileTask} -* -* @author David Estes -* @since 4.0 -*/ -class GspCompileOptions implements Serializable { + * Presents the Compile Options used by the {@llink GroovyPageForkCompileTask} + * + * @author David Estes + * @since 4.0 + */ +abstract class GspCompileOptions extends AbstractOptions { private static final long serialVersionUID = 0L; @Input - String encoding = "UTF-8" + String encoding = "UTF-8" + + @Inject + protected ObjectFactory getObjectFactory() { + throw new UnsupportedOperationException(); + } @Nested - GroovyForkOptions forkOptions = new GroovyForkOptions() + GroovyForkOptions forkOptions = getObjectFactory().newInstance(GroovyForkOptions.class) } \ No newline at end of file