user3792978
user3792978

Reputation: 91

SBT resolution fails with Ivy extra attributes

I'm trying to use Ivy extra attributes with SBT. I have two modules: foo-model and foo-api. For both of them I added this to build.sbt:

projectID <<= projectID { id =>
   id extra("branch" -> "master-api-model-separation")
}

Foo-model is being published to Artifactory (with sbt publish). The published POM file looks like this:

<?xml version='1.0' encoding='UTF-8'?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.foo</groupId>
    <artifactId>foo-model</artifactId>
    <packaging>jar</packaging>
    <description>foo-model</description>
    <version>1.0</version>
    <name>foo-model</name>
    <organization>
        <name>com.foo</name>
    </organization>
    <properties>
        <branch>master-api-model-separation</branch>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.10.3</version>
        </dependency>
        ...

Then I need foo-api to use foo-model, so I've added this to its build.sbt:

def appDependencies = Seq(
    "com.foo"%"foo-model"%"1.0" extra( "branch" -> "master-api-model-separation" ) changing(),
    ...

However, when I try to run SBT (either update or package), I get this:

[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: com.foo#foo-model;1.0: java.text.ParseException: inconsistent module descriptor file found in 'http://xdctest-app-01:8081/artifactory/foo-master/com/foo/foo-model/1.0/foo-model-1.0.pom': bad branch found in http://xdctest-app-01:808/artifactory/foo-master/com/foo/foo-model/1.0/foo-model-1.0.pom: expected='master-api-model-separation' found='null';
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn] 
[warn]  Note: Some unresolved dependencies have extra attributes.  Check that these dependencies exist with the requested attributes.
[warn]          com.foo:foo-model:1.0 (branch=master-api-model-separation)
[warn] 

And there's an exception and an error. I tried with SBT 0.13.0 and 0.13.1.

I didn't manage to get more useful debug output. I only get this from the last command:

[debug]                 tried http://xdctest-app-01:8081/artifactory/foo-master/com/foo/foo-model/1.0/foo-model-1.0.jar
[debug] com.foo#foo-model;1.0 is changing, but has not changed: will trust cached artifacts if any
[debug] Deleting additional old artifacts from cache for changed module com.foo#foo-model;1.0:
[debug]         
[error]         foo-master: bad branch found in http://xdctest-app-01:8081/artifactory/foo-master/com/foo/foo-model/1.0/foo-model-1.0.pom: expected='master-api-model-separation' found='null'
[debug] problem occurred while resolving dependency: com.foo#foo-model;1.0 {compile=[default(compile)]} with foo-master: java.text.ParseException: inconsistent module descriptor file found in 'http://xdctest-app-01:8081/artifactory/foo-master/com/foo/foo-model/1.0/foo-model-1.0.pom': bad branch found in http://xdctest-app-01:8081/artifactory/foo-master/com/foo/foo-model/1.0/foo-model-1.0.pom: expected='master-api-model-separation' found='null';
[debug]         at org.apache.ivy.plugins.resolver.BasicResolver.checkDescriptorConsistency(BasicResolver.java:640)
[debug]         at org.apache.ivy.plugins.resolver.BasicResolver.getDependency(BasicResolver.java:284)
[debug]         at org.apache.ivy.plugins.resolver.IBiblioResolver.getDependency(IBiblioResolver.java:503)
[debug]         at sbt.ConvertResolver$PluginCapableResolver$1.sbt$ConvertResolver$DescriptorRequired$$super$getDependency(ConvertResolver.scala:28)
...

The POM file at the above URL really exists and its contents is quoted above, ie. it has the branch property with the value master-api-model-separation.

What am I doing wrong?

Upvotes: 9

Views: 1010

Answers (1)

Eugene Yokota
Eugene Yokota

Reputation: 95624

The Ivy extra attribute might require an Ivy repository to get it work, which should work if you are using Artifactory. sbt does internally use extra attributes to encode Scala version on Maven repository, but I don't know if that bits are exposed.

Here's what I used as a test.

build.sbt

lazy val root = (project in file(".")).
  settings(
    bintrayReleaseOnPublish in ThisBuild := false
  )

val customPattern = "[organisation]/[module]/" +
  "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)(branch_[branch_name]/)" +
  "[revision]/[type]s/[artifact](-[classifier]).[ext]"

lazy val libExtra = (project in file("libExtra")).
  settings(
    version := "0.1",
    scalaVersion := "2.11.7",
    organization := "com.example",
    name := "somelibrary",
    projectID := {
      val previous = projectID.value
      previous.extra("branch_name" -> "master-api-model-separation")
    },
    licenses += ("MIT", url("http://opensource.org/licenses/MIT")),
    bintrayVcsUrl := Some("[email protected]:you/your-repo.git"),
    bintrayOrganization := None,
    bintrayRepository := "test-test-test",
    publishMavenStyle := false,
    checksums in publish := Nil,
    publishTo := {
      Some(URLRepository("test-bintray-ivy", Patterns(
        s"https://api.bintray.com/content/you/${bintrayRepository.value}/" +
        customPattern +
        s";bt_package={normalizedName.value};bt_version={version.value}")))
    }
  )

lazy val app = (project in file("app")).
  settings(
    scalaVersion := "2.11.7",
    organization := "foo",
    libraryDependencies += "com.example" %% "somelibrary" % "0.1" extra("branch_name" -> "master-api-model-separation"),
    resolvers += Resolver.url("test-bintray-ivy", url("https://dl.bintray.com/you/test-test-test/"))(Patterns(
      customPattern)),
    fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project")
  )

project/build.properties

sbt.version=0.13.8

project/bintray.sbt

addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0")

libExtra/src/main/scala/Something

object Something

The half of the settings are basically setup to publish into a dummy Bintray repository for testing. Here are some of the notes:

  • The name branch is already taken, so I don't think you can use it. I'm sugin branch_name.
  • publishTo includes a custom artifact pattern that includes your extra attribute embedded in the URL.

Using app I was able to resolve the JAR from Bintray:

app> compile
[info] Updating {file:/Users/xxx/extra-attribute-test/}app...
[info] Resolving jline#jline;2.12.1 ...
[info] downloading https://dl.bintray.com/eed3si9n/test-test-test/com/example/somelibrary_2.11/branch_master-api-model-separation/0.1/jars/somelibrary_2.11.jar ...

Future improvements: Here's my attempt at trying to do this using a Maven repo - https://gist.github.com/eed3si9n/a6de413b1ced84649ae0

Upvotes: 4

Related Questions