2

I have an SBT task that I want available across multiple "parallel" configuration scopes, where the dependencies have scope specifiers automatically applied based on the scope the task is invoked in.

I have something that works--whereby a separate task is instantiated per configuration scope--but it feels clumsy and want to know if there's a better way with less boilerplate.

In my specific use case I'm using sbt-native-packager and defining package preparation tasks with OS-specific settings. Specifically, I'd like to be able to define unpack without specifying the config scope, and then invoke windows:unpack and have the config scope selector appropriately applied to the declared dependencies.

...
// Task and setting definitions
lazy val unpackSrc = settingKey[File]("Name of file we wish to unpack.")
lazy val unpackDstName = settingKey[File]("Unpacking destination.")
lazy val unpack = taskKey[Set[File]]("Unpack `unpackSrc` to `unpackDst`")
...

// OS specific settings via config scopes
unpackSrc in Windows := target.value / "foo-bar-windows.zip"
unpackSrc in Linux := target.value / "foo-bar-linux.zip"

unpackDst in Windows := target.value / "extract" / "windows"
unpackDst in Linux := target.value / "extract" / "linux"

// Task definition.
// This is what I wish I could do, but can't since it assumes global scope:
// unpack <<= (unpackSrc, unpackDst) map { (src, dst) ⇒
//   IO.unzip(src, dst) 
// }

// Workaround is to create a task generating function...
def unpackTask(conf: Configuration) = Def.task {
    val src = (unpackSrc in conf).value
    val dst = (unpackDst in conf).value
    val s = streams.value
    IO.unzip(src, dst)
}

// ... and invoke per configuration. 
// This seems clumsy to me, but can't figure out a better way.
unpack in Windows <<= unpackTask(Windows)
unpack in Linux <<= unpackTask(Linux)

Is there some way have defining a task and it's dependencies, and having it work across scopes with proper scope selection?

metasim
  • 4,793
  • 3
  • 46
  • 70
  • 1
    This is currently the way we do it in sbt-native-packager as well :( I'm not aware of another way to achieve this. https://github.com/sbt/sbt-native-packager/blob/master/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala#L70-L79 – Muki Feb 13 '15 at 18:05
  • 1
    Could this answer fit? https://stackoverflow.com/a/30925566/1531945 – Konstantin Pelepelin Dec 25 '17 at 19:06
  • @KonstantinPelepelin I do believe it does! Looks like a feature added sometime after I created the question. Would you care to construct a full answer for it? – metasim Dec 29 '17 at 02:02

0 Answers0