How to disable specific plugins for generated source code in sbt? [duplicate] - sbt

I generate code with the scalaxb-sbt plugin that, when compiled, generates a good number of warning messages. Is there any way to hide compilation warnings for generated code or by package?

The silencer compiler plugin allows to suppress compiler warnings. It supports filtering out files by path. This will filter out all generated files from warnings:
scalacOptions += "-P:silencer:pathFilters=src_managed"

For Scala 2.12.13+ or 2.13.2+
Recent versions of the Scala compiler integrate the silencer plugin, see configurable warnings.
So now you don't need any plugin, just add the following line to build.sbt:
ThisBuild / scalacOptions += "-Wconf:src=src_managed/.*:silent"
Using this option will suppress warnings for generated code that lives under a directory called src_managed anywhere in your source tree.
This solved my problem with code generated by zio-grpc, where the compiler emitted warnings like parameter value evidence$3 in method live is never used (adding this info only for better searchability).

In your sbt console you could try the following:
set logLevel in compile := Level.Error or eventually set logLevel in sourceGenerators := Level.Error
and experiment with different settings. Once you are happy you could apply this setting in your build.sbt.
More detailed information can be found in the sbt documentation: http://www.scala-sbt.org/release/docs/Howto/logging.html

I found that I needed to do set logLevel in Compile := Level.Error in my sbt console session in order for this to work. This is with a capital C in Compile. This is with sbt version 0.13.11. This is also to turn all warnings off, though.

Put the code in a subproject, and set scalacOptions differently in that project? Whether this will work depends on whether the support even exists in scalac for suppressing the particular kind of warning you are getting. See for example https://issues.scala-lang.org/browse/SI-1781 . What kind of warnings are you needing to suppress exactly? Certain warnings like unchecked warnings can be suppressed with e.g. #unchecked without having to do the subproject thing.

Related

Execute sbt task without prior compiling (for generating database classes with JOOQ)

I have a PlayFramework 2.7 application which is build by sbt.
For accessing the database, I am using JOOQ. As you know, JOOQ reads my database schema and generates the Java source classes, which then are used in my application.
The application only compiles, if the database classes are present.
I am generating the classes with this custom sbt task:
// https://mvnrepository.com/artifact/org.jooq/jooq-meta
libraryDependencies += "org.jooq" % "jooq-meta" % "3.12.1"
lazy val generateJOOQ = taskKey[Seq[File]]("Generate JooQ classes")
generateJOOQ := {
(runner in Compile).value.run("org.jooq.codegen.GenerationTool",
(fullClasspath in Compile).value.files,
Array("conf/db.conf.xml"),
streams.value.log).failed foreach (sys error _.getMessage)
((sourceManaged.value / "main/generated") ** "*.java").get
}
I googled around and found the script above and modified it a little bit according to my needs, but I do not really understand it, since sbt/scala are new to me.
The problem now is, when I start the generateJOOQ, sbt tries to compile the project first, which fails, because the database classes are missing. So what I have to do is, comment all code out which uses the generated classes, execute the task which compiles my project, generates the database classes and then enable the commented out code again. This is a pain!
I guess the problem is the command (runner in Compile) but I did not find any possibility to execute my custom task WITHOUT compiling first.
Please help! Thank you!
Usually, when you want to generate sources, you should use a source generator, see https://www.scala-sbt.org/1.x/docs/Howto-Generating-Files.html
sourceGenerators in Compile += generateJOOQ
Doing that automatically causes SBT to execute your task first before trying to compile the Scala/Java sources.
Then, you should not really use the runner task, since that is used to run your project, which depends on the compile task, which needs to execute first of course.
You should add the jooq-meta library as a dependeny of the build, not of your sources. That means you should add the libraryDependencies += "org.jooq" % "jooq-meta" % "3.12.1" line e.g. to project/jooq.sbt.
Then, you can simply call the GenerationTool of jooq just as usually in your task:
// build.sbt
generateJOOQ := {
org.jooq.codegen.GenerationTool.main(Array("conf/db.conf.xml"))
((sourceManaged.value / "main/generated") ** "*.java").get
}

Why does Play build give "No trace dependencies for Activator" after adding plugins?

