(This gist represents my current understanding of how this works… which is likely to be wrong or at least not completely right! 😀)
Each time .parsed or .evaluated is invoked, sbt consumes some input from the user, so it's not enough to do something like
inputA := parser.parsed
inputB := parser.parsed
combined := {
inputA.evaluated + inputB.evaluated
}You can map an InputTask to another task, but I couldn't make the typing work when mapping more than one.
However, with Def.inputTaskDyn, we can parse the input once for the dependent task, and then recreate the original input and pass it into the InputTasks that need it.
cloudformationOptions := cloudFormationOptionParser.parsed,
awsAccountId := cloudformationOptions.map(plugin.find[AwsAccountId]).evaluated,
awsRoleName := cloudformationOptions.map(plugin.find[AwsRoleName]).evaluated,
stackRoleArn := Def.inputTaskDyn {
// parse the input string into a sequence of our case classes
// using the parser this way means we get the benefit of tab completion and error messaging,
// as opposed to simply parsing a space-separated Seq[String], e.g. `DefaultParsers.spaceDelimited("<args>")`
val args = CloudFormationStackParsers.cloudFormationOptionParser.parsed
Def.taskDyn {
// recreate the input string and pass it as programmatic input to the upstream tasks
// unfortunately we can't extract `args.mkString(…)` without an Illegal Dynamic Reference error
val maybeAccountId: Option[String] = awsAccountId.toTask(args.mkString(" ", " ", "")).value
val maybeRoleName: Option[String] = awsRoleName.toTask(args.mkString(" ", " ", "")).value
// now that we have all the input values we have, actually define the task at hand
Def.task {
plugin.roleArn(maybeAccountId, maybeRoleName)
}
}
}.evaluatedIn the example, cloudformationOptions, awsAccountId, and awsRoleName are mainly there to make each piece of the parsed input available for inspection in the sbt console.
$ sbt
[info] Loading project definition from /Users/bholt/sbt-input-task-chaining/project
[info] Set current project to sbt-input-task-chaining (in build file:/Users/bholt/sbt-input-task-chaining/)
> show awsAccountId 123456789012 role/myRole Sandbox
[info] Some(123456789012)
[success] Total time: 0 s, completed Mar 12, 2017 3:10:18 PM
> show awsRoleName 123456789012 role/myRole Sandbox
[info] Some(myRole)
[success] Total time: 0 s, completed Mar 12, 2017 3:10:27 PM
> show environment 123456789012 role/myRole Sandbox
[info] Some(Sandbox)
[success] Total time: 0 s, completed Mar 12, 2017 3:10:33 PM
> show roleArn 123456789012 role/myRole Sandbox
[info] Some(arn:aws:iam::123456789012:role/myRole)
[success] Total time: 0 s, completed Mar 12, 2017 3:10:40 PM