Add source file extension in gradle - gradle

I am trying to tell gradle that files with the *.dsl extension should be compiled as groovy files, so I have added a source set with the inclusion pattern and changed the compile task includes property:
sourceSets {
...
dsl_scripts {
groovy {
include '**/*.dsl'
}
}
}
compileDsl_scriptsGroovy.includes = ['**/*.dsl']
But when I run the build under a debug mode it skips all *.dsl files with the following message:
Skipping task ':compileDsl_scriptsGroovy' as it has no source files
The following line successfully outputs all the files I try to compile:
println sourceSets.dsl_scripts.allSource.matching({include '**/*.dsl'}).getFiles()
What do I do wrong?
EDIT:
I found the following snippet in gradle sources:
FileCollection groovyJavaOnly = spec.getSource().filter(new Spec<File>() {
public boolean isSatisfiedBy(File element) {
return element.getName().endsWith(".groovy") || element.getName().endsWith(".java");
}
});
spec.setSource(new SimpleFileCollection(groovyJavaOnly.getFiles()));
Is it possible to override?

It seems to be a gradle bug http://issues.gradle.org/browse/GRADLE-2372

Related

Codenarc unable to resolve groovy classes

I am using codenarc 1.4 with gradle to test groovy code in a Jenkins shared library, but when running it outputs errors saying it was unable to resolve groovy.lang.Closure though this doesn't seem to prevent the checks being run.
An example of the code that's hitting the problem is
interface IStepExecutor {
int sh(String command)
void dir(String path, Closure commands)
...
when codenarc is run the following error is produced:
file:/.../IStepExecutor.groovy: 8: unable to resolve class Closure
# line 8, column 27.
void dir(String path, Closure commands)
^
The codenarc parts of my gradle config is as follows:
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.5.7'
testCompile "org.spockframework:spock-core:1.3-groovy-2.5"
}
codenarc {
toolVersion = "1.4"
}
codenarcMain {
configFile = file("config/codenarc/CodeNarcMain.groovy")
source = 'src'
compilationClasspath += files('src/')
}
codenarcTest {
configFile = file("config/codenarc/CodeNarcMain.groovy")
source = 'src'
compilationClasspath += files('src/')
}
I can stop the error messages by adding an import groovy.lang.Closure but that causes the UnnecessaryGroovyImport rule to error. Is there a way to prevent these errors being reported without removing the UnnecessaryGroovyImport rule?
I'm also using CodeNarc with Gradle for Jenkins shared library tests and found adding the following to my Gradle configuration fixed a similar issue:
codenarcMain {
compilationClasspath = sourceSets.main.compileClasspath + sourceSets.main.output
}
codenarcTest {
compilationClasspath = codenarcMain.compilationClasspath + sourceSets.test.compileClasspath + sourceSets.test.output
}
I found this in a comment on a CodeNarc issue on GitHub.
I think the problem is something to do with each file being compiled in isolation for static analysis which is different from the normal compilation steps in Gradle. I'm very new to this though so maybe misunderstanding it.

GZip every file with Gradle 5.x and higher

We currently have a Gradle (v4.10.3) build script that compresses every static resource during build time. Below is a snippet of the code that we have:
tasks.register("gzipJsFiles") {
doLast {
fileTree(dir: "${buildDir}/classes/main/static/js", include: "**/*.min.js", exclude: "*.gz").eachWithIndex { file, index ->
def dynamicTask = "gzipJs-$file.name"
task "${dynamicTask}" (type: GzipJsTask) {
source = file
dest = Paths.get(file.absolutePath + ".gz").toFile()
}
tasks."$dynamicTask".execute()
}
}}
Now, with the latest versions of Gradle, the Task.execute() is being deprecated.
Is there a way to achieve the GZip task, to zip every file in file tree, individually with the newer versions of Gradle (5.x or higher)?
I don't know where the GzipJsTask comes from, but if it is the one from gradle-js-plugin, you can see from the source code that it is simply a wrapper around some Ant commands. So instead of creating Gradle tasks dynamically at execution time, which is no longer possible, just run the commands directly:
doLast {
fileTree(dir: "${buildDir}/classes/main/static/js", include: "**/*.min.js", exclude: "*.gz").each { file ->
ant.gzip(src: file.absolutePath, destfile: file.absolutePath + ".gz")
}
}

Gradle doesn't emit kotlin.js

