How to add new sourceset with gradle kotlin-dsl - gradle

I want to add a sourceset src/gen/java. With groovy this is rather easy and already described in https://discuss.gradle.org/t/how-to-use-gradle-with-generated-sources/9401/5
sourceSets {
gen {
java.srcDir "src/gen/java"
}
}
But I stuck with the kotlin-dsl to add a new one. All I've got is:
java {
sourceSets {
}
}
Can anyone help here to

The answer of #s1m0nw1 is correct to add a new sourceset.
But to just add a new source-folder in an existing sourceset, this can be used:
java.sourceSets["main"].java {
srcDir("src/gen/java")
}

You should try the following:
java.sourceSets.create("src/gen/java")
Hope it's what you need!

Worked for me on Gradle 4.10.2:
sourceSets.getByName("main") {
java.srcDir("src/main/java")
java.srcDir("src/main/kotlin")
}
sourceSets.getByName("test") {
java.srcDir("src/test/java")
java.srcDir("src/test/kotlin")
}
The codes above can also be used in subprojects block.

Worked for me on Gradle 4.10.2:
sourceSets.create("integrationTest") {
java.srcDir("src/integrationTest/java")
java.srcDir("build/generated/source/apt/integrationTest")
resources.srcDir("src/integrationTest/resources")
}

kotlin-dsl
sourceSets {
this.getByName("androidTest"){
//Adds the given source directory to this set.
this.java.srcDir("src/mock/java")
}
this.getByName("test"){
this.java.srcDir("src/mock/java")
}
}

I wanted to add a source set with the name "test-integration" and the source directory src/test-integration/kotlin. I was able to accomplish that by combining the two pre-existing answers:
java.sourceSets.create("test-integration").java {
srcDir("src/test-integration/kotlin")
}

As of Gradle 7.5:
sourceSets {
main {
java.sourceSets {
create("gen"){
java.srcDir("src/gen/java")
}
}
}
}

This is what I had before:
main.kotlin.srcDirs = main.java.srcDirs = ['src']
test.kotlin.srcDirs = test.java.srcDirs = ['test']
main.resources.srcDirs = ['resources']
test.resources.srcDirs = ['testresources']
Above now translates to:
sourceSets {
main {
java {
srcDirs("src")
}
resources {
srcDirs("resources")
}
}
test {
java {
srcDirs("test")
}
resources {
srcDirs("testresources")
}
}}

Related

Declare Gradle buildSrc plugin using Kotlin DSL

I'm trying to figure out how to convert this configuration to the Kotlin DSL, but I can't find much in the way of examples:
gradlePlugin {
plugins {
javaConventionsPlugin {
id = "build.java-conventions"
implementationClass = "buildlogic.plugins.JavaConventionsPlugin"
}
}
}
What would this declaration look like using Kotlin?
It is documented in the guide: https://docs.gradle.org/current/userguide/java_gradle_plugin.html#sec:gradle_plugin_dev_usage
The way you have also works. Any of the following would also work:
gradlePlugin {
plugins {
register("javaConventionsPlugin") {
id = "build.java-conventions"
implementationClass = "buildlogic.plugins.JavaConventionsPlugin"
}
}
}
gradlePlugin {
plugins {
create("javaConventionsPlugin") {
id = "build.java-conventions"
implementationClass = "buildlogic.plugins.JavaConventionsPlugin"
}
}
}
The former uses Gradle's lazy configuration.
This is what I've found so far, not sure if there's a more fluent way to do it:
gradlePlugin {
val javaConventionsPlugion = plugins.register("javaConventionsPlugin")
javaConventionsPlugion.configure {
id = "build.java-conventions"
implementationClass = "buildlogic.plugins.JavaConventionsPlugin"
}
}

Gradle: how to run a task for specified input files?

I have a Gradle build file which uses ProtoBuffer plugin and runs some tasks. At some point some tasks are run for some files, which are inputs to tasks.
I want to modify the set of files which is the input to those tasks. Say, I want the tasks to be run with files which are listed, one per line, in a particular file. How can I do that?
EDIT: Here is a part of rather big build.gradle which provides some context.
configure(protobufProjects) {
apply plugin: 'java'
ext {
protobufVersion = '3.9.1'
}
dependencies {
...
}
protobuf {
generatedFilesBaseDir = "$projectDir/gen"
protoc {
if (project.hasProperty('protocPath')) {
path = "$protocPath"
}
else {
artifact = "com.google.protobuf:protoc:$protobufVersion"
}
}
plugins {
...
}
generateProtoTasks {
all().each { task ->
...
}
}
sourceSets {
main {
java {
srcDirs 'gen/main/java'
}
}
}
}
clean {
delete protobuf.generatedFilesBaseDir
}
compileJava {
File generatedSourceDir = project.file("gen")
project.mkdir(generatedSourceDir)
options.annotationProcessorGeneratedSourcesDirectory = generatedSourceDir
}
}
The question is, how to modify the input file set for existing task (which already does something with them), not how to create a new task.
EDIT 2: According to How do I modify a list of files in a Gradle copy task? , it's a bad idea in general, as Gradle makes assumptions about inputs and outputs dependencies, which can be broken by this approach.
If you would have added the gradle file and more specific that would have been very helpful. I will try to give an example from what I have understood:
fun listFiles(fileName: String): List<String> {
val file = file(fileName).absoluteFile
val listOfFiles = mutableListOf<String>()
file.readLines().forEach {
listOfFiles.add(it)
}
return listOfFiles
}
tasks.register("readFiles") {
val inputFile: String by project
val listOfFiles = listFiles(inputFile)
listOfFiles.forEach {
val file = file(it).absoluteFile
file.readLines().forEach { println(it) }
}
}
Then run the gradle like this: gradle -PinputFile=<path_to_the_file_that_contains_list_of_files> readFiles

