I'm setting up a build.sbt
where I need to have a bunch of managed JARs on the classpath. I basically have two large folders containing all of the JARs and then also the source JARs.
myManagedRoot
|- deps
| |- alib.jar
| |- blib.jar
| `- clib.jar
`- sources
|- alib-sources.jar
|- blib-sources.jar
`- clib-sources.jar
In my build.sbt
, I've got something like
import sbt.nio.file._
lazy val MyProject= project
.settings(
Compile / unmanagedJars ++= FileTreeView.default
.list((file("myManagedRoot") / "deps").toGlob / "*.jar")
.collect {
case (path, attributes) if attributes.isRegularFile => path.toFile
}
)
However, I'm not sure where I can thread in the source JARs. I see in SBT that the fetching of those JARs occurs in updateClassifiers
, but I'm not sure what the best way is to hook into existing tasks for that.
I'm setting up a build.sbt
where I need to have a bunch of managed JARs on the classpath. I basically have two large folders containing all of the JARs and then also the source JARs.
myManagedRoot
|- deps
| |- alib.jar
| |- blib.jar
| `- clib.jar
`- sources
|- alib-sources.jar
|- blib-sources.jar
`- clib-sources.jar
In my build.sbt
, I've got something like
import sbt.nio.file._
lazy val MyProject= project
.settings(
Compile / unmanagedJars ++= FileTreeView.default
.list((file("myManagedRoot") / "deps").toGlob / "*.jar")
.collect {
case (path, attributes) if attributes.isRegularFile => path.toFile
}
)
However, I'm not sure where I can thread in the source JARs. I see in SBT that the fetching of those JARs occurs in updateClassifiers
, but I'm not sure what the best way is to hook into existing tasks for that.
2 Answers
Reset to default 2You could use:
Compile / unmanagedSourceDirectories += baseDirectory.value / "extra-sources"
But it may require to have the sources unzipped from the JARs (that maybe you can do as part of the build in another folder).
⚠️ And it's not really meant for this purpose as sources referenced by this setting will be compiled. They're extra source code, but not sources for the unmanaged dependencies in my understanding.
Reference: https://www.scala-sbt./1.x/docs/Howto-Customizing-Paths.html#Add+an+additional+source+directory
You can try a custom setting (i.e. calculated once on a project load, on contrary to a custom task calculated every time when executed) decompressing jars with sources
lazy val unjar = settingKey[Seq[File]]("unjar sources")
lazy val myProject = project
.settings(
unjar := {
(baseDirectory.value / ".." / "sources" ** "*.jar").get.map { file =>
val dir = baseDirectory.value / ".." / "sources-unjar" / file.name.stripSuffix(".jar")
IO.unzip(file, dir)
dir
}
},
Compile / unmanagedSourceDirectories ++= unjar.value,
Compile / unmanagedJars ++= (baseDirectory.value / ".." / "deps" ** "*.jar").get,
)
https://www.scala-sbt./1.x/docs/Custom-Settings.html
Make sure that all directories sources-unjar/alib-sources
, sources-unjar/blib-sources
, ... are marked as source roots in your IDE.
Update. You can rename your jars (adding version e.g. 1.0.0
) and re-arrange them into the following directory structure:
The .pom
files are:
<?xml version='1.0' encoding='UTF-8'?>
<project xsi:schemaLocation="http://maven.apache./POM/4.0.0 http://maven.apache./xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3./2001/XMLSchema-instance" xmlns="http://maven.apache./POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>alib</artifactId> <!-- alib, blib, clib, ... -->
<packaging>jar</packaging>
<version>1.0.0</version>
</project>
Then with the following build.sbt
your dependencies should be found (both classes and sources):
lazy val myProject = project
.settings(
resolvers += MavenCache("local-maven", baseDirectory.value / "deps"),
libraryDependencies ++= Seq(
"com.example" % "alib" % "1.0.0",
"com.example" % "blib" % "1.0.0",
"com.example" % "clib" % "1.0.0",
)
)
https://www.scala-sbt./1.x/docs/Resolvers.html#Local+Maven+resolvers
Upon necessity all renamings and re-arrangings can be done programmatically.
(The easiest would be if you had all projects alib
etc. locally. Then you could do sbt publishLocal
for them and use them as ordinary dependencies.)
unmanagedBase := baseDirectory.value / "deps"
instead of explicitly listing all the files. – Gaël J Commented Mar 24 at 19:09updateClassifiers
(here for Bloop and here for the SBT BSP impl) – Alec Commented Mar 24 at 19:22updateClassifiers
: scala-sbt./1.x/docs/Library-Management.html#Download+Sources – Gaël J Commented Mar 25 at 19:06