Sbt plugin publication and resolution on bintray, different paths (sbt-bintray plugin) - sbt

I have some troubles to publish/use a custom sbt plugin from bintray. I'm able
to publish sbt-plugin on bintray but when I try to use it the resolver uses
another path.
I have followed the official guide but adapted it to the latest version of the plugin, I have this build.sbt into my plugin :
lazy val commons = Seq(
organization in ThisBuild := "me.my.app",
version in ThisBuild := "0.1.0"
)
lazy val root = (project in file(".")).
settings(commons ++ BintrayPlugin.bintrayPublishSettings: _*).
settings(
sbtPlugin := true,
name := "sbt-plugin",
description := "Share configuration and plugins accros app projects",
bintrayOmitLicense := true,
publishMavenStyle := false,
bintrayRepository := "sbt-plugins",
bintrayOrganization := None
).
settings(
addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0"),
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0"),
addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "0.8.0")
)
The sbt-plugin> publish task complete successfully and publish my plugin into
me.my.app/sbt-plugin/scala_2.10/sbt_0.13/0.1.0/jars/sbt-plugin.jar
Then I add addSbtPlugin("me.my.app" % "sbt-plugin" % "0.1.0") to my-project\project\plugins.sbt and
reload it. But he fail with
[warn] ==== bintray-{organization}-{repo}: tried
[warn] https://dl.bintray.com/{organization}/sbt-plugins/me/my/app/sbt-plugin_2.10_0.13/0.1.0/sbt-plugin-0.1.0.pom
...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: me.my.app#sbt-plugin;0.1.0: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.
[warn] me.my.app:sbt-plugin:0.1.0 (scalaVersion=2.10, sbtVersion=0.13)
[warn]
[warn] Note: Unresolved dependencies path:
[warn] me.my.app:sbt-plugin:0.1.0 (scalaVersion=2.10, sbtVersion=0.13) (/home/me/Projects/app/app-web/project/plugins.sbt#L7-8)
[warn] +- default:app-web-build:0.1-SNAPSHOT (scalaVersion=2.10, sbtVersion=0.13)
sbt.ResolveException: unresolved dependency: me.my.app#sbt-plugin;0.1.0: not found
at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:313)
[error] (*:update) sbt.ResolveException: unresolved dependency: me.my.app#sbt-plugin;0.1.0: not found
As you can see the URL used to download the plugin is not the same as the
one where the plugin has been published. (with publishLocal my plugin is
published under the same path but resolved successfully.
Local : me.my.app/sbt-plugin/scala_2.10/sbt_0.13/0.1.0/jars/sbt-plugin.jar
Upload : me.my.app/sbt-plugin/scala_2.10/sbt_0.13/0.1.0/jars/sbt-plugin.jar
Downlad: me/my/app/sbt-plugin_2.10_0.13/0.1.0/sbt-plugin-0.1.0.pom
I have tried with or without publishMavenStyle := false and with Resolver.bintrayRepo and Resolver.bintrayIvyRepo but without success.
I will be missing something but I have to admit that I feel a bit lost. So what are the missing configuration that should align the upload and download paths ?
Details :
publishMavenStyle := false -> me.my.app/sbt-plugin/scala_2.10/sbt_0.13/0.1.0/jars/sbt-plugin.jar
publishMavenStyle := true -> me.my.app/sbt-plugin/scala_2.10/sbt_0.13/0.1.0/jars/sbt-plugin.jar
Resolver.bintrayRepo -> me/my/app/sbt-plugin_2.10_0.13/0.1.0/sbt-plugin-0.1.0.pom
Resolver.bintrayIvyRepo -> me.my.app/sbt-plugin/scala_2.10/sbt_0.13/0.1.0/ivys/ivy.xml

The publication part was ok. The only problem was on the resolution side.
I had to add a custom resolver with explicit ivyStylePatterns resolver into my-project\build.sbt:
resolvers += Resolver.url("me # bintray", url("https://dl.bintray.com/{my-bintray-account}/{my-bintray-generic-repo}"))(Resolver.ivyStylePatterns)

Related

sbt: publishing plugin to and resolving from local repo

I am trying to publish an sbt plugin to a local file repo. In the plugin's build.sbt I have:
publishTo := Some(Resolver.file("localtrix", file("/Users/jast/repo/localtrix")))
I run the publish task and it gets published fine to
/Users/jast/repo/localtrix/org/me/sbt-plugin_2.12_1.0/1.2.3
In another project, I want to resolve this plugin. in project/plugins.sbt I have:
resolvers += Resolver.file("localtrix", file("/Users/jast/repo/localtrix"))
addSbtPlugin("org.me" % "sbt-plugin" % "1.2.3")
I try to run sbt in the this project and I get:
[info] Updating ProjectRef(uri("file:/Users/jast/playspace/untitled38/project/"), "untitled38-build")...
[warn] module not found: org.me#sbt-plugin;1.2.3
[warn] ==== typesafe-ivy-releases: tried
[warn] https://repo.typesafe.com/typesafe/ivy-releases/org.me/sbt-plugin/scala_2.12/sbt_1.0/1.2.3/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn] https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/org.me/sbt-plugin/scala_2.12/sbt_1.0/1.2.3/ivys/ivy.xml/2017.2+4-3037ba82+20180314-1919/ivys/ivy.xml
[warn] ==== local: tried
[warn] /Users/jast/.ivy2/local/org.me/sbt-plugin/scala_2.12/sbt_1.0/1.2.3/ivys/ivy.xml
[warn] ==== public: tried
[warn] https://repo1.maven.org/maven2/org/me/sbt-plugin_2.12_1.0/1.2.3/sbt-plugin-1.2.3.pom
[warn] ==== local-preloaded-ivy: tried
[warn] /Users/jast/.sbt/preloaded/org.me/sbt-plugin/scala_2.12/sbt_1.0/1.2.3/ivys/ivy.xml
[warn] ==== local-preloaded: tried
[warn] file:////Users/jast/.sbt/preloaded/org/me/sbt-plugin_2.12_1.0/1.2.3/sbt-plugin-1.2.3.pom
[warn] ==== localtrix: tried
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.me#sbt-plugin;1.2.3: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
So how can I publish to a local repo it in a way that also gets resolved correctly?
Note: publishLocal and resolving from .ivy2/local works, but I want to be able to publish to a repo that I can copy to another machine without messing with that directory.
sbt plugins by default are published ivy-style, so you when you refer to your local repository, use Resolver.ivyStylePatterns. To publish:
publishTo := Some(Resolver.file("localtrix", file("/Users/jast/repo/localtrix"))(Resolver.ivyStylePatterns))
And to resolve:
resolvers += Resolver.file("localtrix", file("/Users/jast/repo/localtrix"))(Resolver.ivyStylePatterns)
addSbtPlugin("org.me" % "sbt-plugin" % "1.2.3")
Alternatively you can set publishMavenStyle := true for the plugin, but I see that you already figured that out.
You missed scala version in name. And you have also strange suffix in plugin name _1.0 in your published artifact, so just fixing scala version could be not enough.
This should work.
addSbtPlugin("org.me" % "sbt-plugin_2.12_1.0" % "1.2.3")
If you find out where came this suffix _1.0 from, fix on scala version should help:
addSbtPlugin("org.me" %% "sbt-plugin" % "1.2.3")
Update after comment
Ok, thanks, I did not know that for plugins it works differently.
But try to define resolver differently for resolvers (works for me):
resolvers += "localtrix" at "file:///Users/jast/repo/localtrix"
addSbtPlugin("org.me" % "sbt-plugin" % "1.2.3")

sbt behind local artifactory proxy

When setting up a sbt project with a local artifactory / maven proxy I see the following message:
In order to specify that all resolvers added in the sbt project should
be ignored in favor of those configured in the repositories
configuration, add the following configuration option to the sbt
launcher script:
-Dsbt.override.build.repos=true
Add the following to your build.sbt file:
resolvers +=
"Artifactory" at "http://url/artifactory/virtualRepository/"
But what I would like to achieve is a behaviour similar to maven i.e. not manually overriding resolvers in the SBT file, but rather via the configuration.
Is this possible as well? If yes how?
Desired behaviour
the project should compile fine without local artifactory proxy
when available / configured in repositories the local one should be used as the source / cache for quicker access
currently, I only get unresolved dependencies for sbt plugins:
::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.scalariform#sbt-scalariform;1.6.0: not found
[warn] :: org.scoverage#sbt-scoverage;1.5.0: not found
[warn] :: org.scalastyle#scalastyle-sbt-plugin;0.8.0: not found
[warn] :: net.virtual-void#sbt-dependency-graph;0.8.2: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
With warnings of
[warn] module not found: org.scalariform#sbt-scalariform;1.6.0
[warn] ==== typesafe-ivy-releases: tried
[warn] https://repo.typesafe.com/typesafe/ivy-releases/org.scalariform/sbt-scalariform/scala_2.10/sbt_0.13/1.6.0/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn] https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/org.scalariform/sbt-scalariform/scala_2.10/sbt_0.13/1.6.0/ivys/ivy.xml
[warn] ==== local: tried
[warn] d:\users\heilerg\.ivy2\local\org.scalariform\sbt-scalariform\scala_2.10\sbt_0.13\1.6.0\ivys\ivy.xml
[warn] ==== my-ivy-proxy-releases: tried
[warn] http://url/artifactory/virtualRepositoryScala/org.scalariform/sbt-scalariform/scala_2.10/sbt_0.13/1.6.0/ivys/ivy.xml
[warn] ==== my-maven-proxy-releases: tried
[warn] http://url/artifactory/virtualRepositoryScala/org/scalariform/sbt-scalariform_2.10_0.13/1.6.0/sbt-scalariform-1.6.0.pom
[warn] ==== Artima Maven Repository: tried
[warn] http://repo.artima.com/releases/org/scalariform/sbt-scalariform_2.10_0.13/1.6.0/sbt-scalariform-1.6.0.pom
[info] Resolving org.scoverage#sbt-scoverage;1.5.0 ...
and SBT logs will show
[ERROR] (o.a.r.RemoteRepoBase:766) - IO error while trying to download resource 'repo1:org/scalariform/sbt-scalariform_2.10_0.13/1.6.0/sbt-scalariform-1.6.0.pom': org.artifactory.api.repo.exception.maven.BadPomException: The target deployment path 'org/scalariform/sbt-scalariform_2.10_0.13/1.6.0/sbt-scalariform-1.6.0.pom' does not match the POM's expected path prefix 'org/scalariform/sbt-scalariform/1.6.0'. Please verify your POM content for correctness and make sure the source path is a valid Maven repository root path.
Somewhere people mention to use the following option in Artifactory to "suppress POM consistency checks", but in the current version of artifactory I can not finde such an option.
edit
I can see only these options
As answered in the comment, a common workaround is "Suppress POM Consistency Checks" - Advanced Settings.
If that is not desirable, another method might be to re-publish the plugin with a valid POM. I've written POM consistency for sbt plugins to show that can be done.
// set some unique postfix
ThisBuild / version := "0.15.0-Pets1"
lazy val root = (project in file("."))
.enablePlugins(SbtPlugin)
.settings(
name := "sbt-assembly",
....
publishMavenStyle := true,
// add this
pomConsistency2021DraftSettings,
)
// Add the following
lazy val pomConsistency2021Draft = settingKey[Boolean]("experimental")
/**
* this is an unofficial experiment to re-publish plugins with better Maven compatibility
*/
def pomConsistency2021DraftSettings: Seq[Setting[_]] = Seq(
pomConsistency2021Draft := Set("true", "1")(sys.env.get("POM_CONSISTENCY").getOrElse("false")),
moduleName := {
if (pomConsistency2021Draft.value)
sbtPluginModuleName2021Draft(moduleName.value,
(pluginCrossBuild / sbtBinaryVersion).value)
else moduleName.value
},
projectID := {
if (pomConsistency2021Draft.value) sbtPluginExtra2021Draft(projectID.value)
else projectID.value
},
)
def sbtPluginModuleName2021Draft(n: String, sbtV: String): String =
s"""${n}_sbt${if (sbtV == "1.0") "1" else if (sbtV == "2.0") "2" else sbtV}"""
def sbtPluginExtra2021Draft(m: ModuleID): ModuleID =
m.withExtraAttributes(Map.empty)
.withCrossVersion(CrossVersion.binary)

How to keep library dependencies updated to Scala version?

I am compiling my project with sbt and am getting an UNRESOLVED DEPENDENCIES error.
The fact is that I fetched the example I use (a hello world program) from an online blog, that uses scalaVersion := "2.10.0" as shown below. I am using 2.11.2.
How do I update the library dependencies (in the build.sbt) to the latest version of Scala, specifically the revision part?
build.sbt
name := "Hello Test #1"
version := "1.0"
scalaVersion := "2.10.0"
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.10" % "2.2-M1"
The error:
[info] Resolving com.typesafe.akka#akka-actor_2.11.2;2.2-M1 ...
[warn] module not found: com.typesafe.akka#akka-actor_2.11.2;2.2-M1
[warn] ==== local: tried
[warn] /home/plard/.ivy2/local/com.typesafe.akka/akka-actor_2.11.2/2.2-M1/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/com/typesafe/akka/akka-actor_2.11.2/2.2-M1/akka-actor_2.11.2-2.2-M1.pom
[warn] ==== Typesafe Repository: tried
[warn] http://repo.typesafe.com/typesafe/releases/com/typesafe/akka/akka-actor_2.11.2/2.2-M1/akka-actor_2.11.2-2.2-M1.pom
[info] Resolving jline#jline;2.12 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.typesafe.akka#akka-actor_2.11.2;2.2-M1: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) sbt.ResolveException: unresolved dependency: com.typesafe.akka#akka-actor_2.11.2;2.2-M1: not found
[error] Total time: 1 s, completed Aug 11, 2014 10:32:11 AM
name := "Hello Test #1"
version := "1.0"
scalaVersion := "2.11.2"
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.4"
This should do it. Note the %% and no version specified for the Akka artifact. Doing so, SBT will automatically append your Scala version to the artifact. See docs for more details.

Why SBT doesn't use resolvers from root project (in multi-module project)

In a multi-module project, SBT doesn't seem to use resolvers when building modules. The resolvers are declared in the root project's build.sbt as follows:
resolvers += "SpringSource Milestone Repository" at "http://repo.springsource.org/milestone"
and the projects are declared like:
lazy val core = project.settings(
libraryDependencies ++= { ... }
)
But when compiling, the resolvers are not used and I get :
[info] Resolving org.springframework.scala#spring-scala;1.0.0.BUILD-SNAPSHOT ...
[warn] module not found: org.springframework.scala#spring-scala;1.0.0.BUILD-SNAPSHOT
[warn] ==== local: tried
[warn] /home/ariskk/.ivy2/local/org.springframework.scala/spring-scala/1.0.0.BUILD-SNAPSHOT/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/org/springframework/scala/spring-scala/1.0.0.BUILD-SNAPSHOT/spring-scala-1.0.0.BUILD-SNAPSHOT.pom
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.springframework.scala#spring-scala;1.0.0.BUILD-SNAPSHOT: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
Any ideas what might be wrong?
Use the following in the root project's build.sbt:
resolvers in ThisBuild += "SpringSource Milestone Repository" at "http://repo.springsource.org/milestone"
in ThisBuild is the answer. See Scopes.
I had a similar issue with a Scala / ScalaJS project.
The resolver was only taken when added to the 'sub-project'.
//this works NOT
resolvers += Resolver.sonatypeRepo("snapshots")
// this works
lazy val client = (project in file("client")).settings(
scalaVersion := scalaV,
...,
resolvers += Resolver.sonatypeRepo("snapshots"),
...
(sbt 0.13.15)

Why can't SBT find the Play 2.1 plugin?

In my plugins.sbt file, I have
scalaVersion := "2.10.0"
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
addSbtPlugin("play" % "sbt-plugin" % "2.1")
When I try run sbt I get, among other things
[warn] ==== Typesafe repository: tried
[warn] http://repo.typesafe.com/typesafe/releases/play/sbt-plugin_2.10_0.12/2.1/sbt- plugin-2.1.pom
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/play/sbt-plugin_2.10_0.12/2.1/sbt-plugin-2.1.pom
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: play#sbt-plugin;2.1: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.
[warn] play:sbt-plugin:2.1 (sbtVersion=0.12, scalaVersion=2.10)
[warn]
sbt.ResolveException: unresolved dependency: play#sbt-plugin;2.1: not found
Why can't SBT find the plugin? I've also tried addSbtPlugin("play" % "sbt-plugin" % "2.1-RC1") with similar results.
The problem was including the scalaVersion setting inside the plugins.sbt file. This causes sbt to search for sbt-plugin_2.10.0_0.12 in the repositories when it should actually search for sbt-plugin_2.9.2_0.12.
I'm not sure about the semantics behind specifying the scalaVersion in the plugins.sbt file, but maybe it's declaring the Scala version that SBT is running on.
Here is a link to the Play 2.1 sbt-plugin files: http://repo.typesafe.com/typesafe/simple/ivy-releases/play/sbt-plugin/scala_2.9.2/sbt_0.12/2.1-RC1/srcs/
As per the documentation,
Add this in your project/plugins.sbt:
addSbtPlugin("play" % "sbt-plugin" % "2.1.0")
Change the project/build.properties
sbt.version=0.12.2

Resources