I'm trying to compile my Kotlin app and set of Kotlin libraries to JavaScript. I've got that working well, but when I try to run it it can't find kotlin.js.
So what's going on here? When I compile using IDEA (instead of Gradle), it outputs kotlin.js just fine. I tried making my build script more like an example I found, but that wouldn't compile...
Here's a link to the code and project in question: https://github.com/BlueHuskyStudios/Decision-Cruncher/blob/SO/q/53582651/1/build.gradle
This only worked for me. unzip for some reason was no working
task assembleWeb() {
configurations.implementation.setCanBeResolved(true)
configurations.implementation.each { File file ->
if (file.path.indexOf('kotlin-stdlib-js') >= 0) {
exec {
workingDir "$projectDir/web"
standardOutput = new ByteArrayOutputStream()
commandLine "7z", "e", file.absolutePath, "kotlin.js", "-aos", "-r"
}
}
}
dependsOn classes
}
assemble.dependsOn assembleWeb
Be aware of "-aos" param. This flag will prevent from overwriting of existing file
Here you can find the code snippet to extract all .js files from Kotlin/JS libraries:
task assembleWeb(type: Sync) {
configurations.compile.each { File file ->
from(zipTree(file.absolutePath), {
includeEmptyDirs = false
include { fileTreeElement ->
def path = fileTreeElement.path
path.endsWith(".js") && (path.startsWith("META-INF/resources/") ||
!path.startsWith("META-INF/"))
}
})
}
from compileKotlin2Js.destinationDir
into "${projectDir}/web"
dependsOn classes
}
assemble.dependsOn assembleWeb
For any others struggling in the future, I've had the following issue:
IntelliJ Kotlin/JS starter project has been generated with this in the gradle file:
implementation "org.jetbrains.kotlin:kotlin-stdlib-js"
which needs to be this to get the kotlin.js file
compile "org.jetbrains.kotlin:kotlin-stdlib-js"

How to set Eclipse's output directory from Gradle

I am using Gradle's eclipse plugin. For cross-project reference reasons, I need Eclipse's output directory to not be the default bin, rather ecbuild.
Everytime I run ./gradlew eclipse, it overwrites this output directory setting.
How to make sure it doesn't, or how to set it within gradle build script ?
Add this to the build.gradle script:
eclipse {
classpath { defaultOutputDir = file('ecbuild') }
}
This might require you to upgrade the version of your gradle wrapper.
If so, run :
./gradlew wrapper --gradle-version 3.3
In my case, seting defaultOutputDir was not enough. So I did the following:
eclipse {
classpath {
defaultOutputDir = file("build")
file.whenMerged {
entries.each { entry ->
if (entry.kind == 'src' && entry.hasProperty('output')) {
entry.output = entry.output.replace('bin/', "build/")
}
}
}
}
}

How to add gradle generated source folder to Eclipse project?

My gradle project generates some java code inside gen/main/java using annotation processor. When I import this project into Eclipse, Eclipse will not automatically add gen/main/java as source folder to buildpath. I can do it manually. But is there a way to automate this?
Thanks.
You can easily add the generated folder manually to the classpath by
eclipse {
classpath {
file.whenMerged { cp ->
cp.entries.add( new org.gradle.plugins.ide.eclipse.model.SourceFolder('gen/main/java', null) )
}
}
}
whereby null as a second constructor arg means that Eclipse should put the compiled "class" files within the default output folder. If you want to change this, just provide a String instead, e.g. 'bin-gen'.
I think it's a little bit cleaner just to add a second source directory to the main source set.
Add this to your build.gradle:
sourceSets {
main {
java {
srcDirs += ["src/gen/java"]
}
}
}
This results in the following line generated in your .classpath:
<classpathentry kind="src" path="src/gen/java"/>
I've tested this with Gradle 4.1, but I suspect it'd work with older versions as well.
Andreas' answer works if you generate Eclipse project from command line using gradle cleanEclipse eclipse. If you use STS Eclipse Gradle plugin, then you have to implement afterEclipseImport task. Below is my full working snippet:
project.ext {
genSrcDir = projectDir.absolutePath + '/gen/main/java'
}
compileJava {
options.compilerArgs += ['-s', project.genSrcDir]
}
compileJava.doFirst {
task createGenDir << {
ant.mkdir(dir: project.genSrcDir)
}
createGenDir.execute()
println 'createGenDir DONE'
}
eclipse.classpath.file.whenMerged {
classpath - >
def genSrc = new org.gradle.plugins.ide.eclipse.model.SourceFolder('gen/main/java', null)
classpath.entries.add(genSrc)
}
task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
doLast {
compileJava.execute()
def classpath = new XmlParser().parse(file(".classpath"))
new Node(classpath, "classpathentry", [kind: 'src', path: 'gen/main/java']);
def writer = new FileWriter(file(".classpath"))
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.setPreserveWhitespace(true)
printer.print(classpath)
}
}

Resources