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?
Extra attributes can be specified by passing key/value pairs to the extra method. To select dependencies by extra attributes: To define extra attributes on the current project: sbt additionally supports directly specifying the configurations or dependencies sections of an Ivy configuration file inline.
Override default resolvers resolvers configures additional, inline user resolvers. By default, sbt combines these resolvers with default repositories (Maven Central and the local Ivy repository) to form externalResolvers. To have more control over repositories, set externalResolvers directly.
sbt additionally supports directly specifying the configurations or dependencies sections of an Ivy configuration file inline. You can mix this with inline Scala dependency and repository declarations. By default, sbt uses the standard Ivy home directory location $ {user.home}/.ivy2/.
See Resolvers for details on defining other types of repositories. resolvers configures additional, inline user resolvers. By default, sbt combines these resolvers with default repositories (Maven Central and the local Ivy repository) to form externalResolvers. To have more control over repositories, set externalResolvers directly.
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.
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")
)
sbt.version=0.13.8
addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0")
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:
branch
is already taken, so I don't think you can use it. I'm sugin branch_name
.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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With