20
votes

When switching from one of the older versions of SBT to the latest version, we lost our ability to quickly grab all jar dependencies and copy them to a directory. Is there an easy way to do the same in XSBT 0.11.2?

5

5 Answers

39
votes

Adding the following to your build.sbt copies all the dependencies into a lib_managed folder in the root of your project.

retrieveManaged := true

Is that what you're asking for?

3
votes

We use a custom task definition similar to this to copy the jars. I have no idea whether this is the recommended way to do it — there's un ugly collect in there. Feel free to post improvements (or modify my answer in-line if you want).

copyJarsFolder <<= (crossTarget in (Compile, packageBin)).apply(_ / "jars")

copyJars <<= inputTask { (argTask: TaskKey[Seq[String]]) =>
  (copyJarsFolder, dependencyClasspath in Compile) map { (folder, cpEntries) =>
    ("mkdir -p " + folder).!
    //
    // find all dependencies
    val jars = cpEntries.collect {
      case attrFile if attrFile.metadata.keys.exists(_.label == "artifact") =>
        // probably an external jar
        attrFile.data
    }
    val copyCmd = jars.mkString("cp -p ", " ", " " + folder)
    copyCmd.!
    folder
  }
}
3
votes

See also this: How to declare a project dependency in SBT 0.10?

yes, you add

retrieveManaged := true

and you will see the jars in lib_managed folder

3
votes

Using sbt 0.13.7, IO.copy and friends.

  1. Define few setting somewhere in your build definition:

    val copyOutpath             = settingKey[File]("Where to copy all libs and built artifact")
    val copyAllLibsAndArtifact  = taskKey[Unit]("Copy runtime dependencies and built artifact to 'copyOutpath'")
    
  2. Define behaviour for these settings:

    lazy val myProject = project
      .in(file("."))
      .settings(
        copyOutpath              := baseDirectory.value / "specialFolderForMyProgram",
        copyAllLibsAndArtifact   := {
          val allLibs:                List[File]          = dependencyClasspath.in(Runtime).value.map(_.data).filter(_.isFile).toList
          val buildArtifact:          File                = packageBin.in(Runtime).value
          val jars:                   List[File]          = buildArtifact :: allLibs
          val `mappings src->dest`:   List[(File, File)]  = jars.map(f => (f, maxDynamicJarDir.value / f.getName))
          val log                                         = streams.value.log
          log.info(s"Copying to ${copyOutpath.value}:")
          log.info(s"  ${`mappings src->dest`.map(_._1).mkString("\n")}")
          IO.copy(`mappings src->dest`)
        },
        libraryDependencies       ++= Seq(
          //...
        )
      )
    
0
votes

Maybe my answer to this question helps you: Is there a way to get all dependencies of the project via sbt plugin? This is the easiest way I know of (I'm using sbt 0.11.2).