Deprecation and feature warnings for SBT project definition files - sbt

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.")
}

Related

sbt 1.3.8 publishLocal creates a jar that sbt update can't resolve. scala version is appended to jar name

I published some libraries using sbt publishLocal it worked and published to my ~/.ivy2/local dir.
I then have a project that depends on these libraries but sbt update can't find them.
specifically, my project has these dependencies:
lazy val myDependencies = commonDependencies ++ Seq(
"my.corp" %% "lib1" % "1.0.1-SNAPSHOT" withSources () withJavadoc (),
"my.corp" %% "lib2" % "2.0.2-SNAPSHOT" withSources () withJavadoc ()
)
sbt update has this error:
[error] (services / update) lmcoursier.internal.shaded.coursier.error.FetchError$DownloadingArtifacts: Error fetching artifacts:
[error] file:////home/myuser/.ivy2//local/my.corp/lib1_2.12/1.0.1-SNAPSHOT/jars/lib1.jar: not found: /home/myuser/.ivy2//local/my.corp/lib1_2.12/1.0.1-SNAPSHOT/jars/lib1.jar
[error] file://///home/myuser/.ivy2//local/my.corp/lib2_2.12/2.0.2-SNAPSHOT/jars/lib2.jar: not found: /home/myuser/.ivy2//local/my.corp/lib2_2.12/2.0.2-SNAPSHOT/jars/lib2.jar
when I look in the dir I can see the published jars but their name has the scala version appended, which is why the update resolving fails, I think :
$ ls /home/myuser/.ivy2/local/my.corp/lib1_2.12/1.0.1-SNAPSHOT/jars
lib1_2.12.jar lib1_2.12.jar.md5 lib1_2.12.jar.sha1
$ ls /home/myuser/.ivy2/local/my.corp/lib2_2.12/2.0.2-SNAPSHOT/jars
lib2_2.12.jar lib2_2.12.jar.md5 lib2_2.12.jar.sha1
If I publish to a repo for real I can resolve the libs.
Does anyone know the sbt incantation to fix this? ;-)
Cheers
Karl
Update:- I think coursier is the problem, not sure how to tell it to look for lib2_2_12.jar. Could it have a bad cached reference?
Caused by: lmcoursier.internal.shaded.coursier.cache.ArtifactError$NotFound: not found: /home/myuser/.ivy2/local/my.corp/lib2_2.12/2.0.2-SNAPSHOT/jars/lib2.jar
Update:-
disabling coursier worked
from the sbt REPL I can run
sbt:my-project> set ThisBuild / useCoursier := false
and then
sbt:my-project> update
and that worked, but setting it back to true update failed again, so this looks like a coursier issue.
Update:
coursier fetch from the command line worked!!
coursier fetch my.corp::lib1:1.0.1-SNAPSHOT --no-default -r central -r ivy2Local
downloaded the transitive dependencies and found my jar in my local ivy2 dir
so this is back to looking like an sbt - coursier interaction issue
I've just now run into this and after lots of diffs between an older working version and this non-working version I figured out that it is the withSources() that triggers the bug in sbt and/or coursier.

Running sbt release task from cli for sub-project doesn't work

I have a multi-project sbt where I use sbt-release plugin. Everything works fine if I run release in a sub-project
> project reporter
[info] Set current project to reporter (in build file:/source/storage-integ/)
> release
[info] Starting release process off commit: c069698baf8bb6fca611ab4e7e086398aab473c5
[info] Checking remote [origin] ...
But this doesn't work when I run "sbt reporter/release" from cli. Where as "sbt reporter/compile" or "sbt reporter/assembly" do work.
$ sbt reporter/release
[warn] Executing in batch mode.
[warn] For better performance, hit [ENTER] to switch to interactive mode, or
[warn] consider launching sbt without any commands, or explicitly passing 'shell'
[info] Loading global plugins from /home/vagrant/.sbt/0.13/plugins
[info] Loading project definition from /source/storage-integ/project
[info] Set current project to root (in build file:/source/storage-integ/)
[error] Expected ':' (if selecting a configuration)
[error] Not a valid key: release (similar: releaseVcs, rpmRelease, rpm-release)
[error] reporter/release
This looks very similar to another SO post. I tried adding releaseSettings to build.sbt as suggested but it throws error
build.sbt:62: error: not found: value releaseSettings
I tried import sbtrelease.Release._ but that throws
error: object Release is not a member of package sbtrelease
At this point I feel the solution mentioned is no longer valid. Also, I don't see any reference to releaseSettings in sbt-release readme. Any idea how to get this working?
sbt.version = 0.13.15 && sbt-release: "1.0.6"
The release settings should be only in your root project. So, in order to have that:
First, your build.sbt could be something like this
lazy val root: Project = project.in(file("."))
.settings(Releases.settings: _*)
.aggregate(module1, module2)
Then, your project/Releases.scala like:
object Releases {
// You need to custom these to reflect your actual procedure
private val releaseProcess = Def.setting {
Seq[ReleaseStep](
checkSnapshotDependencies,
inquireVersions,
runClean,
runTest,
setReleaseVersion,
commitReleaseVersion,
tagRelease,
publishArtifacts,
setNextVersion,
commitNextVersion,
pushChanges
)
}
val settings = Seq(
releaseCommitMessage := s"Set version to ${(version in ThisBuild).value}",
releaseTagName := (version in ThisBuild).value,
releaseProcess := releaseProcess.value
)
}
By default you need a version.sbt with your current version. Lets say:
version in ThisBuild := "1.0.0-SNAPSHOT"
Then just:
sbt release

