mzywiol
mzywiol

Reputation: 436

How to combine input parser with fullRunInputTask?

In my build.sbt I want to have a task with input parameters that calls a main method in my code, but I'd like to have the parameters parsed before calling the method.

This is the InputKey definition:

val clearDatabase = inputKey[Unit]("Clear database, arguments:  endpoint user password")

A parser I'd like to use:

val databaseTaskParser = sbt.Def.spaceDelimited("endpoint username password").map(_.toList).map {
  case List(endpoint) => (endpoint, "", "")
  case List(endpoint, username, password) => (endpoint, username, password)
  case _ =>
    sys.error("Supported arguments: \"endpoint\" or \"endpoint username password\"")
}

And then I know that to pass input arguments to the main method I need to use fullRunInputTask parametrized with the InputKey defined above:

fullRunInputTask(clearDatabase, Compile, "my.code.ClearDatabaseTask")

Now, how can I combine the call to fullRunInputTask with using the databaseTaskParser (to display error when a wrong set of parameters is given) even before themain method is called?

Upvotes: 4

Views: 151

Answers (1)

mzywiol
mzywiol

Reputation: 436

Okay, I found a way myself.

The most important thing here was that I need to use runTask instead of fullRunInputTask, but I need to wrap it in a dynamic input task in order to use the parser. And then I need to evaluate it to get the InputTask value for my inputKey.

So the actual task definition is:

clearDatabase := Def.inputTaskDyn {
  runTask(Compile, "my.code.ClearDatabaseTask", databaseTaskParser.parsed:_*)
}.evaluated

Now I also need to modify the parser to not return a tuple but a list or sequence, but still verify if the right number of params is passed. I did it like so:

val databaseTaskParser = sbt.Def.spaceDelimited("endpoint username password").map(_.toList).map {
  case args if List(1, 3).contains(args.length) => args.padTo(3, "")
  case _ =>
        sys.error("Supported arguments: \"endpoint\" or \"endpoint username password\"")
}

And this does the trick: sbt clearDatabase fails if given zero or two parameters and runs the main method in my.code.ClearDatabaseTask passing all the params if one or three are given, with no need for additional verification inside that method.

Upvotes: 1

Related Questions