Is it possible to import Groovy into settings.gradle without having Groovy locally installed? - gradle

I have a settings.gradle in my project root as:
rootProject.name = 'root'
new File('.').eachFileRecurse FileType.FILES, { file ->
if (file.name.matches("build.gradle")) {
println "Dir name ${file.getParentFile().getName()}"
}
}
Script is used to list all directory names (last child) where build.gradle is found.
However this script doesn't work without an import groovy.io.FileType.
Any ideas to have that Groovy import included, without having it locally installed, into settings.gradle ?

Bro, Groovy is a part of Gradle by default, put that import statement back where it should be and everything is good, no worries.
If you don't trust me, delete your locally installed Groovy and check it out :)

Related

How to execute gradle task during project import in Intellij Idea

Let's assume my build.gradle file contains task generateSources which as name suggests generates additional java files. It's easy to ensure that generateSources is executed before compileJava: compileJava.dependsOn generateSources. How can I make sure generateSources is called when importing project into Intellij Idea as well?
To elaborate on #vladimir-sitnikov's answer: I added the idea-ext-plugin to my root project:
apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'
// ...
buildscript {
dependencies {
classpath "org.jetbrains.gradle.plugin.idea-ext:org.jetbrains.gradle.plugin.idea-ext.gradle.plugin:0.7"
}
}
Because without that I wasn't able to use it in my sub project, but now it works like this:
idea.project.settings.taskTriggers {
beforeSync tasks.getByName("generateSources")
}
Adding the plugin to the sub-project only didn't do it.
Note: The plugin's documentation is kind of limited, but in "DSL spec v. 0.2" is stated
beforeSync - before each Gradle project sync. Will NOT be executed on initial import
Didn't try that, but it works with existing projects.
This can be done via id("org.jetbrains.gradle.plugin.idea-ext") plugin (https://github.com/JetBrains/gradle-idea-ext-plugin).
See sample code in Gradle sources: https://github.com/gradle/gradle/blob/135fb4751faf2736c231636e8a2a92d47706a3b9/buildSrc/subprojects/ide/src/main/kotlin/org/gradle/gradlebuild/ide/IdePlugin.kt#L147
You can set the task in Gradle tool window: Execute Before Sync:

How to set the gradle outout folder for the kotlin2JS plugin?

I have a KotlinJs only project which I use official kotlin2js gradle to build, and no problems there.
How to setup the output folder, currently, the building of subproject will result in a build which locates inside the subproject folder, how to set it to somewhere else? I tried:
sourceSets {
main {
kotlin.outputDir = new File(‘./out/‘)
}
}
and
sourceSets {
main.kotlin.outputDir = new File(‘./out/’)
}
No luck.
What I want is to no matter how many subprojects are there, the output folder should be in some path like ./build/projectA and ./build/projectB, rather than all in their own folder. How to do this?
Currently, it's done through the task configuration, namely setting its kotlinOptions.outputFile:
compileKotlin2Js.kotlinOptions.outputFile = "out/output.js"
It's briefly mentioned in the tutorial: Getting Started with Kotlin and JavaScript with Gradle

gradle main task to zipup sub-projects distribution files

I have a gradle project which at main is using java plugin. At subproj1 - thru subproj4 the build.gradle files are also using application plugin. It works well in sub projects to compile the jars (with a main class) and create a distribution zipfile (using resources and dist files).
Now I want to build a 'main' dist zip file, comprising of the contents of all those subproj contents. I found I can run installDist to unzip to each of the subprojects build/install/subprojN
Now at a loss howto in the main only, have a task and/or dependency to create a "main" dist zip file containing: subproj1/** subproj2/** subproj3/** subproj4/**
My thoughts are to do a copy from('.').include('subproj*/build/install//')
then zip that up. but havent figured out howto add the task only at main level, plus have it not complain: NO SOURCE
thanks in advance
Here's an example that just uses two sub-projects, and does not show the compilation of the main code. That stuff should be easy to add. The key to the solution is the zip and zipfileset via the AntBuilder.
Consider this in the main build.gradle:
task uberBuild(dependsOn: ['subProj1:build',
'subProj2:build']) {
doLast {
ant.mkdir(dir: "${projectDir}/dist")
def PATH = "build/distributions"
ant.zip(destfile: "${projectDir}/dist/uber.zip") {
zipfileset(src: "${projectDir}/subProj1/${PATH}/subProj1.zip")
zipfileset(src: "${projectDir}/subProj2/${PATH}/subProj2.zip")
}
}
}
This will write ~/dist/uber.zip, which has the contents:
$ jar tf dist/uber.zip
subProj1/
subProj1/bin/
subProj1/lib/
subProj1/bin/subProj1
subProj1/bin/subProj1.bat
subProj1/lib/subProj1.jar
subProj2/
subProj2/bin/
subProj2/lib/
subProj2/bin/subProj2
subProj2/bin/subProj2.bat
subProj2/lib/subProj2.jar

Importing GeneratedSource in Gradle

I'm generating some source files via ANTLR. I want to use those files while writing my own source code.
When I use the generateGrammarSource task the code is perfectly generated but goes to the build\generated-src directory. When I import classes from that directory, both my build task and the make project compiles successfully. But IntelliSense is generating a metric ton of errors and warnings (mostly indicating that the imports are non-existent - Cannot resolve Symbol, even though they really are there).
Is this a problem with IntelliJ, what can I do to appease IntelliSense, so I can continue my work in peace?
Basically you should have the following setup:
def generatedDir = 'src/main/gen'
sourceSets {
main {
java {
srcDirs += [generatedDir]
}
}
}
task generateGrammarSource // need to generate the file under src/main/gen
compileTask.dependsOn(generateGrammarSource) // don't know the exact name of the compile task
clean << {
project.file(generatedDir).deleteDir()
}
You'll also need to add the generated sources to IntelliJ, google for it.

Gradle dependency destination on non-jar config file

I can create a dependency to something other than a jar file like this:
dependencies {
compile files("../other-project/config.txt")
}
The above works fine, except that config.txt ends up in the WEB-INF/lib folder of my war file. Instead I need it to be in WEB-INF/classes in the war file, and in src/main/resources for jettyRun.
How can I control where the dependency ends up? Or am I going about this the wrong way?
I can also solve this with a copy task, but this really is a dependency in that I don't need the file updated unless it changes. An unconditional copy would work, but I'd rather do this the right way.
The war task (as configured by the war plugin) puts dependencies into WEB-INF/lib, the web project's own code/resources into WEB-INF/classes, and web app content (which by default goes into src/main/webapp) into WEB-INF. Other content can be added by explicitly configuring the war task. For example:
war {
into("WEB-INF/classes") {
from "../other-project/config.txt"
}
}
One way to make this work with embedded Jetty (though maybe not the most convenient during development) is to use jettyRunWar instead of jettyRun. Another solution that comes to mind, particularly if the content to be added resides in its own directory, is to declare that directory as an additional resource directory of the web project (sourceSets.main.resources.srcDir "../other-project/someResourceDir"). This is in fact an alternative to configuring the war task. If the web project already has a dependency on the other project, you could instead configure an additional resource directory for that project.
Let's say you have configured a multi-project build with the following directory and file structure:
/combined-war
/main-project
/src
/webapp
/WEB-INF
web.xml
build.gradle
/other-project
/resources
/WEB-INF
/classes
config.txt
build.gradle
build.gradle
In order to allow jettyRun to combine the contents of the webapp directory from main-project with the contents of the resources directory in other-project you need to add a workaround to your build.gradle of main-project (I've adapted the one posted by the user siasia on gist).
Adding the same directory content to the war file is quite simple and is documented in the Gradle User Guide and and the DSL reference.
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'jetty'
import org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext
def newResourceCollection(File... resources) {
def script = '''
import org.mortbay.resource.ResourceCollection
new ResourceCollection(resources)
'''
def shell = new GroovyShell(JettyPluginWebAppContext.class.classLoader)
shell.setProperty("resources", resources as String[])
return shell.evaluate(script)
}
jettyRun.doFirst {
jettyRun.webAppConfig = new JettyPluginWebAppContext()
jettyRun.webAppConfig.baseResource = newResourceCollection(
// list the folders that should be combined
file(webAppDirName),
file("${project(':other-project').projectDir}/resources")
)
}
war {
from("${project(':other-project').projectDir}/resources")
}
Whenever you execute gradle jettyRun a new ResourceCollection is created that combines the given directories. Per default Jetty locks (at least on Windows) all the files it's serving. So, in case you want to edit those files while Jetty is running take a look at the following solutions.
Update
Since other-project in this case is not another Gradle project the two tasks in build.gradle should look like that:
jettyRun.doFirst {
jettyRun.webAppConfig = new JettyPluginWebAppContext()
jettyRun.webAppConfig.baseResource = newResourceCollection(
file(webAppDirName),
file("$projectDir/../other-project/resources")
)
}
war {
from("$projectDir/../other-project/resources")
}
I'm not aware of any solution that adds only one file (e.g. config.txt). You'll always have to add a complete directory.
As I mentioned above, it's simple enough to do an unconditional copy that solves the problem. Again, not the question I originally asked. But here's my solution that works for both war and jettyRun tasks:
processResources.doFirst {
copy {
from '../other-project/config.txt'
into 'src/main/resources'
}
}

Resources