What is an SBT resolver? - scala

There are a lot of questions and guides about how to include SBT resolver to a project, but still there are no info about what is an SBT resolver and how can it help including dependencies to a project?

sbt resolver is the configuration for repository that contains jars and their dependencies
for example the below is a resolver definition for a repository called Sonatype and it points at snapshot releases (dev versions)
resolvers +=
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
When you specify a dependncy in sbt (or any other build system for that matter) the build system needs to know where to look to find that dependency. in JVM world a lot of dependencies are stored in the default maven2 repo ( https://repo1.maven.org/maven2/) but sometimes you need to use other custom repositories and you'd define add a resolver for that

Related

SBT plugins not using custom resolvers

I am trying to add sbt-native-packager plugin to my sbt build. For a number of reasons, I do not want my build to rely on default sbt repositories, I have blocked access to them on the network and added a resolver to my <project_home>/project/plugins.sbt in the following way:
resolvers += "local-repo-plugins" at "file:///" + baseDirectory.value + "/libs/repo/"
resolvers += Resolver.url("my-ivy-proxy-plugins", url("http://fullURLForRepo/"))(Patterns("[organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]") )
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.4")
I can confirm the plugin it is hosted in my ivy proxy, but that is not even the issue, because sbt is still trying to go to default repos:
[info] Resolving com.typesafe.sbt#sbt-native-packager;0.7.4 ...
[error] Server access Error: Connection timed out url=https://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.10/sbt_0.13/0.7.4/ivys/ivy.xml
[error] Server access Error: Connection timed out url=https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.10/sbt_0.13/0.7.4/ivys/ivy.xml
[error] Server access Error: Connection timed out url=https://repo1.maven.org/maven2/com/typesafe/sbt/sbt-native-packager_2.10_0.13/0.7.4/sbt-native-packager-0.7.4.pom
Also, this very same custom resolver works just fine (together with a couple of other ones, including one based on local filesystem) on my <project_home>/build.sbt when resolving library dependencies.
While I understand why the resolvers used in my project build are not the same used in my <project_home>/project/plugins.sbt, I have several questions regarding the issue I just described:
Is this the right way to define resolvers for plugins? just adding them to the <project_home>/project/plugins.sbt with that syntax?
If the answer to question 1) is yes: is there any way to avoid redundancy when defining these resolvers? e.g. I have defined exactly the very same ones in <project_home>/build.sbt
And the most important: why is the sbt build not using my ivy proxy, as specified in the resolver, to retrieve the sbt-native-packager plugin?
Yes this is a correct way to define your resolvers for plugins
This is actually quite tricky : you are trying to share settings between the plugins build and the build. These are "separate" projects from sbt's perspective. There are solutions using a project ref to gain access to the plugins build settings from the build but they are quite tricky. If this is a corporate environment where you will never have access to the default repositories anyways, it might be easier to use a custom sbt.boot.properties. You can start from the default file for 0.13.x
Changing the sbt.boot.properties should deliver you from the Server access errors.
There is nothing in the logs you provide which indicates that the plugin failed to be resolved from your proxy, only that it timedout trying to reach the official repositories. With the default sbt.boot.properties, sbt will try to resolve artefacts in the order the resolvers are defined :
local
typesafe-ivy-releases: https://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
maven-central
sonatype-snapshots: https://oss.sonatype.org/content/repositories/snapshots
Then any resolver found in any .sbt files in the <project_home>/project/directory. As far as I am aware, sbt files are evaluated in the alphabetical order and resolvers are added in the order they appear in each file.
It seems the documents are not updated yet which ask you to put resolvers in plugins.sbt. Moving resolvers ++= Seq("Artima Maven Repository" at "http://repo.artima.com/releases") to build.sbt fixes the issue.
I think that you guys got it all wrong, it should be like this:
my_project/project/plugins.sbt should have:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.4")
and my_project/project/project/build.sbt should have:
resolvers += ...
They are 2 different build definitions ...

Maven and Ivy dependency management

