SBT plugins not using custom resolvers - scala

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 ...

Related

What is an SBT resolver?

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

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

File of one of the sbt plugin's dependencies

I need to get hold of the File reference to a specific artifact during the setup phase of my sbt's plugin.
I've tried:
obtaining the ivy home directory, but that basically means assuming where ivy will place the files (they could be even be in a local maven)
parsing System.getProperty("java.class.path"), but it only contains the sbt-launch jar
obtaining the resolved sbt jars from the update.value setting, but it doesn't have any of the plugin's jars in the list! (only the jars for the application being compiled)
Short of invoking the Ivy API manually, is there any way to get the File to the plugin's jar dependency?
NOTE: This is a very specific part of how to write an sbt plugin to launch the app with an agent factored out into a separate question.
got it! adding the dependency explicitly within the source reveals its resolved path:
override val projectSettings = Seq(
libraryDependencies += "com.github.fommil.lion" %% "agent" % "1.0-SNAPSHOT",
javaOptions ++= Seq(s"-Dhack=${update.value}}")
)
has a reference in it!

Finding resolver and version of dependency, say play-json, in sbt?

Say I want to include a dependency on the play-json library in my sbt file. How and where can I find that information?
I tried searching central repo, play git repository -- couldn't find anything.
First of all, when you want to include a dependency, you've somehow been told about it - about the required version and where to find it. Ask the person this question and you're done. The official source should always be the home page of a dependency.
I'd use http://search.maven.org/ or http://mvnrepository.com/ and pick whatever version is the most current. In your case, however, esp. after the comment where you pointed at Adding Play JSON Library to sbt the answer was right there - in the answers - see https://stackoverflow.com/a/20475410/1305344:
Play 2.2 is out and can be added separately from rest of Play
Framework. in build.sbt:
resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.2.1"
The trick is to set up resolvers properly and using the above resolver gives http://repo.typesafe.com/typesafe/releases/com/typesafe/play/play-json_2.10.
When you've got resolvers and any version in your build configuration, you may want to use sbt-updates that's (quoting the plugin's headline) "SBT plugin that can check maven repositories for dependency updates". Quite handy to have it installed as a global plugin, i.e. .sbt/0.13/plugins/sbt-updates.sbt with the following:
resolvers += Classpaths.sbtPluginSnapshots
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.6-SNAPSHOT")
When you execute dependencyUpdates you're told what needs version update.
> dependencyUpdates
[info] Found 1 dependency update for superapp
[info] org.jacoco:org.jacoco.agent:jacoco : 0.6.4.201312101107 -> 0.6.5.201403032054 -> 0.7.0.201403182114
[success] Total time: 1 s, completed 2014-03-28 18:30:12
As you can see, I need to upgrade jacoco.
If the project you depend on releases to some known repositories, running sbt-updates regularly will ultimately tell you about the update. I'd strongly recommend reading RELEASE_NOTES for an update before upgrading since it may be introducing some breaking changes you'd rather know about before going to production.