Hello. Learning Gradle and noticed in some cases `...
# community-support
b
Hello. Learning Gradle and noticed in some cases
build.gradle.kts
wants the
setX(value)
syntax, in others
x = value
, for example in:
Copy code
sourceSets {
  main {
    java {
      setSrcDirs(listOf("somedir"))
      destinationDirectory = File("otherdir")
    }
  }
}
I.e.,
setDestinationDirectory(...)
doesn't compile, and neither does
srcDirs = ...
. Am I doing this wrong?
v
No.
destinationDirectory
is Kotlin sugar for calling
getDestinationDirectory()
which returns a
DirectoryProperty
, so the "natural" way is to do
destinationDirectory.set(...)
but there is some syntax sugar that you can do
destinationDirectory = ...
instead. With the
srcDirs
it is a bit different,
getSrcDirs()
returns a copy of the src dirs a new
Set<File>
, so even if you could call
add
and so on on it, it would not have any effect. You can call
srcDir(...)
to add a src dir, or you can use
setSrcDirs(listOf(...))
to overwrite all already defined src dirs.
Besides that, you should never use
File(...)
with a relative path. In practically all JVM code this is a very bad idea, because the
File
constructor resolves relative paths relative to the current working directory, so is always depending on the users current working directory. The only valid use-case I'm aware is, if you code some commandline utility and the relative path is coming from the user calling the utility in which case you can usually safely assume the given path is relative to the current user's working directory. In Gradle logic this is even more problematic, as the current working directory of the Gradle daemon is the on that is used to resolve the relative path. This working directory can be the root project's project directory, but this is not guaranteed and sometimes not the case. So in your case you most probably would have wanted to do
destinationDirectory = layout.projectDirectory.dir("otherdir")
b
srcDirs.set(...)
doesn't work either. I'm just trying to find a universal way to set values, but maybe there isn't one?
I mean, from your explanation it sounds like you've got to know and understand the exact class you're working with while setting values.
v
srcDirs.set(...)
doesn't work either.
Yes, why should it work?
srcDirs
is giving you a
Set<File>
as I just explained and that does not have a method called
set
and even if it would have, it would not have any effect as it is just a copy as I just explained.
I'm just trying to find a universal way to set values, but maybe there isn't one?
No, there isn't in this case.
I mean, from your explanation it sounds like you've got to know and understand the exact class you're working with while setting values.
Like with any API you use. 😄
b
sounds like it needs a full IDE to be able to write script files then, to have the autocomplete and everything I don't think simply reading https://docs.gradle.org/current/userguide/java_plugin.html#source_sets is enough in this case problem is, when you're writing Gradle build files in an IDE, and the IDE loads the current project from those build files, making mistakes while editing kind of screws up the entire project/IDE state ... again, maybe I'm doing this wrong? Maybe the
build.gradle.kts
is better edited as an arbitrary Kotlin file, not the project build file
feels like the Gradle community should have this figured out by now and I'm not just not doing it right
I wonder if there's a declarative Gradle build syntax that hides all the type complexity away, that you can load and then add custom kotlin code if needed on top?
v
sounds like it needs a full IDE
Well, like with any coding, it greatly helps if you have a good IDE like IntelliJ IDEA or Android Studio, especially when using the Kotlin DSL which has much better IDE support than Groovy DSL due to the dynamic nature of Groovy. And if you don't use an IDE to edit any code, you just have to know the API and how to use it as you just a text editor. But usually the Userguide should provide you with appropriate examples how to do it, so it should usually be sufficient to edit the build script, even if not supported by IDE, it's just not as convenient.
king mistakes while editing kind of screws up the entire project/IDE state
Indeed, but usually not while editing. By default IntelliJ for example only reloads the project when either an external change is detected, or if you trigger the reload manually, so that you can do changes without breaking the reload and then trigger the reload when finished. If you broke it an lost IDE support, what I usually do is commenting out the problematic code, then reload the project so that IDE assistence is there again, then I comment back in the code and use IDE assistence to do what I want to do before I then reload again.
Maybe the
build.gradle.kts
is better edited as an arbitrary Kotlin file, not the project build file
Not really, that would then only work much worse if at all, as the context is different then.
I wonder if there's a declarative Gradle build syntax that hides all the type complexity away,
There is the "Declarative Gradle" project that should provide exactly what you are after, but this is in a very early stage. You can have a look at #C06JG95HREY and at the Gradle Blog posts relating to it.
b
I see. Thanks for all the explanations!
👌 1