Can I use sbt's `apiMappings` setting for managed dependencies?

前端 未结 3 530
死守一世寂寞
死守一世寂寞 2020-12-05 16:25

I\'d like the ScalaDoc I generate with sbt to link to external libraries, and in sbt 0.13 we have autoAPIMappings which is supposed to add these links for libra

相关标签:
3条回答
  • 2020-12-05 17:00

    The accepted answer is good, but it'll fail when assumptions about exact project dependencies don't hold. Here's a variation that might prove useful:

    apiMappings ++= {
      def mappingsFor(organization: String, names: List[String], location: String, revision: (String) => String = identity): Seq[(File, URL)] =
        for {
          entry: Attributed[File] <- (fullClasspath in Compile).value
          module: ModuleID <- entry.get(moduleID.key)
          if module.organization == organization
          if names.exists(module.name.startsWith)
        } yield entry.data -> url(location.format(revision(module.revision)))
    
      val mappings: Seq[(File, URL)] =
        mappingsFor("org.scala-lang", List("scala-library"), "http://scala-lang.org/api/%s/") ++
          mappingsFor("com.typesafe.akka", List("akka-actor"), "http://doc.akka.io/api/akka/%s/") ++
          mappingsFor("com.typesafe.play", List("play-iteratees", "play-json"), "http://playframework.com/documentation/%s/api/scala/index.html", _.replaceAll("[\\d]$", "x"))
    
      mappings.toMap
    }
    

    (Including scala-library here is redundant, but useful for illustration purposes.)

    If you perform mappings foreach println, you'll get output like (note that I don't have Akka in my dependencies):

    (/Users/michaelahlers/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.7.jar,http://scala-lang.org/api/2.11.7/)
    (/Users/michaelahlers/.ivy2/cache/com.typesafe.play/play-iteratees_2.11/jars/play-iteratees_2.11-2.4.6.jar,http://playframework.com/documentation/2.4.x/api/scala/)
    (/Users/michaelahlers/.ivy2/cache/com.typesafe.play/play-json_2.11/jars/play-json_2.11-2.4.6.jar,http://playframework.com/documentation/2.4.x/api/scala/)
    

    This approach:

    1. Allows for none or many matches to the module identifier.
    2. Concisely supports multiple modules to link the same documentation.
      • Or, with Nil provided to names, all modules for an organization.
    3. Defers to the module as the version authority.
      • But lets you map over versions as needed.
        • As in the case with Play's libraries, where x is used for the patch number.

    Those improvements allow you to create a separate SBT file (call it scaladocMappings.sbt) that can be maintained in a single location and easily copy and pasted into any project.

    0 讨论(0)
  • 2020-12-05 17:17

    I managed to get this working for referencing scalaz and play by doing the following:

    apiMappings ++= {
      val cp: Seq[Attributed[File]] = (fullClasspath in Compile).value
      def findManagedDependency(organization: String, name: String): File = {
        ( for {
            entry <- cp
            module <- entry.get(moduleID.key)
            if module.organization == organization
            if module.name.startsWith(name)
            jarFile = entry.data
          } yield jarFile
        ).head
      }
      Map(
          findManagedDependency("org.scalaz",        "scalaz-core") -> url("https://scalazproject.ci.cloudbees.com/job/nightly_2.10/ws/target/scala-2.10/unidoc/")
        , findManagedDependency("com.typesafe.play", "play-json")   -> url("http://www.playframework.com/documentation/2.2.1/api/scala/")
      )
    }
    

    YMMV of course.

    0 讨论(0)
  • 2020-12-05 17:22

    Alternatively to my last suggestion, the sbt-api-mappings plugin by ThoughtWorks shows a lot of promise. Long term, that's a far more sustainable route than each project maintaining its own set of mappings.

    0 讨论(0)
提交回复
热议问题