doLast doesn't prompt user for input but doFirst does?


(James Maddison) #1

I have written a task to run my project using a main class chosen via user input however I am a tad confused about prompting the user for input.

My task:

task run(dependsOn: "classes", type: JavaExec) {
    description "Executes the project using the selected main class"
      doFirst {
        def selection = null
        def mainClasses = []
          // Select the java files with main classes in
        sourceSets.main.allJava.each {
            if(it.text.contains("public static void main")) {
                def pkg = relativePath(it) - 'src/main/java/' - '.java'
                pkg = pkg.tr "/", "."
                  println "${mainClasses.size()}. $pkg"
                mainClasses << pkg
            }
        }
          // Now prompt the user to choose a main class to use
        while(selection == null) {
            def input = System.console().readLine "#? "
              if(input?.isInteger()) {
                selection = input as int
                  if(selection >= 0 && selection < mainClasses.size()) {
                    break
                } else {
                    selection = null
                }
            } else if(input?.toLowerCase() == "quit") {
                return
            }
              if(selection == null) {
                println "Unknown option."
            }
        }
          main = mainClasses[selection]
        classpath = sourceSets.main.runtimeClasspath
    }
}

My confusion is because: If I don’t include the code in a ‘doFirst’ or ‘doLast’ closure the user is prompted for input during the configuration phase, I now understand that I need to put it in ‘doFirst’ or ‘doLast’ so that is only executed during the execution phase.

However the user will only be prompted for input if I use ‘doFirst’? If I use the ‘doLast’ closure then the user isn’t prompted, it just goes right through and complains that no main class was selected.


(Perryn Fowler) #2

doFirst and doLast add actions to your task.

Because your task is a JavaExec task it already has an action to execute a main class.

doFirst adds your task to prompt the user before this pre-existing action.

doLast adds it after (when it is too late).


(James Maddison) #3

Ahhh, of course. it’s all so obvious!