How to make sbt publishLocal task compatible with IvyDE?

124 views Asked by At

I'm using the IvyDE Eclipse plugin to resolve my project's (let's call it A) dependencies. One of those dependencies is another project (call it B) which I build using sbt. The final part of the build is to invoke sbt's publishLocal task to publish the B project's artefacts to the local Ivy repository.

It all works fine up to this point. However, when I then try to resolve the project A dependencies, IvyDE generates an error message saying that it failed to resolve the "doc" and "src" jars. I can force it to work in the end because it doesn't fail to resolve the main jar containing the actual code. Still, I find it somewhat annoying.

After spending a considerable amount of time looking for a solution, I have come up with the following sbt code to change my project B configuration:

import sbt.Build
import sbt.Project
import java.io.File
import sbt.PathExtra
import sbt.SettingKey
import sbt.Artifact
import sbt.Keys.{ artifact, artifactName, artifactPath, packageSrc, packageDoc, crossTarget, projectID, scalaVersion, scalaBinaryVersion, moduleName }
import sbt.ScalaVersion
import sbt.Configurations.{ Compile }
import sbt.Configurations

/**
 * The objective here is to make the artefacts published to the local repository by the publishLocal task
 * compatible with the local resolver used by IvyDE.
 * This is achieved by dropping the classifiers from the "doc" and "source" artefacts, and by adding
 * an extra level directory to their paths to avoid clashing with the "jar" main artefact.
 */
object SbtIvyFix extends Build with PathExtra {
  lazy override val projects = Seq(root)
  lazy val root: Project = Project("xlstocsv", new File(".")) settings (
    artifact in (Compile, packageSrc) := {
      (artifact in (Compile, packageSrc)).value.copy(classifier = None)
    },
    artifact in (Compile, packageDoc) := {
      (artifact in (Compile, packageDoc)).value.copy(classifier = None)
    },
    artifactPath in (Compile, packageSrc) <<= myArtifactPathSetting(artifact in (Compile, packageSrc)),
    artifactPath in (Compile, packageDoc) <<= myArtifactPathSetting(artifact in (Compile, packageDoc)))

  // Lifted from the Sbt source artifactPathSetting() function in Defaults.scala
  def myArtifactPathSetting(art: SettingKey[Artifact]) = (crossTarget, projectID, art, scalaVersion in artifactName, scalaBinaryVersion in artifactName, artifactName) {
    (t, module, a, sv, sbv, toString) =>
      {
        t / a.`type` / toString(ScalaVersion(sv, sbv), module, a)
      }
  }
}


This works quite well but feels somewhat over the top. Can someone suggest a simpler way of achieving the same result?

0

There are 0 answers