What does extend for a configuration do?

In SBT I create a new config, called katebush, as follows:
lazy val KateBush: Configuration = config("katebush")
When I try to run katebush:compile I get an error. That's what I expect.
> katebush:compile
[error] No such setting/task
[error] katebush:compile
[error] ^
Now I extend Compile in my config definition, and I expect to pick up the compile from the inherited scope.
lazy val KateBush: Configuration = config("katebush") extend Compile
Except it doesn't work:
> katebush:compile
[error] No such setting/task
[error] katebush:compile
[error] ^
But if I add in the defaults to the config (in build.sbt) so it looks as follows:
lazy val KateBush: Configuration = config("katebush") extend Compile
inConfig(KateBush)(Defaults.compileSettings)
it works fine:
> katebush:compile
[info] Updating {file:/Users/jacek/sandbox/so-25596360/}so-25596360...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[success] Total time: 0 s, completed Aug 31, 2014 11:35:47 PM
So, my question is, what exactly does extend for a configuration do?
DISCLAIMER I've got a rather basic understanding of the config concept of sbt.
tl;dr Extending a configuration is solely to inherit the dependencies groups not settings.
From the sources of final case class Configuration:
def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive)
By default, extendsConfigs is Nil as can be seen in the sbt.Configurations object:
def config(name: String) = new Configuration(name)
that resolves to (note Nil)
def this(name: String) = this(name, "", true, Nil, true)
In sbt.IvySbt.toIvyConfiguration:
import org.apache.ivy.core.module.descriptor.{ Configuration => IvyConfig }
and that's where the support of the config concept ends in sbt and Ivy steps in. That's where you'd have to look at the documentation of Ivy.
But before that read Advanced configurations example where it says:
This is an example .scala build definition that demonstrates using Ivy
configurations to group dependencies.
That's the beginning of the explanation. Ivy configurations are to group dependencies and extending a configuration is to extend the grouping.
From the official documentation of Ivy about the conf element:
a configuration is a way to use or construct a module.(...)
a module may need some other modules and artifacts only at build time, and some others at runtime. All those differents ways to use or build a module are called in Ivy module configurations.
Reading along you can find the answer to your question (that I'm myself yet to digest, too):
A configuration can also extend one or several other ones of the same
module. When a configuration extends another one, then all artifacts
required in the extended configuration will also be required in the
configuration that extends the other one. For instance, if
configuration B extends configuration A, and if artifacts art1 and
art2 are required in configuration A, then they will be automatically
required in configuration B. On the other hand, artifacts required in
configuration B are not necessarily required in configuration A.
This notion is very helpful to define configurations which are similar
with some differences.
At the bottom of the page, there's the Examples section with an example with runtime config that has "runtime will be composed of all dependencies, all transitively, including the dependencies declared only in compile."
With this, you can now understand the config concept in sbt as a dependencies groups and what's grouped in Compile is available in Runtime as its definition looks as follows:
lazy val Runtime = config("runtime") extend (Compile)
I have just had to figure this out, so I thought this was worth clarifying. The configuration has to be added to the project for delegation to the extended configuration to occur:
lazy val KateBush: Configuration = config("katebush") extend Compile
lazy val root = (project in file(".")).configs(KateBush)
will work fine. If you
inspect katebush:compile
then you can view the delegation chain:
...
[info] Delegates:
[info] katebush:compile
[info] compile:compile
[info] *:compile
[info] {.}/katebush:compile
[info] {.}/compile:compile
[info] {.}/*:compile
[info] */katebush:compile
[info] */compile:compile
[info] */*:compile
...

How to configure Typesafe Activator not to use user home?

I'd like to configure Typesafe Activator and it's bundled tooling not to use my user home directory - I mean ~/.activator (configuration?), ~/.sbt (sbt configuration?) and especially ~/.ivy2, which I'd like to share between my two OSes.
Typesafe "documentation" is of little help.
Need help for both Windows and Linux, please.
From Command Line Options in the official documentation of sbt:
sbt.global.base - The directory containing global settings and plugins (default: ~/.sbt/0.13)
sbt.ivy.home - The directory containing the local Ivy repository and artifact cache (default: ~/.ivy2)
It appears that ~/.activator is set and used in the startup scripts and that's where I'd change the value.
It also appears (in sbt/sbt.boot.properties in activator-launch-1.2.1.jar) that the value of ivy-home is ${user.home}/.ivy2:
[ivy]
ivy-home: ${user.home}/.ivy2
checksums: ${sbt.checksums-sha1,md5}
override-build-repos: ${sbt.override.build.repos-false}
repository-config: ${sbt.repository.config-${sbt.global.base-${user.home}/.sbt}/repositories}
It means that without some development it's only possible to change sbt.global.base.
➜ minimal-scala activator -Dsbt.global.base=./sbt -Dsbt.ivy.home=./ivy2 about
[info] Loading project definition from /Users/jacek/sandbox/sbt-launcher/minimal-scala/project
[info] Set current project to minimal-scala (in build file:/Users/jacek/sandbox/sbt-launcher/minimal-scala/)
[info] This is sbt 0.13.5
[info] The current project is {file:/Users/jacek/sandbox/sbt-launcher/minimal-scala/}minimal-scala 1.0
[info] The current project is built against Scala 2.11.1
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4
If you want to see under the hood, you could query for the current values of the home directories for sbt and Ivy with consoleProject command (it assumes you started activator with activator -Dsbt.global.base=./sbt -Dsbt.ivy.home=./ivy2):
> consoleProject
[info] Starting scala interpreter...
[info]
import sbt._
import Keys._
import _root_.sbt.plugins.IvyPlugin
import _root_.sbt.plugins.JvmPlugin
import _root_.sbt.plugins.CorePlugin
import _root_.sbt.plugins.JUnitXmlReportPlugin
import currentState._
import extracted._
import cpHelpers._
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60).
Type in expressions to have them evaluated.
Type :help for more information.
scala> appConfiguration.eval.provider.scalaProvider.launcher.bootDirectory
res0: java.io.File = /Users/jacek/sandbox/sbt-launcher/minimal-scala/sbt/boot
scala> appConfiguration.eval.provider.scalaProvider.launcher.ivyHome
res1: java.io.File = /Users/jacek/.ivy2
Iff you're really into convincing Activator to use sbt.ivy.home, you have to change sbt/sbt.boot.properties in activator-launch-1.2.2.jar. Just follow the steps:
Unpack sbt/sbt.boot.properties out of activator-launch-1.2.2.jar.
jar -xvf activator-launch-1.2.2.jar sbt/sbt.boot.properties
Edit sbt/sbt.boot.properties and replace ivy-home under [ivy].
ivy-home: ${sbt.ivy.home-${user.home}/.ivy2}
Add the changed sbt/sbt.boot.properties to activator-launch-1.2.2.jar.
jar -uvf activator-launch-1.2.2.jar sbt/sbt.boot.properties
With the change, -Dsbt.ivy.home=./ivy2 works fine.
scala> appConfiguration.eval.provider.scalaProvider.launcher.bootDirectory
res0: java.io.File = /Users/jacek/sandbox/sbt-launcher/minimal-scala/sbt/boot
scala> appConfiguration.eval.provider.scalaProvider.launcher.ivyHome
res1: java.io.File = /Users/jacek/sandbox/sbt-launcher/minimal-scala/ivy2
I was experimenting with this today. After a while, it seems to me like this could be the best thing to do:
Windows:
setx _JAVA_OPTIONS "-Duser.home=C:/my/preferred/home/"
Linux:
export _JAVA_OPTIONS='-Duser.home=/local/home/me'
Then you should be good to go for any Java Program that wants to store data in your home directory.
As an addition to Jacek's answer, another way that worked for me to set the .ivy2 directory was to use the sbt ivyConfiguration task. It returns configuration settings related to ivy, including the path to the ivy home (the one which defaults to ~/.ivy2).
Simply add these few lines to the build.sbt file in your project :
ivyConfiguration ~= { originalIvyConfiguration =>
val config = originalIvyConfiguration.asInstanceOf[InlineIvyConfiguration]
val ivyHome = file("./.ivy2")
val ivyPaths = new IvyPaths(config.paths.baseDirectory, Some(ivyHome))
new InlineIvyConfiguration(ivyPaths, config.resolvers, config.otherResolvers,
config.moduleConfigurations, config.localOnly, config.lock,
config.checksums, config.resolutionCacheDir, config.log)
}
It returns a new ivy configuration identical to the original one, but with the right path to the ivy home directory (here ./.ivy2, so it'll be located just next to the build.sbt file). This way, when sbt uses the ivyConfiguration task to get the ivy configuration, the path to the .ivy2 directory will be the one set above.
It worked for me using sbt 0.13.5 and 0.13.8.
Note: for sbt versions 0.13.6 and above, the construction of the InlineIvyConfiguration needs an additional parameter to avoid being flagged as deprecated, so you might want to change the last line into :
new InlineIvyConfiguration(ivyPaths, config.resolvers, config.otherResolvers,
config.moduleConfigurations, config.localOnly, config.lock,
config.checksums, config.resolutionCacheDir, config.updateOptions, config.log)
(note the additional config.updateOptions)
I had that same problem on Mac. I erased the directory in user home directory named .activator and all related folder. After that run activator run command on terminal. Activator download all of the folder which I deleted. Than problem solved.

Sbt, local sbt plugin, using jooq code generation plugin

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.

Resources