最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

scala - Add sources for unmanaged JARs in SBT - Stack Overflow

programmeradmin4浏览0评论

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.

Share Improve this question asked Mar 24 at 18:49 AlecAlec 32.4k7 gold badges73 silver badges119 bronze badges 5
  • FYI I think you could just use unmanagedBase := baseDirectory.value / "deps" instead of explicitly listing all the files. – Gaël J Commented Mar 24 at 19:09
  • Regarding the sources, I'm not sure SBT is even responsible to do so. What's your goal? Attach the sources in your IDE for debugging? – Gaël J Commented Mar 24 at 19:10
  • @GaëlJ yeah, I want to provide the sources in the IDE (eg. goto-definition). I'm using Metals, but tracing through both the integration through Bloop and SBT directly, things come back to updateClassifiers (here for Bloop and here for the SBT BSP impl) – Alec Commented Mar 24 at 19:22
  • Reference to SBT doc about updateClassifiers: scala-sbt./1.x/docs/Library-Management.html#Download+Sources – Gaël J Commented Mar 25 at 19:06
  • 1 @Alec See update of my answer with a local maven repository solution. – Dmytro Mitin Commented Mar 26 at 1:40
Add a comment  | 

2 Answers 2

Reset to default 2

You 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.)

发布评论

评论列表(0)

  1. 暂无评论