Idea Gradle integration add classes as a test source tree, but don't include in test sourceSet

I would like to mark the classes of my systest sourceSet as unit test classes. I tried to mark them with the following code:
sourceSets {
main {
groovy {
srcDirs = [
'src/main/masks'
}
resources {
srcDirs += 'src/main/journaltemplates'
}
}
/* This brings up systest in the test resources */
test.java.srcDir 'src/systest/java'
test.resources.srcDir 'src/systest/resources'
systest {
java {
srcDirs = ['src/systest/java']
}
resources {
srcDirs = ['src/systest/resources']
}
}
}
With this solution the sourceset got marked as unit test class, but was additionally added to the test sourceSet which is not desired. I want to keep the classes in the systest sourceSet and specify that the systest sourceSet, is a unit test sourceSet. I want the same behaviour for the systest sourceSet as for the test sourceSet, but they should be distinct sourceSets.
The second solution i tried was using the idea plugin for gradle and modify the module setting, as seen in this SO post:
idea {
module {
testSourceDirs += file('src/systest')
}
}
The problem with this solution is that the systest sources are added to the test sourceSet too.
Hopefully this is clear enough, otherwise please comment. Thank you.
There is a dedicated Gradle feature called Declarative Test Suite that supports this case:
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
}
register("integrationTest", JvmTestSuite::class) {
dependencies {
implementation(project())
}
targets {
all {
testTask.configure {
shouldRunAfter(test)
}
}
}
}
}
}
More:
https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests
Please try this configuration:
apply plugin: "idea"
sourceSets {
systest {
java {
compileClasspath = test.output + main.output
runtimeClasspath = output + compileClasspath
}
}
}
idea {
module {
testSourceDirs = sourceSets.systest.allSource.srcDirs
}
}

How to configure the processResources task in a Gradle Kotlin build

I have the following in a groovy-based build script. How do I do the same in a kotlin-based script?
processResources {
filesMatching('application.properties'){
expand(project.properties)
}
}
Why not to just use "withType" ?
I just mean (IMHO)
tasks {
withType<ProcessResources> {
..
}
looks much better than
tasks {
"processResources"(ProcessResources::class) {
..
}
So,
tasks.withType<ProcessResources> {
//from("${project.projectDir}src/main/resources")
//into("${project.buildDir}/whatever/")
filesMatching("*.cfg") {
expand(project.properties)
}
}
EDIT:
With newer release you can just do:
tasks.processResources {}
or
tasks { processResources {} }
generated accessors are "lazy" so it has all the benefits and no downsides.
I think task should look like:
Edit: According this comment in gradle/kotlin-dsl repository. Task configuration should work this way:
import org.gradle.language.jvm.tasks.ProcessResources
apply {
plugin("java")
}
(tasks.getByName("processResources") as ProcessResources).apply {
filesMatching("application.properties") {
expand(project.properties)
}
}
Which is pretty ugly. So i suggest following utility function for this purpose, until one upstream done:
configure<ProcessResources>("processResources") {
filesMatching("application.properties") {
expand(project.properties)
}
}
inline fun <reified C> Project.configure(name: String, configuration: C.() -> Unit) {
(this.tasks.getByName(name) as C).configuration()
}
With updates to the APIs in newer release of the Kotlin DSL and Gradle, you can do something like:
import org.gradle.language.jvm.tasks.ProcessResources
plugins {
java
}
tasks {
"processResources"(ProcessResources::class) {
filesMatching("application.properties") {
expand(project.properties)
}
}
}
And also:
val processResources by tasks.getting(ProcessResources::class) {
filesMatching("application.properties") {
expand(project.properties)
}
}

How to access list of values from gradle.properties to build.gradle

I have the following gradle.properties
version=2.1
paths=['/home/desk/hie', '/home/mydesk1/hai1', '/home/mydesk2/hai2']
sources=['/src/path/impl', '/src/path/src']
I need to access these paths and sources form gradle.properties to build.gradle
sourceSets {
main {
java {
srcDir=${paths}
}
}
}
but ${paths} is not working.
Can you someone help to get out of this issue and how to use those list in build.gradle file
Consider the following, which converts the paths String to an Iterable (that is, a List):
apply plugin: 'java'
def pathsList = Eval.me(project.ext.paths)
sourceSets {
main {
java {
srcDirs = pathsList
}
}
}
You can share the value using gradle object:
// settings.gradle
gradle.ext {
paths = ['/home/desk/hie', '/home/mydesk1/hai1', '/home/mydesk2/hai2']
}
// build.gradle
sourceSets {
main {
java {
srcDir = paths
}
}
}

Resources