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)
}
}
Related
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"
}
}
Consider this toy build.gradle file:
plugins {
id "java"
}
import org.gradle.internal.os.OperatingSystem;
apply plugin: 'java'
repositories {
mavenLocal()
mavenCentral()
}
def pathExists(pathname) {
// Returns true iff pathame is an existing file or directory
try {
// This may throw an error for a Windows pathname, c:/path/to/thing
if (file(pathname).exists()) {
return true;
}
} catch (GradleException e) {
// I don't care
}
if (OperatingSystem.current().isWindows()) {
try {
// If we're on Windows, try to make c:/path/to/thing work
if (file("file:///${pathname}").exists()) {
return true;
}
} catch (GradleException e) {
// I don't care
}
}
return false
}
def someVariable = "absent"
if (pathExists("/tmp")) {
someVariable = "present"
}
task someCommonTask() {
doLast {
println("Did some setup stuff: ${someVariable}")
}
}
task someATask(dependsOn: ["someCommonTask"]) {
doLast {
println("A: ${someVariable}")
}
}
task someBTask(dependsOn: ["someCommonTask"]) {
def otherVariable = someVariable == "absent" || pathExists("/etc")
doLast {
println("B: ${otherVariable}")
}
}
Is it possible to reorganize this build file so that someATask is in a.gradle and someBTask is in b.gradle? I've made some attempts to use apply from: without success and, if the answer is on this page: https://docs.gradle.org/current/userguide/organizing_gradle_projects.html it eludes me.
In the real project, there would be a couple of dozen tasks in each of those subordinate files and the goal of dividing up the build.gradle file isn't to have them be subprojcts, per se, they're just logical groupings of tasks.
This split can be done using apply from: ... to separate the files.
E.g.
build.gradle:
plugins {
id "java"
}
apply plugin: 'java'
repositories {
mavenLocal()
mavenCentral()
}
ext {
someVariable = "absent" // XXX
}
apply from: "setup.gradle" // XXX
apply from: "common.gradle" // XXX
task someATask(dependsOn: ["someCommonTask"]) {
doLast {
println("A: ${someVariable}")
}
}
setup.gradle:
task setup() {
someVariable = "present"
}
common.gradle:
task someCommonTask(dependsOn: ["setup"]) {
doLast {
println("Did some setup stuff: ${someVariable}")
}
}
# gradle someATask
> Task :someCommonTask
Did some setup stuff: present
> Task :someATask
A: present
BUILD SUCCESSFUL in 403ms
My guess, the problems you are facing are with toplevel code and not
using properties.
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
I defined two tasks in my build.gradle
task a(type: JavaExec) {
}
task b(type: JavaExec) {
}
When I execute task a, b also runs. Is this normal?
gradle a
I'm sharing my own experience for others.
I am a newbie on groovy/gradle.
What I tried to achieve was using a shared function for getting project properties.
def projectProperty = {
if (!project.hasProperty(it)) {
throw new Exception...
}
return project.getProperty(it);
}
task a(type: JavaExec) {
do some with projectProperty(a);
}
task b(type: JavaExec) {
do some with projectProperty(b);
}
And I changed like this.
task a(type: JavaExec) {
if (project.hasProperty('a')) {
do some with projectProperty('a');
}
}
task b(type: JavaExec) {
if (project.hasProperty('b')) {
do some with projectProperty('b');
}
}
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")
}
}}