I am currently working on a Scala.js library intended to be exposed as a JS library. To make my tests run faster I added the option as per scalajs's Basic Tutorial
scalaJSUseRhino in Global := false
However when I run the tests in sbt nothing seems to happen:
clean
project myprojectJS
test
last
Here are the relevant outputs from the last command
[debug] Loading JSEnv with linked file /home/jacob/proj/mastermind/js/target/scala-2.11/mastermind-test-fastopt.js
[debug] Subclass fingerprints: List()
[debug] Annotation fingerprints: List()
Nothing seems to be happening after JSEnv has been loaded.
The problem was since I was writing a library that'll be exposed as a Javascript module, I had the following config in SBT:
scalaJSOutputWrapper := ("var __ScalaJSEnv = { exportsNamespace: exports };", ""),
Which means the test runner JS file produced will be wrapped too, making the output Javascript file essentially do nothing.
Adding this config in SBT fixes the issue:
scalaJSOutputWrapper in Test := ("", ""),
ScalaJS tests where not running in my environment, too, as long I was using ScalaTest and UnitTest for a sbt-crossproject.
[debug] Subclass fingerprints: List()
[debug] Annotation fingerprints: List()
both fingerprints where empty lists (running sbt -v -d for verbosity + debug informations)
I switched then to uTest (because of sbt-crossproject),
added to my build.sbt settings:
testFrameworks += new TestFramework("utest.runner.Framework"),
libraryDependencies += "com.lihaoyi" %%% "utest" % "0.6.3" % "test"
Now the test log shows...
...
[debug] Loading JSEnv with linked file qqqqq/.js/target/scala-2.11/qqqq-test-fastopt.js
[debug] Starting process: node
[debug] Subclass fingerprints: List((utest.TestSuite,true,org.scalajs.testcommon.Serializer$FingerprintSerializer$$anon$3#12662894))
[debug] Annotation fingerprints: List()
-------------------------------- Running Tests --------------------------------
[debug] Running TaskDef(TutorialTest, org.scalajs.testcommon.Serializer$FingerprintSerializer$$anon$3#60e5e39e, false, [SuiteSelector])
....
Related
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
After upgrading to version 0.8.0 of the sbt-resolver plugin I get the following error messages after typing sbt ~re-start:
[info] Application exampleJS not yet started
[info] Application exampleJVM not yet started
[info] Starting application exampleJVM in the background ...
exampleJVM Starting example.Server.main()
java.lang.RuntimeException: No main class detected!
at scala.sys.package$.error(package.scala:27)...
Hoewever, I did specify a main class in my build.sbt:
).jvmSettings(
name := "Server",
mainClass := Some("example.Server"),
...
My project setup is quite analogous to this example.
However - despite this error message - the spray server is started correctly!?
But I want to get rid of this annoying message...
If you're just looking to suppress the warning, try replacing reStart in the JS subproject's build settings with a no-op:
import spray.revolver.RevolverPlugin.Revolver
// Assuming you're using the same name as the example you linked.
// Override the reStart task to do nothing.
val exampleJS = example.js.settings(Revolver.reStart := {})
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 can I set a system property for runMain upon executing it from command line on Windows?
I'd like to be able to run the following command:
sbt -Dconfig.resource=../application.conf "runMain akka.Main com.my.main.Actor"
Regardless of whether fork is true, whether I put it in SBT_OPTS, or how I pass it in I cannot accomplish this. I am familiar with both Setting value of setting on command line when no default value defined in build? and Setting system properties with "sbt run" but neither answer my question.
Other questions seem to indicate you can't even easily view the Java invocation arguments easily in SBT. Any help is appreciated.
This works:
sbt '; set javaOptions += "-Dconfig.resource=../application.conf" ; runMain akka.Main com.my.main.Actor'
If this isn't a "friendly" enough syntax, wrap it in a little shell script.
(Note this assumes you have fork set to true for running. If you don't, see akauppi's comment.)
You could use envVars setting. I'm unsure how idiomatic it is in SBT, though.
> help envVars
Environment variables used when forking a new JVM
The following (very minimalistic) build.sbt worked fine.
fork := true
envVars := Map("msg" -> "hello")
Once you get it running, setting envVars to any value with set does the trick.
> help set
set [every] <setting-expression>
Applies the given setting to the current project:
1) Constructs the expression provided as an argument by compiling and loading it.
2) Appends the new setting to the current project's settings.
3) Re-evaluates the build's settings.
This command does not rebuild the build definitions, plugins, or configurations.
It does not automatically persist the setting(s) either.
To persist the setting(s), run 'session save' or 'session save-all'.
If 'every' is specified, the setting is evaluated in the current context
and the resulting value is used in every scope. This overrides the value
bound to the key everywhere.
I've got a simple app to run.
$ sbt run
[info] Set current project to fork-testing (in build file:/C:/dev/sandbox/fork-testing/)
[info] Running Hello
[info] hello
With the envVars setting changed on the command line the output would change as follows:
$ sbt 'set envVars := Map("msg" -> "Hello, Chad")' run
[info] Set current project to fork-testing (in build file:/C:/dev/sandbox/fork-testing/)
[info] Defining *:envVars
[info] The new value will be used by *:runner, compile:run::runner and 1 others.
[info] Run `last` for details.
[info] Reapplying settings...
[info] Set current project to fork-testing (in build file:/C:/dev/sandbox/fork-testing/)
[info] Running Hello
[info] Hello, Chad
runMain is no different from run in this case.
$ sbt 'set envVars := Map("msg" -> "Hello, Chad")' 'runMain Hello'
[info] Set current project to fork-testing (in build file:/C:/dev/sandbox/fork-testing/)
[info] Defining *:envVars
[info] The new value will be used by *:runner, compile:run::runner and 1 others.
[info] Run `last` for details.
[info] Reapplying settings...
[info] Set current project to fork-testing (in build file:/C:/dev/sandbox/fork-testing/)
[info] Running Hello
[info] Hello, Chad
If you're trying to set SBT properties, like plugin settings, then the above won't work (AFAICT) as of 0.13+ in my experience. The following however did work, when trying to pass in Liquibase settings, like password, from our CI frameworks.
In your build.sbt
Ugly, but supplies defaults, and optionally grabs from System.properties. This way you've got your default and override cases covered.
def sysPropOrDefault(propName:String,default:String):String = Option(System.getProperty(propName)).getOrElse(default)
liquibaseUsername := sysPropOrDefault("liquibase.username","change_me")
liquibasePassword := sysPropOrDefault("liquibase.password","chuck(\)orris")
From the commandline
Now just override via -Dprop=value like you would with Maven or other JVM programs. Note props appear before SBT task.
sbt -Dliquibase.password="shh" -Dliquibase.username="bob" liquibase:liquibase-update
I'm running compile test:compile it:compile quite often and...would like to cut the number of keystrokes to something like *:compile. It doesn't seem to work, though.
$ sbt *:compile
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Loading project definition from /Users/jacek/oss/scalania/project
[info] Set current project to scalania (in build file:/Users/jacek/oss/scalania/)
[error] No such setting/task
[error] *:compile
[error] ^
Is it possible at all? I use SBT 0.13.
test:compile implies a compile so compile doesn't need to be explicitly run before test:compile. If your IntegrationTest configuration extends Test, it:compile implies test:compile.
One option is to define an alias that executes multiple commands:
sbt> alias compileAll = ; test:compile ; it:compile
See help alias and help ; for details. You can make this a part of your build with:
addCommandAlias("compileAll", "; test:compile ; it:compile")
The other option is to define a custom task that depends on the others and call that:
lazy val compileAll = taskKey[Unit]("Compiles sources in all configurations.")
compileAll := {
val a = (compile in Test).value
val b = (compile in IntegrationTest).value
()
}