I started with the latest Typesafe Activator download using the play-scala template.
Activator 1.2.10
Akka 2.3.4
Play 2.3.4
Scala 2.11.1
Then I modified build.sbt file to add play2-reactivemongo with
"org.reactivemongo" % "play2-reactivemongo_2.11" % "0.10.5.akka23-SNAPSHOT"
, but it failed with No trace dependencies for Activator.
I removed play2-reactivemongo and tried play-silhouette and received the same error.
"com.mohiva" % "play-silhouette_2.11" % "1.1-SNAPSHOT"
The app builds with neither plugin added.
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.1"
resolvers += "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"
libraryDependencies ++= Seq(
// "com.mohiva" % "play-silhouette_2.11" % "1.1-SNAPSHOT",
// "org.reactivemongo" % "play2-reactivemongo_2.11" % "0.10.5.akka23-SNAPSHOT",
jdbc,
anorm,
cache,
ws
)
The output from Play Framework tells me nothing beyond that one line as best I can tell. Maybe there is better information leading to a solution, but I have not been able to find it. Any ideas?
CORRECTION: now when I disable the resolver line, disable the play-silhouette line, and disable the reactivemongo line, the same error message appears. Yet, it once compiled successfully.
The error is from the sbt-echo plugin here:
https://github.com/typesafehub/sbt-echo/blob/3f431a9748a45fcb328efe4d5f989a99b5c8f7f2/akka/src/main/scala/com/typesafe/sbt/echo/EchoRun.scala#L95
I improved this error message just the other day, incidentally, but you don't have it yet:
https://github.com/typesafehub/sbt-echo/blob/master/akka/src/main/scala/com/typesafe/sbt/echo/EchoRun.scala#L118
activator's ui mode (activator ui) adds the sbt-echo plugin in order to power the Inspect tab. You can remove the plugin again (by deleting the .sbt file for it in project/) if you are not currently using UI mode, to fix this.
If you are using UI mode, to fix this you need akka and play to have versions which are understood by sbt-echo. This may mean downgrading to 2.3.3 for now, we are a little behind on updating the tracing.

SBT console encoding for test results

I have an SBT + Scalatest project. Now my tests log in console something like this:
[info] - should do something *** FAILED ***
[info] java.lang.Exception: ╧ЁштхЄ!
That's not very useful of cause.. Exception text is in Cyrillic so I have to set cp866 charset on console stream to display it correctly.
I've tried
Console.setOut(new PrintStream(System.out, true, "cp866"))
But SBT ignores it. It seems that SBT constructs it's own stream for logging various messages, but I can't find where and how to alter it..
There is a way to add custom logger, but it's an overkill.
I've found a solution.
I can create a custom LogManager
val customLogManager = LogManager.defaultManager(ConsoleOut.printStreamOut(new java.io.PrintStream(System.out, true, "cp866")))
And set it in project settings:
logManager := customLogManager
Though, I'm not sure if it is the best solution. One flaw is that you have to provide logManager setting for every project. Inheriting it from build settings doesn't work for some reason.

"include_recipe" vs. Vagrantfile "chef.add_recipe". What's the difference?

Just ran nginx::source recipe on my vagrant box, and I have very unusual behaviour.
When I include a recipe from the Vagrantfile (as below), everything works like a charm,
chef.add_recipe("project::nginx")
chef.add_recipe("nginx::source")
(project::nginx recipe is very simple. Using it to override default attributes of the nginx cookbook)
but if I include a recipe at the very end of project::nginx (mentioned up), everything falls apart:
node.default['nginx']['server_names_hash_bucket_size'] = 128
include_recipe "nginx::source"
Until now I didn't know there's any difference in behaviour between those two invocations. Does anybody here knows what's the difference?
Gotya! Chef 11 feature. Issue with it exist in chef-solo solely :)
To make a quick resume, difference is:
chef.add_recipe() - loads entire cookbook context (all the files, e.g. recipes, definitions, attributes...)
include_recipe "" - files(attributes, definitions etc.) that are not in the expended run list are not loaded.
There are at least 4 ways to solve the issue(put files in the run list):
include_attribute - include desired attribute file explicitly.
metadata.rb->dependency - if your cookbook is using recipe from another cookbook, put that cookbook in metadata.rb's dependency section, and all it's files will be loaded.
chef.add_recipe() - Load recipe via Vagrantfile. (Mentioned here just for reference)
Berkshelf - you may use this cookbook manager to solve the issue as well. Here's the Stackoverflow thread about this exact problem and some Docs
For those who are interested in further reading, Chef 11 introduced dependency-based cookbook loading for non-recipe files. The new loading logic means that files belonging to cookbooks which exist in the cookbook_path but are not in the expanded run_list or dependencies of the cookbooks in the expanded run_list will no longer be loaded. REF: Opscode breaking changes documentation, and if you need a signature of the error I got, here's the exactly same one, even for the same cause.