I have a project (project1) that is built using Maven. There is another project (project2) which uses SBT and is a Scala code base. The jar built by project1 is added as a dependency to project2. Since project2 is using ivy as its repository, how should I handle this in my Build file of project2?
Currently what I do is the following in my Build.scala of project2:
resolvers ++= Seq(
"Local Maven Repository" at "file:///"+Path.userHome+"/Softwares/maven-repo"
),
This way of adding this dependency is a bit problematic as the path to the local maven repo might differ from each developer. Is there a proper way to refer to maven dependencies from within my Scala project?
As a default, I expect that all my developers are following convention and configure SBT with:
resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"
If you have developers that are not following convention for whatever reason, maybe they are forced to use a network drive or something, then they need to do some local configuration and not check their changes in (a cultural thing).
You could also look up an environment variable but then you still burden your devs with setting that up.

Resolving an online SBT dependency with "." characters in path

In my project I want to use the sbinary library to (de)serialize some case classes to a binary form. I also want to use the latest Scala in the project. Typesafe offers a version of sbinary in their repositories, and they seem to be the only one who are doing so.
So I add the repository and dependency to my build.sbt like so:
scalaVersion := "2.11.2"
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "org.scala-tools.sbinary" %% "sbinary" % "0.4.2"
Surprisingly, this fails. With a dependency defined like this, SBT tries to find the dependency at the url http://repo.typesafe.com/typesafe/releases/org/scala-tools/sbinary/sbinary_2.11.0 whereas it is really located at http://repo.typesafe.com/typesafe/releases/org.scala-tools.sbinary/sbinary_2.11.0. Because SBT replaces the dots in the dependency group id with slashes, it is not able to find the dependency in the place it's in.
I've tried some tricks for building the string in other ways, but they are all useless since SBT replaces the .s by /s in the string after it is evaluated. How can I get SBT to find the dependency at this URL?
Please note that I'm aware that I could simply make this an offline dependency, but I'd prefer to have this build script work out of the box on any computer with SBT installed.
http://repo.typesafe.com/typesafe/releases/org.scala-tools.sbinary/sbinary_2.11.0 is in ivy style. The default style of sbt is maven2 so your resolver doesn't work.
try
resolvers += Resolver.url("Typesafe Repository (ivy)", url("http://repo.typesafe.com/typesafe/releases/"))(Resolver.ivyStylePatterns)
Source: https://groups.google.com/forum/#!topic/simple-build-tool/TY1AoYYvB4k

Is finagle 5.0 published in a Maven repository which I can add to my sbt.build (sbt11)?

I'm trying to use finagle in a Scala project and I'm wondering if there's a Maven repository out there which has the jars. I want to add it as a dependency and rather not compile all the stuff locally.
Here is an example build.sbt file for one of my projects which uses Finagle 5.0.0:
https://github.com/cb372/finagle-beanstalk/blob/d2ac139999fd49a6dc4fcd6e1097b07da234b408/build.sbt
Basically you need:
resolvers += "Twitter Maven repo" at "http://maven.twttr.com/"
libraryDependencies += "com.twitter" % "finagle-core" % "5.0.0"
When I checked a few days ago, the latest version of finagle-core available in the Maven repo was 5.3.1, so you should probably use that.
from http://twitter.github.com/finagle/
Note: Maven Artifacts are published to the public twitter maven repo
at http://maven.twttr.com.

How do I force SBT plugins and plugins to be downloaded through Nexus?

I think that by now I figured out how to force project dependencies to be downloaded through Nexus. (I did that by explicitly setting externalResolvers to a Seq with only one value:
override lazy val settings = super.settings ++ Seq(
externalResolvers := Seq("Nexus repository" at "http://.../nexus/content/groups/public/")
)
However, if I drop my Ivy cache, SBT still accesses a number of public repositories for getting the plugins. Ideally I would like that to go through Nexus as well, to make sure we are not dependent on those repositories to exist forever. (Which they don't.)
Any clues? (I'm on SBT 0.11.2)
sbt 0.12 added Global repository setting for this purpose.
Define the repositories to use by putting a standalone [repositories] section (see the Launcher Specification page) in ~/.sbt/repositories and pass -Dsbt.override.build.repos=true to sbt. Only the repositories in that file will be used by the launcher for retrieving sbt and Scala and by sbt when retrieving project dependencies.