I have a multi project sbt build and I would like to use https://github.com/softprops/coffeescripted-sbt to compile my coffeescript to javascript, but it is not performing the tasks.
The code was taken from https://github.com/jeffmay/angular-play-multimodule-seed/tree/stackoverflow-17289043
With build.sbt
Even though it is not recommended, I mixed a build.sbt file in the project directory with my project objects in order to test if this plugin worked.
In build.sbt:
seq(coffeeSettings: _*)
When I ran:
$ sbt
[info] Loading project definition from /Users/jeffmay/code/righttrack/project
[info] Set current project to root (in build file:/Users/jeffmay/code/righttrack/)
> coffee
[success] Total time: 0 s, completed Jun 24, 2013 11:40:37 PM
> show coffee
[info] ArrayBuffer()
[success] Total time: 0 s, completed Jun 24, 2013 11:40:52 PM
> project web
[info] Set current project to web (in build file:/Users/jeffmay/code/righttrack/)
[web] $ coffee
[error] Not a valid command: coffee
[error] No such setting/task
[error] coffee
[error] ^
[web] $
What does ArrayBuffer() mean? Is that a silent failure (coffeescript returning the last expression that would otherwise be a return; of null?)
Multi Project Setup
For some context, my build is broken out like so...
In project/plugins.sbt:
// SBT community plugin resolver
resolvers += Resolver.url("sbt-plugin-releases",
new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
// CoffeeScript compiler plugin
addSbtPlugin("me.lessis" % "coffeescripted-sbt" % "0.2.3")
In project/Modules.scala (my build object):
import sbt._
object Modules extends Build {
lazy val root = RootModule.project
lazy val api = ApiModule.project
lazy val web = WebModule.project
}
In the project/WebModule.scala:
object WebModule extends BaseModule {
// ... libraries dependencies and stuff
override def project = play.Project(moduleName, moduleVersion, libraries, file(location),
moduleSettings ++
Seq((resourceManaged in (Compile, CoffeeKeys.coffee)) <<= (crossTarget in Compile)(_ / "src" / "main" / "coffee"))
)
}
I use a project/BaseModule.scala to remove the clutter of the common elements of each module, but it isn't doing anything fancy.
With Build.scala
I remove the build.sbt stuff and put it into Build.scala via project/WebModule.scala by adding:
override def project = play.Project(moduleName, moduleVersion, libraries, file(location),
moduleSettings ++
coffeeSettings ++ // With the settings moved from build.sbt
Seq((resourceManaged in (Compile, CoffeeKeys.coffee)) <<= (crossTarget in Compile)(_ / "src" / "main" / "coffee"))
)
Then I give it a whirl
$ sbt
[info] Loading project definition from /Users/jeffmay/code/righttrack/project
[info] Set current project to root (in build file:/Users/jeffmay/code/righttrack/)
> coffee
[error] Not a valid command: coffee
[error] No such setting/task
[error] coffee
[error] ^
> project web
[info] Set current project to web (in build file:/Users/jeffmay/code/righttrack/)
[web] $ coffee
[success] Total time: 0 s, completed Jun 25, 2013 12:08:36 AM
[web] $ show coffee
[info] ArrayBuffer()
[success] Total time: 0 s, completed Jun 25, 2013 12:08:40 AM
I'm not seeing any changes after running the coffee command. Any ideas what the problem is?
Thanks!
See my dialog with softprops for more details: https://github.com/softprops/coffeescripted-sbt/issues/17
There were three problems with and one improvement to the code above.
I wasn't aggregating my web project into the root project.
I wasn't setting where to find the coffee script files.
Play uses "./app" as the sourceDirectory, so when I added the seemingly "correct" directory path of
sourceDirectory in (Compile, CoffeeKeys.coffee) <<= sourceDirectory { _ / "main" / "coffee" }
It was searching in "./app/src/main/coffee", which doesn't exist
I was able to improve this example by having the compiler manage the ./public directory, so that it could drop the compiled javascript sources in the recommended public/js directory for the Angular Seed Project.
You can see the full seed project example here: https://github.com/jeffmay/angular-play-multimodule-seed
Related
I have a project which I publish locally to my .m2 directory as a plugin, which later I need to import into a different Scala project and use it.
It seems like the publishing step is executed correctly.
The build.sbt file of the plugin project looks like this:
lazy val root = (project in file("."))
.enablePlugins(SbtPlugin)
.settings(
name := "pluginName",
organization := "com.myOrg",
pluginCrossBuild / sbtVersion := {
scalaBinaryVersion.value match {
case "2.12" => "1.4.6" // set minimum sbt version
}
}
)
resolvers += "confluent" at "https://packages.confluent.io/maven"
libraryDependencies ++= Seq(
"io.confluent" % "kafka-schema-registry-client" % "7.0.1"
// some other dependemcies
)
After running the compile and publishLocal commands in sbt shell I get the next message:
[info] delivering ivy file to /Users/me/Work/repos/external/pluginName/target/scala-2.12/sbt-1.0/ivy-1.0.0.xml
[info] published pluginName to /Users/me/.ivy2/local/com.myOrg/pluginName/scala_2.12/sbt_1.0/1.0.0/poms/pluginName.pom
[info] published pluginName to /Users/me/.ivy2/local/com.myOrg/pluginName/scala_2.12/sbt_1.0/1.0.0/jars/pluginName.jar
[info] published pluginName to /Users/me/.ivy2/local/com.myOrg/pluginName/scala_2.12/sbt_1.0/1.0.0/srcs/pluginName-sources.jar
[info] published pluginName to /Users/me/.ivy2/local/com.myOrg/pluginName/scala_2.12/sbt_1.0/1.0.0/docs/pluginName-javadoc.jar
[info] published ivy to /Users/me/.ivy2/local/com.myOrg/pluginName/scala_2.12/sbt_1.0/1.0.0/ivys/ivy.xml
[success] Total time: 0 s, completed 3 Jan 2022, 10:07:43
In order to import/install this plugin in the other Scala project, I have added the next line to the plugins.sbt file: addSbtPlugin("com.myOrg" % "pluginName" % "1.0.0")
I also added libs-release-local and libs-snapshot-local to the externalResolvers section in the buid.sbt file.
After reloading and compiling the project I received this error:
[error] (update) sbt.librarymanagement.ResolveException: Error downloading io.confluent:kafka-schema-registry-client:7.0.1
[error] Not found
[error] Not found
[error] not found: https://repo1.maven.org/maven2/io/confluent/kafka-schema-registry-client/7.0.1/kafka-schema-registry-client-7.0.1.pom
[error] not found: /Users/me/.ivy2/local/io.confluent/kafka-schema-registry-client/7.0.1/ivys/ivy.xml
[error] not found: https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/io.confluent/kafka-schema-registry-client/7.0.1/ivys/ivy.xml
[error] not found: https://repo.typesafe.com/typesafe/ivy-releases/io.confluent/kafka-schema-registry-client/7.0.1/ivys/ivy.xml
I am kind of new to Scala and I don't understand what and I doing wrong.
Can anyone shed some light on this problem?
You're publishing to your local Maven cache, but sbt uses Ivy.
Try removing the publishTo setting, it shouldn't be needed. Just use the publishLocal task to publish to your local Ivy cache.
I am using sbt version 1.0
$ sbt version
[info] Loading project definition from /Users/harit/code/learningScala/project
[info] Set current project to learningScala (in build file:/Users/harit/code/learningScala/)
[info] 1.0
I am using IntelliJ IDEA v14.1.3 for my project and the structure looks like
As you may see that project was not able to resolve Build. When I try command-line to run sbt, I see
$ sbt
[info] Loading project definition from /Users/harit/code/learningScala/project
[info] Set current project to learningScala (in build file:/Users/harit/code/learningScala/)
> compile
[info] Updating {file:/Users/harit/code/learningScala/}learningscala...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/harit/code/learningScala/target/scala-2.11/classes...
[error] /Users/harit/code/learningScala/Build.scala:1: not found: object sbt
[error] import sbt.Build
[error] ^
[error] /Users/harit/code/learningScala/Build.scala:3: not found: type Build
[error] object MyBuild extends Build {
[error] ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 2 s, completed May 28, 2015 8:10:37 PM
>
I am very new to Scala, sbt so no idea what is going wrong with it
The MyBuild.scala was at root. It should be inside project folder. I made that change and now it works. Thanks to tpolecat on IRC who helped me with this
> compile
[success] Total time: 0 s, completed May 28, 2015 8:20:57 PM
> compile
[info] Updating {file:/Users/harit/code/learningScala/}learningscala...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[success] Total time: 0 s, completed May 28, 2015 8:21:22 PM
>
I have a multi-project sbt build, and two of the projects were declaring two of the same val in their build.sbt files. I moved the duplicated val (s) to the Build.scala in the root project as def, and error stopped. Found the answer here: https://github.com/sbt/sbt/issues/1465
example: val samza_gid = "org.apache.samza" in build.sbt file became
def samza_gid = "org.apache.samza" in the Build.scala file.
I have two sbt plugin projects that both use multi-project builds. I would like to use one of the plugins as a dependency for the other. I was able to get this working with single project builds, but once I move to the multi-project build, I can't seem to get the dependencies to link up correctly.
my-test-plugin
build.sbt
lazy val commonSettings = Seq(
organization := "com.example",
name := "my-test-plugin",
version := "0.1.0-SNAPSHOT",
scalaVersion := "2.10.5"
)
// The contents of root are largely unimportant here
lazy val root = (project in file(".")).settings(commonSettings: _*)
lazy val plugin = (project in file("plugin"))
.settings(commonSettings: _*)
.settings(
sbtPlugin := true
)
my-test-plugin/plugin/src/main/scala/PluginTest.scala
package com.example.test
// Sample code I would like to access from another plugin
object PluginTest {
def foo: Unit = println("test")
}
my-sub-plugin
build.sbt
lazy val commonSettings = Seq(
organization := "com.sample",
name := "my-sub-plugin",
version := "0.1.0-SNAPSHOT",
scalaVersion := "2.10.5"
)
lazy val root = (project in file(".")).settings(commonSettings: _*)
lazy val plugin = (project in file("plugin"))
.settings(commonSettings: _*)
.settings(
sbtPlugin := true,
libraryDependencies += Defaults.sbtPluginExtra("com.example" % "my-test-plugin" % "0.1.0-SNAPSHOT", "0.13", "2.10")
).dependsOn(root)
my-sub-plugin/plugin/src/main/scala/SubPluginTest.scala
package com.sample.test
object SubPluginTest {
def bar = com.example.test.PluginTest.foo
}
But the last file doesn't compile:
[error] /home/mike/code/sbt-tests/my-sub-plugin/plugin/src/main/scala/SubPluginTest.scala:4: object example is not a member of package com
[error] def bar = com.example.test.PluginTest.foo
[error] ^
When I publish-local and plugin/publish-local both projects (rather, just compile the second), the artifacts resolve correctly, but SubPlugintest.scala fails to compile with the above error, as if the dependency isn't there. However, if I remove the root projects and put the plugin files in root (without lazy vals or anything, just a flat build.sbt structure), it works.
What am I missing here?
I don't think it's relevant, but I tried 0.13.5 and 0.13.8. I've also fruitlessly tried adding the dependency without sbtPluginExtra, and putting them in plugins.sbt as well (I didn't think that would work, but hey).
Edit:
The dependency jars appear exist locally and resolve correctly:
$ jar tf ~/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/jars/my-test-plugin.jar
META-INF/MANIFEST.MF
com/
com/example/
com/example/test/
com/example/test/PluginTest$.class
com/example/test/PluginTest.class
$ jar tf ~/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/jars/my-test-plugin_2.10.jar
META-INF/MANIFEST.MF
com/
com/example/
com/example/test/
com/example/test/DummyCode.class
com/example/test/DummyCode$.class
You're not setting a distinct name for each module:
my-test-plugin
> ;show root/name ;show plugin/name
[info] my-test-plugin
[info] my-test-plugin
my-sub-plugin
> ;show root/name ;show plugin/name
[info] my-sub-plugin
[info] my-sub-plugin
As you can see, publishing in my-test-plugin works:
> ;root/publishLocal ;plugin/publishLocal
[info] Wrote /Users/dnw/Desktop/sbt-tests/my-test-plugin/target/scala-2.10/my-test-plugin_2.10-0.1.0-SNAPSHOT.pom
[info] :: delivering :: com.example#my-test-plugin_2.10;0.1.0-SNAPSHOT :: 0.1.0-SNAPSHOT :: integration :: Sat Apr 11 09:16:15 BST 2015
[info] delivering ivy file to /Users/dnw/Desktop/sbt-tests/my-test-plugin/target/scala-2.10/ivy-0.1.0-SNAPSHOT.xml
[info] published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/poms/my-test-plugin_2.10.pom
[info] published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/jars/my-test-plugin_2.10.jar
[info] published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/srcs/my-test-plugin_2.10-sources.jar
[info] published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/docs/my-test-plugin_2.10-javadoc.jar
[info] published ivy to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/ivys/ivy.xml
[success] Total time: 0 s, completed 11-Apr-2015 09:16:15
[info] Wrote /Users/dnw/Desktop/sbt-tests/my-test-plugin/plugin/target/scala-2.10/sbt-0.13/my-test-plugin-0.1.0-SNAPSHOT.pom
[info] :: delivering :: com.example#my-test-plugin;0.1.0-SNAPSHOT :: 0.1.0-SNAPSHOT :: integration :: Sat Apr 11 09:16:15 BST 2015
[info] delivering ivy file to /Users/dnw/Desktop/sbt-tests/my-test-plugin/plugin/target/scala-2.10/sbt-0.13/ivy-0.1.0-SNAPSHOT.xml
[info] published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/poms/my-test-plugin.pom
[info] published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/jars/my-test-plugin.jar
[info] published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/srcs/my-test-plugin-sources.jar
[info] published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/docs/my-test-plugin-javadoc.jar
[info] published ivy to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/ivys/ivy.xml
[success] Total time: 0 s, completed 11-Apr-2015 09:16:15
But note the publish paths:
com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/jars/my-test-plugin_2.10.jar
com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/jars/my-test-plugin.jar
A non-sbt-plugin called my-test-plugin cross-built for Scala 2.10.
An sbt-plugin called my-test-plugin, cross-built for Scala 2.10 and sbt 0.13.
This has an impact when trying to resolve my-test-plugin in my-sub-plugin:
[error] Modules were resolved with conflicting cross-version suffixes in {file:/Users/dnw/Desktop/sbt-tests/my-sub-plugin/}root:
[error] com.example:my-test-plugin <none>, _2.10
java.lang.RuntimeException: Conflicting cross-version suffixes in: com.example:my-test-plugin
at scala.sys.package$.error(package.scala:27)
at sbt.ConflictWarning$.processCrossVersioned(ConflictWarning.scala:46)
at sbt.ConflictWarning$.apply(ConflictWarning.scala:32)
Try and specify different names for each module and it should work.
WartRemover is a scalac plugin. Typically it is configured via an sbt plugin.
I'd like to be able to run WartRemover on my sbt project as a separate configuration or task without affecting the usual run of compile.
After adding Wartremover to my plugins.sbt I tried quite a few variations on the following.
lazy val Lint = config("lint").extend(Compile)
project("foo").
configs(Lint)
settings(inConfig(Lint)(Defaults.compileSettings): _*).
settings(inConfig(Linting)(wartremover.wartremoverSettings):_*).
settings(inConfig(Linting)(wartremover.wartremoverErrors := wartremover.Warts.all))
Afterward scalacOptions contained roughly what I expected inside my new lint configuration and in the compile configuration. However, when I ran lint:compile and compile with sbt in debug mode so I could see the command line arguments to scalac, either both or neither commands would result in pass the -P:wartremover:... switches. That was surprising because only lint:scalacOptions showed the -P:wartremover:... switches.
How can I create a separate sbt Configuration or Task to compile with WartRemover without affecting compile:compile?
I think you came really close. Here are some of the details:
sbt downloads library dependencies and compiler plugins all using Compile configuration's update task, which uses libraryDependencies setting. addCompilerPlugin is a shorthand for libraryDependencies with CompilerPlugin configuration.
Compiler plugin requires scalaOptions on the configuration that you're interested in.
You need to grab sources from Compile to use them in Lint.
If you see the implementation of wartremoverSettings it's doing both addCompilerPlugin and scalacOptions. You have two options to disable wartremover on Compile:
Use auto plugin (requires sbt 0.13.5+) to inject wartremoverSettings, then manually remove wartremover compiler plugin from Compile.
Disable auto plugin, then manually add wart remover into libraryDependencies.
Here's the first option.
project/build.properties
sbt.version=0.13.7
project/wart.sbt
addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.11")
build.sbt
lazy val Lint = config("lint") extend Compile
lazy val foo = project.
configs(Lint).
settings(inConfig(Lint) {
Defaults.compileSettings ++ wartremover.wartremoverSettings ++
Seq(
sources in Lint := {
val old = (sources in Lint).value
old ++ (sources in Compile).value
},
wartremover.wartremoverErrors := wartremover.Warts.all
) }: _*).
settings(
scalacOptions in Compile := (scalacOptions in Compile).value filterNot { _ contains "wartremover" }
)
foo/src/main/scala/Foo.scala
package foo
object Foo extends App {
// Won't compile: Inferred type containing Any
val any = List(1, true, "three")
println("hi")
}
sample output
foo> clean
[success] Total time: 0 s, completed Dec 23, 2014 9:43:30 PM
foo> compile
[info] Updating {file:/quick-test/wart/}foo...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /quick-test/wart/foo/target/scala-2.10/classes...
[success] Total time: 1 s, completed Dec 23, 2014 9:43:33 PM
foo> run
[info] Running foo.Foo
hi
[success] Total time: 0 s, completed Dec 23, 2014 9:43:37 PM
foo> lint:compile
[info] Compiling 1 Scala source to /quick-test/wart/foo/target/scala-2.10/lint-classes...
[error] /quick-test/wart/foo/src/main/scala/Foo.scala:5: Inferred type containing Any
[error] val any = List(1, true, "three")
[error] ^
[error] /quick-test/wart/foo/src/main/scala/Foo.scala:5: Inferred type containing Any
[error] val any = List(1, true, "three")
[error] ^
I've got a multi-project build with scalania main project as well as exercises and answers (sub)projects.
The scalania project is hosted on GitHub.
I'm trying to set up a SBT project configuration where the test classes are part of the exercises project while the answers project provides the solutions.
I read Per-configuration classpath dependencies in the official documentation of SBT and ended up with the following configuration in the scalania main project:
lazy val exercises = project
lazy val answers = project.dependsOn(exercises % "test->test")
It doesn't seem to work and upon test execution I used to get:
> project answers
[info] Set current project to scalania-answers (in build file:/Users/jacek/oss/scalania/)
> test
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for answers/test:test
[success] Total time: 1 s, completed Oct 27, 2013 1:06:51 AM
It was until I changed answers/build.sbt to the following:
scalaSource in Test := (scalaSource in LocalProject("exercises") in Test).value
It works fine now.
> reload
[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-answers (in build file:/Users/jacek/oss/scalania/)
> project answers
[info] Set current project to scalania-answers (in build file:/Users/jacek/oss/scalania/)
> testOnly *s99.P01*
[info] Formatting 19 Scala sources {file:/Users/jacek/oss/scalania/}answers(test) ...
[info] Compiling 19 Scala sources to /Users/jacek/oss/scalania/answers/target/scala-2.10/test-classes...
[info] P01Spec
[info]
[info] P01 solution should
[info] + Find the last element of a list
[info]
[info]
[info] Total for specification P01Spec
[info] Finished in 151 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 74 s, completed Oct 27, 2013 1:09:07 AM
What's wrong with using project.dependsOn(exercises % "test->test") only? Am I missing something in the build configuration?
Declaring a dependency on tests in another project just makes the classpath available. Running its tests doesn't happen by default because otherwise tests would run multiple times in the common situation of just reusing code.
To run tests in another project, add the discovered tests from the other project to those for the current project:
definedTests in Test :=
(definedTests in Test).value ++
(definedTests in exercises in Test).value