A better way to passing parameters/options/arguments to tasks

I feel that Gradle needs a better way to allow users to pass arguments to individual tasks.

At the moment this can be achieved in three different ways:

  • defining to define properties via -Pmyprop=myvalue * defining JVM system properties via -Dmyprop=myvalue * handling optional arguments via a task rule (which from a usability means you get to pass one argument)

None of these are particularly great from a usability perspective.

The ideal solution (IMHO) would have been if Gradle’s own options had been restricted to only use a single dash, then double dashes (–) could have been used to pass parameters to each task in a way that most users would expect from convention (and conventions matter, right?).

However, if that is not possible to do, I realised today that task rules are indeed very flexible.

It is quite easy to introduce a new paradigm, by eg. defining a task rule around ‘+’ and then handling the remainder as a parameter, eg. +myparam=myvalue. The task rule can collect the options in a common object, similar to ext for example.

So for the time being this is the route we are going down.

But the ideal would have been something else. Is there any chance you can consider adding a way to pass command line arguments either by reworking how gradle uses “-” and “–”, or allow ‘—’ to pass arguments to a task and not go via a common global object?

Gradle’s built-in tasks can already have task-specific command line options. One example is the ‘dependencyInsight’ task (e.g. ‘dependencyInsight --configuration compile --dependency guava’).

Task-specific command line options aren’t currently part of Gradle’s public API, but I hope they will be in the future.

I would add to this that, the command line properties could be applied after evaluation. At this point, extensions and conventions would be applied, so that you know what to set specifically. E.g. project.javadoc means something at this point.

There’s also room here to apply the setting as groovy code, so that “.” (periods) can get applied properly. While you said in the title that would would be used to pass parameters to tasks, I would say that someone can run +project.tasks.compileJava.excludes="**/Exclude’ to arbitrarily address a task. If the value can’t be executed as Groovy code, then at least it can be parsed and tokenized by “.”, then applied in a hierarchy, e.g. in the above example, look up project, then tasks, then compileJava, then set excludes.

Like your idea Justin. My own idea to use task rules doesn’t work because task rules are evaluated last and not first as I had imagined. There are quite a few differences programmatically between task rules and default tasks than meets the eye at first glance (thinking in plugin terms).