(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 InputTask
s 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)
}
}
}.evaluated
In 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