How do you do develop an SBT project, itself?

Background: I've got a Play 2.0 project, and I am trying to add something to do aspectj weaving using aspects in a jar on some of my classes (Java). (sbt-aspectj doesn't seem to do it, or I can't see how). So I need to add a custom task, and have it depend on compile. I've sort of figured out the dependency part. However, because I don't know exactly what I'm doing, yet, I want to develop this using the IDE (I'm using Scala-IDE). Since sbt projects (and therefore Play projects) are recursively defined, I assumed I could:
Add the eclipse plugin to the myplay/project/project/plugins.sbt
Add the sbt main jar (and aspectj jar) to myplay/project/project/build.sbt:
libraryDependencies ++= Seq(
"org.scala-sbt" % "main" % "0.12.2",
"aspectj" % "aspectj-tools" % "1.0.6"
)
Drop into the myplay/project
Run sbt, run the eclipse task, then import the project into eclipse as a separate project.
I can do this, though the build.scala (and other scala files) aren't initially considered source, and I have to fiddle with the build path a bit. However, even though I've got the sbt main defined for the project, both eclipse IDE and the compile task give errors:
> compile
[error] .../myplay/project/Build.scala:2: not found: object keys
[error] import keys.Keys._
[error] ^
[error] .../myplay/project/SbtAspectJ.scala:2: object Configurations is not a member of package sbt
[error] import sbt.Configurations.Compile
[error] ^
[error] .../myplay/project/SbtAspectJ.scala:3: object Keys is not a member of package sbt
[error] import sbt.Keys._
[error] ^
[error] three errors found
The eclipse project shows neither main nor aspectj-tools in its referenced-libraries. However, if I give it a bogus version (e.g. 0.12.4), reload fails, so it appears to be using
the dependency.
So,...
First: Is this the proper way to do this?
Second: If so, why aren't the libs getting added.
(Third: please don't let this be something dumb that I missed.)
If you are getting the object Keys is not a member of package sbt error, then you should check that you are running sbt from the base directory, and not the /project directory.
sbt-aspectj
sbt-aspectj doesn't seem to do it, or I can't see how.
I think this is the real issue. There's a plugin already that does the work, so try making it work instead of fiddling with the build. Using plugins from build.scala is a bit tricky.
Luckily there are sample projects on github:
import sbt._
import sbt.Keys._
import com.typesafe.sbt.SbtAspectj.{ Aspectj, aspectjSettings, compiledClasses }
import com.typesafe.sbt.SbtAspectj.AspectjKeys.{ binaries, compileOnly, inputs, lintProperties }
object SampleBuild extends Build {
....
// precompiled aspects
lazy val tracer = Project(
"tracer",
file("tracer"),
settings = buildSettings ++ aspectjSettings ++ Seq(
// stop after compiling the aspects (no weaving)
compileOnly in Aspectj := true,
// ignore warnings (we don't have the sample classes)
lintProperties in Aspectj += "invalidAbsoluteTypeName = ignore",
// replace regular products with compiled aspects
products in Compile <<= products in Aspectj
)
)
}
How do you do develop an SBT project, itself?
If you're interested in hacking on the build still the first place to go is the Getting Started guide. Specifically, your question should be answered in .scala Build Definition page.
I think you want your build to utilize "aspectj" % "aspectj-tools" % "1.0.6". If so it should be included in myplay/project/plugins.sbt, and your code should go into myplay/project/common.scala or something. If you want to use IDE, you have have better luck with building it as a sbt plugin. That way your code would go into src/main/scala. Check out sbt/sbt-aspectj or sbt/sbt-assembly on example of sbt plugin structure.

Resources