0

I have been using Python's Invoke for a couple of years and I just love it. I can quickly write build tasks with documentation, and automatic parsing of custom flags. I have almost completely eradicated the need to write snippets of code in README files, and I think that's great.

I'm currently building a Kotlin+Gradle project and I'm looking for a plugin/library with similar capabilities.

With Gradle/Kotlin you can document a specific task and group them, however in order to define custom flags the default way of doing it is via setting Java System Properties with -D or -P. That works but it falls short compared to Invoke since I have to add a check for the existence of the property every time.

Also, it seems there's no built-in way to document each of the custom flags.

Do you know of a plugin/library that could compare to Invoke?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
pgpb.padilla
  • 2,318
  • 2
  • 20
  • 44
  • 1
    Why not just a Makefile? Otherwise you can write any CLI parser in a JVM language – OneCricketeer Nov 22 '19 at 08:00
  • @cricket_007 `make` works fine, however, documenting targets, and writing targets with custom flags, and also documenting the flags is not as easy as with Invoke. With make I generally pass "custom flags" via env-vars, which is sub-optimal and requires checking if the env-var was set, every time. Invoke does all the boring stuff for you. – pgpb.padilla Nov 22 '19 at 08:09
  • @cricket_007 In general I want to avoid building Invoke for the JVM-languages :) ... however I'm also hesitant to include this Python dependency in a JVM-based project . – pgpb.padilla Nov 22 '19 at 08:12
  • 2
    I'm not aware of anything as nice as that, but maybe this is close enough https://github.com/remkop/picocli – OneCricketeer Nov 22 '19 at 08:13

1 Answers1

1

I am not familiar with Invoke for Python, so I might not be the right one to give an answer. But if you like to pass values from the command line to a Gradle task, there are others ways than using project properties. One is to specify custom command line flags.

If this is not what you asked, and instead wanted a command line parser for your final application (and not for the build system), then something like Picocli would do, as already mentioned in the comments.

Here is an example of a Gradle task written in Kotlin that reads an optional command line flag:

open class OptionsExample
@javax.inject.Inject constructor(objectFactory: ObjectFactory) : DefaultTask() {
    @get:Internal
    @Option(option = "name", description = "Who to say hello to.")
    val name = objectFactory.property<String>()

    init {
        group = "example"
        description ="Says hello."
    }

    @TaskAction
    fun printMessage() {
        logger.lifecycle("Hello ${name.getOrElse("stranger")}")
    }
}

tasks.register("hello", OptionsExample::class)

This will register a task called hello that prints the name given by a flag, or a default message it not present.

When executed without the flag:

$ gradle hello

> Task :hello
Hello stranger

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

When executed with the flag:

$ gradle hello --name World

> Task :hello
Hello World

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

When printing the help page:

$ gradle -q help --task hello
Detailed task information for hello

Path
     :hello

Type
     OptionsExample (Build_gradle$OptionsExample)

Options
     --name     Who to say hello to.

Description
     Says hello.

Group
     example
Bjørn Vester
  • 6,851
  • 1
  • 20
  • 20