When I run makePom in sbt I get:
[warn] Skipped generating '<exclusion/>' for org.scalaz#*. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema.
[warn] Skipped generating '<exclusion/>' for com.jolbox#*. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema.
What's the easiest way to fix this problem so that the correct exclusions get generated?
The following does not work - it breaks the scalaz exclusion rule - I presume because scalaz 7 is composed of multiple jars:
ExclusionRule(organization = "org.scalaz", name="scalaz-core")
and
ExclusionRule(organization = "com.jolbox", name="bonecp")
It's not the multiple jars that's the problem for the scalaz exclusion rule - it's that there is no %% in an ExclusionRule, so I needed to explicitly add the Scala version for any dependencies which have them in their module name, like so:
ExclusionRule(organization = "org.scalaz", name="scalaz-core_2.10")
Related
I created a reproducible example about a problem I'm experiencing with SBT plugin resolution:
https://github.com/NicolasRouquette/sbt.problem.example
This example has two SBT projects:
test.plugin a simple SBT plugin
test.app a simple SBT project that uses the test.plugin
There is also a local Maven repository to which the test.plugin is published with a POM file that includes properties like this:
<properties>
<git.branch>master</git.branch>
<git.commit>fe2dc11d6fbb85c5ce0e83b031bbd425997bbd59</git.commit>
<git.tags></git.tags>
</properties>
<properties>
<scalaVersion>2.10</scalaVersion>
<sbtVersion>0.13</sbtVersion>
<extraDependencyAttributes xml:space="preserve">+e:sbtVersion:###:+0.13:###:+module:###:+sbt-license plugin:###:+e:scalaVersion:###:+2.10:###:+organisation:###:+com.banno:###:+branch:###:+##:NULL:##:###:+revision:###:+0.1.5:###:
+e:sbtVersion:###:+0.13:###:+module:###:+sbt-license-report:###:+e:scalaVersion:###:+2.10:###:+organisation:###:+com.typesafe.sbt:###:+branch:###:+##:NULL:##:###:+revision:###:+1.0.0:###:
+e:sbtVersion:###:+0.13:###:+module:###:+sbt-git:###:+e:scalaVersion:###:+2.10:###:+organisation:###:+com.typesafe.sbt:###:+branch:###:+##:NULL:##:###:+revision:###:+0.8.5:###:
+e:sbtVersion:###:+0.13:###:+module:###:+aether-deploy:###:+e:scalaVersion:###:+2.10:###:+organisation:###:+no.arktekk.sbt:###:+branch:###:+##:NULL:##:###:+revision:###:+0.16:###:
</extraDependencyAttributes>
</properties>
I can't run SBT on test.app because SBT fails to resolve the test.plugin:
addSbtPlugin("org.test" % "test-plugin" % "1.0")
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.test#test-plugin;1.0: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.
[warn] org.test:test-plugin:1.0 (sbtVersion=0.13, scalaVersion=2.10)
[warn]
[warn] Note: Unresolved dependencies path:
[warn] org.test:test-plugin:1.0 (sbtVersion=0.13, scalaVersion=2.10) (/opt/local/imce/users/nfr/github.imce/example/test.app/project/plugins.sbt#L6-7)
[warn] +- default:test-app-build:0.1-SNAPSHOT (sbtVersion=0.13, scalaVersion=2.10)
sbt.ResolveException: unresolved dependency: org.test#test-plugin;1.0: not found
at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:294)
at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:191)
at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:168)
at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:155)
at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:155)
at sbt.IvySbt$$anonfun$withIvy$1.apply(Ivy.scala:132)
at sbt.IvySbt.sbt$IvySbt$$action$1(Ivy.scala:57)
...
Based on trying to understand what's going on with the debugger, I get the impression that:
resolving plugins happens very early when running SBT; which means that it involves a lot of SBT/Ivy machinery
I don't quite understand how the SBT/Ivy machinery resolves SBT plugins published to a Maven repository (though I've seen some kind of Maven/Ivy conversion somewhere)
it seems that the Maven POM properties are not analyzed to retrieve the sbtVersion (e.g. 0.13) and scalaBinaryVersion (e.g. 2.10) of an artifact
Can someone confirm/correct my analysis?
Is there a way to make this maven-published plugin dependency lookup work?
Thanks for the repro project.
First issue is that you have two <properties> element. sbt will use both the URL layout and the content of the POM to resolve the plugin. Here's how to merge <properties> element. Not sure if there's more elegant way:
makePom := {
val old = makePom.value
val pom = xml.XML.loadFile(old)
val additionalProperties =
(<git.branch>{git.gitCurrentBranch.value}</git.branch>
<git.commit>{git.gitHeadCommit.value.getOrElse("N/A")+(if (git.gitUncommittedChanges.value) "-SNAPSHOT" else "")}</git.commit>
<git.tags>{git.gitCurrentTags.value}</git.tags>)
val newPom = pom.copy(child = pom.child.toSeq map {
case elem: xml.Elem if elem.label == "properties" =>
elem.copy(child = elem.child ++ additionalProperties)
case x => x
})
xml.XML.save(old.toString, newPom, enc = "UTF-8", xmlDecl = true)
old
}
Next, you should've seen something like this when you tried to resolve the plugin:
[warn] ==== Local Test: tried
[warn] file:/xxx/sbt.problem.example/test.app/project/../local.repo/org/test/test-plugin_2.10_0.13/1.0/test-plugin-1.0.pom
See that test.app/project/../local.repo/ would become test.app/local.repo. Instead of ".." here's what you can do in test.app/project/plugins.sbt:
resolvers += new MavenCache("Local Test", baseDirectory.value.getParentFile.getParentFile / "local.repo")
addSbtPlugin("org.test" % "test-plugin" % "1.0")
In my SBT build I have a dependency on an ivy artifact that makes use of a custom module status. This causes the following error in SBT:
[error] (*:update) sbt.ResolveException: unresolved dependency: my-org#myapp-core_2.11;1.0: java.text.ParseException: inconsistent module descriptor file found in 'http://artifacts.myorg.com/libs-snapshots-local/myapp-core_2.11/1.0/myapp-ivy.xml': bad status: 'snapshot';
I can work around this by telling SBT to use an external ivy settings, like so:
externalIvySettings(baseDirectory(_ / "ivySettings.xml"))
And then create an ivySettings.xml containing the following:
<statuses default="release">
<status name="release" integration="false"/>
<status name="snapshot" integration="false"/>
</statuses>
But surely there must be a better way? The problem with this work around is that now all my settings (such as resolvers) have to be in the ivy file too, because (IFAIK) it's all or nothing when you use externalIvySettings.
Is there a way to specify a set of custom statuses within my build.sbt? Or alternatively is there a way to tell sbt to combine external ivy settings with the ones it generates from the build.sbt.
Since specifying custom module statuses is a valid thing to do in ivy, this should really be supported in sbt too.
This is because for some repositories, they use non-standard status which fails the consistency check. We addressed this by constructing the customized resolver which doesn't do consistency check. You can also construct resolver with the custom status using the same approach. The following is the working snippet.
resolvers += {
val resolver = new org.apache.ivy.plugins.resolver.IBiblioResolver
resolver.setName("Custom Ivy Snapshots")
resolver.setRoot("http://Custom/snapshots/")
val settings = new org.apache.ivy.core.settings.IvySettings()
settings.setVariable("ivy.local.default.ivy.pattern", Pattern)
settings.setVariable("ivy.local.default.artifact.pattern", Pattern)
resolver.setSettings(settings)
resolver.setM2compatible(true)
resolver.setCheckconsistency(false)
new RawRepository(resolver)
}
I am converting our mixed build environment into an sbt based ecosystem. And I am at a bit of a road block with this issue.
I have deployed a library to a remote repository via sftp but when I try to load it as a dependency I have an issue.
In build.sbt I have:
resolvers += {
val privateKeyFile = new java.io.File(sys.env("HOME") + "/.ssh/id_rsa")
Resolver.sftp("MY REPO", "aHost", "/repoBase/") as ("aUser", privateKeyFile)
}
update in interactive shows:
[info] Resolving com.test.it.out#myLib_2.11;1.0 ...
[warn] module not found: com.test.it.out#myLib_2.11;1.0
[warn] ==== local: tried
[warn] /home/bday/.ivy2/local/com.test.it.out#myLib_2.11/1.0/ivys/ivy.xml
[warn] ==== public: tried
[warn] https://repo1.maven.org/maven2/com.test.it.out#myLib_2.11/1.0/jsshfs_2.11-1.0.pom
[warn] ==== MY REPO: tried
[info] Resolving jline#jline;2.12 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
It never lists any path information for MY REPO.
I have tried multiple ways to configure the resolver, even users/hosts that should fail and the results don't change.
show resolvers
[info] List(SftpRepository(MY REPO,SshConnection(Some(KeyFileAuthentication(aUser,/home/aUser/.ssh/id_rsa,None)),Some(aHost),None),Patterns(ivyPatterns=List(), artifactPatterns=List(/repoBase/[organisation]/module(_[sbtVersion])/[revision]/[artifact]-revision.[ext]), isMavenCompatible=true, descriptorOptional=false, skipConsistencyCheck=false)))
I did see someone had the same issue and said switching from SSH to SFTP fixed it, in 12.?. I am using 13.7
I have come to the end of the internet on this one, please extends it a bit.
Thanks!
I had the similar issue, it was not listing any urls that it tried. I added the same Pattern that I was using while publishing, and it fixed the problem. Also, I have put my resolver as the first one in the order.
resolvers in ThisBuild := (Resolver.sftp("MY Repo", "example.com", 22, "sbt-repos/releases")(Patterns("[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[type]s/[artifact](-[classifier]).[ext]"))) +: resolvers.value
I am using 0.13.9. I searched a lot for this one and finally figured it out after so many trials. Hope this will help somebody.
val sftpRes = {
val privateKeyFile = new java.io.File(sys.env("HOME") + "/.ssh/id_rsa")
Resolver.sftp("REPO", "gitHost", "/path/to/data/")(Resolver.ivyStylePatterns) as ("user", privateKeyFile)
}
publishMavenStyle := false
publishTo := Some(sftpRes)
Using SBT 1.2.4
In the end this is what I got to work. I tried Resolver.mavenStylePatterns, but in that case as with others SBT never really tries to find files on the resolver.
Using Ivy patterns on the publish and resolve worked for me.
I'm trying to use jooq-sbt-plugin to generate some code.
I downloaded the code, compiled it and copied jar into lib directory, but on sbt load i get this error:
[warn] Note: Some unresolved dependencies have extra attributes. Check that th
ese dependencies exist with the requested attributes.
[warn] sean8223:jooq-sbt-plugin:1.4 (sbtVersion=0.13, scalaVersion=2.10
)
in project/plugins.sbt i have this
resolvers += Resolver.file("lib-repo", file("lib")) transactional()
addSbtPlugin("lib-repo" %% "jooq-sbt-plugin" % "1.4")
Is this plugin "detected" and cannot be loaded or sbt does't see it?
P.S.
By default plugin does not work because it depends on jooq-3.2.1 which is not available on maven and I get error - unresolved dependencies. According to plugin readme i could set jooqVersion in build.sbt to other version, but this doesn't seem to work.
In my project/plugins.sbt:
resolvers += "sean8223 Releases" at "https://github.com/sean8223/repository/raw/master/releases"
addSbtPlugin("sean8223" %% "jooq-sbt-plugin" % "1.3")
In my build.sbt:
seq(jooqSettings:_*)
jooqVersion := "3.3.1"
And everything is successfully resolved. I didn't run any tasks, but since you say that the problem is in resolving jooq, show your build.sbt if it still doesn't work for you.
I am getting deprecation and feature warnings when compiling my SBT project definition (i.e. the files inside the project directory). SBT version is 0.13.0.
I do not get more info on these by setting scalacOptions := Seq("-feature", "-deprecation"), this only seems to work for project source files and not project definition files.
Anyone know how I can set deprecation and warning for the compiler when it compiles the project definition?
[info] Loading project definition from /home/xxx/website/project
[warn] there were 2 deprecation warning(s); re-run with -deprecation for details
[warn] there were 4 feature warning(s); re-run with -feature for details
[warn] two warnings found
Create project/build.sbt project definition file with the following content:
scalacOptions := Seq("-feature", "-deprecation")
Since any *.sbt file under project belongs to the meta (build) project, it sets up the Scala compiler for the build configuration not the environment for the project under build.
It was tested with a sample sbt multi-project:
[info] Compiling 1 Scala source to /Users/jacek/sandbox/so/multi-0.13.1/project/target/scala-2.10/sbt-0.13/classes...
[warn] /Users/jacek/sandbox/so/multi-0.13.1/project/Build.scala:4: method error in object Predef is deprecated: Use `sys.error(message)` instead
[warn] lazy val e = error("Launcher did not provide the Ivy home directory.")
[warn] ^
[warn] one warning found
...when it compiled the following project/Build.scala:
import sbt._
object Build extends Build {
lazy val e = error("Launcher did not provide the Ivy home directory.")
}