Custom sbt configuration with Intellij auto import - scala

I can't get the embedded sbt plugin (with auto import enabled) in Intellij (13.1) to recognize custom sbt configurations. I have the follow setup in my sbt build file:
lazy val EndToEndTest = config("e2e") extend (Test)
private lazy val e2eSettings =
inConfig(EndToEndTest)(Defaults.testSettings)
lazy val root: Project = Project(
id = "root",
base = file(".")
)
.configs(EndToEndTest)
.settings(e2eSettings)
The code works according to expectations in the sbt console. E.g I can write:
sbt e2e:test (and it will execute tests located in /src/e2e/scala)
The issue is that the directory /src/e2e/scala won't get registered as a source directory in Intellij. This makes it hard to use intellij to manage the tests. I can manually mark the directory as source but it gets reverted every time
I update my sbt files (auto import).
Do a manual update through the sbt tool window
Related:
Using the preconfigured configuration IntegrationTest works as expected but custom once don't.

According to sbt-idea documentation this can be done in your case by adding
ideaExtraTestConfigurations := Seq(EndToEndTest)
to your project settings.

Related

Mutli-projects build with gradle like sbt

I'm basically a scala developer and i have project in scala - sbt recently i've started using kotlin and trying to some parts of my code in to kotlin. I need help in understanding gradle build system.
db-service
queue-service
business-logic
processor-code depends on projects on db-service, queue-service and business logic
another project "X" depends on queue-service and some other service.
Usually in sbt this is something very straight forward you can use ProjectRef to include these projects as dependencies.
How do i achieve the same with gradle? Thanks in advance
//Update
sample build.sbt
lazy val buildSettings = Seq(
scalaVersion := "2.12",
fork in Test := true,
fork in IntegrationTest := true,
...
)
lazy val root = Project("processor-code", file("."))
.settings(buildSettings: _*)
.settings(
libraryDependencies ++= //Deps
)
.dependsOn(db-service, queue-service, utilities)
.aggregate(db-service, queue-service, utilities)
lazy val db-service = ...
lazy val queue-service = Project("queue-service", file(".")).settings()...
lazy val utilities = ProjectRef(file("../utilities"), "utilities")
i have tried including the project in settings.gradle
include 'project'
project(":project").projectDir = "../myProject"
and added
implementation(project(":project"))
however, it doesn't seem working show error plugin already on classpath, then i've also tried creating a submodule and it seemed like it was working but when i was trying to run it throws a initialization exception
i've understood that we can configure a project in the following scenario
Root project: (contains common build.gradle)
| - subproject A
| - subproject B
| - myapp
now myapp easily can depend on subprojects
My scenario (no common build.gradle, each project will have its own build.gradle)
| Independent project A
| Independent project B
| my app
While it's true that you can only depend on other sub-projects, technically, that's still possible with Gradle.
Since project A is a Gradle project, you could pack it with gradle jar command. Then you could move the produced JAR to wherever you want, but probably to your my app project.
Now it's possible to launch an arbitrary command from Gradle using project.exec {}
What's more, you can even write your own Kotlin/Groovy function inside Gradle to do that for you.
That's what SBT is doing for you, actually.

Running multi-project sbt project results in clobbered compilation of shared project

I have a play application and a normal scala application that have shared code in a dependency defined as such:
project A
project B
shared
lazy val shared = (project in file("shared")).settings(...)
lazy val projectA = (project in file("A")).settings(...).dependsOn(shared)
lazy val projectB = (project in file("B")).settings(...).dependsOn(shared)
Due to the way sbt handles triggered execution, running sbt ~run in development mode is not usable for handling file changes correctly. I'm also using sbt-revolver to handle re-running the non-play application. As a result, I run both applications separately using the commands:
sbt 'project A' '~run'
sbt 'project B' '~reStart'
in parallel, so when I make a change to shared, both try to recompile it, and therefore sometimes result in an error. I frankly despise SBT's documentation, and cannot figure out how to get this to work within SBT, so I am asking for help.

Disable an AutoPlugin from the sbt command line

I'm using a Scalariform AutoPlugin and would like to disable it when running tests on the CI server. Is there a sbt option to do so?
One way to achieve this is via an environment variable. Please note in my example Code below I use the sbt-release plugin but it should be easily adoptable to scalariform.
lazy val isJenkins = sys.props.get("JENKINS").isDefined
lazy val disPlugins = if(isJenkins) Seq(ReleasePlugin) else Seq.empty
lazy val root = (project in file(".")).disablePlugins(disPlugins:_*)
The first val checks if we the system property JENKINS is set. Depending on this value we add the ReleasePlugin to the Sequence of Plugins that need to be disabled. And finally during our project definition we actually disable those.
If you start sbt with the jenkins property set (sbt -DJENKINS=true) the ReleasePlugin is disabled

sbt auto-plugins - disable them but for one sub project

Switching sbt-assembly from 0.11.2 to 0.13.0, I suddenly find myself in a situation where calling sbt assembly does not just invoke the task in the sub-project that explicitly added assemblySettings, but it tries to run it for each and every sub project.
So, if I have
lazy val root = project(...).aggregate(core, app)
lazy val core = project(...)
lazy val app = project(...).dependsOn(core)
How can I disable the assembly task for all but the root project? With other plugins such as sbt-buildinfo this problem doesn't occur because you have to explicitly enable the plugin per sub-project.
The goal is to be able to run sbt assembly so it will do that just for the root project.
Found the answer in a closed issue. You have to add the following line to your common settings:
aggregate in assembly := false

How to define a custom build setting?

I want my users to be able to define a value in their project/ definition that will be used as a URL for fetching a remote configuration file, which an sbt plugin will in turn use. I can't figure out how to define such a value though. When I try to add it to build.sbt I get this error:
/Users/2rs2ts/src/my-cool-plugin/build.sbt:74: error: not found: value myConfigUrl
myConfigUrl := "http://mycoolwebsite.com/config.xml"
^
[error] Type error in expression
Probably because it's not part of Keys. But I don't know how I'm supposed to add something like this. Even after that point, I don't know how to access the setting in my plugin's Scala source.
Use settingKey macro to define the myConfigUrl key.
A sample build.sbt could be as follows:
lazy val myConfigUrl = settingKey[String]("URL for fetching a remote configuration file")
myConfigUrl := "http://mycoolwebsite.com/config.xml"
A sample session:
➜ my-cool-plugin xsbt
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to my-cool-plugin (in build file:/Users/jacek/sandbox/my-cool-plugin/)
> show myConfigUrl
[info] http://mycoolwebsite.com/config.xml
Given the comment where the OP asked:
How can I refer to this in my project code now? I want to be able to
access the value I assigned to myConfigUrl in one of my .scala files,
not related to the build process.
the key should be defined in build.scala build object as no keys in *.sbt files are visible in project/*.scala files.
Here is a sample project/build.scala build definition with the key:
import sbt._
import Keys._
object build extends Build {
lazy val myConfigUrl = settingKey[String]("URL for fetching a remote configuration file")
lazy val mySettings = inConfig(Compile) { Seq(
myConfigUrl := "http://mycoolwebsite.com/config.xml"
)}
}
With the Scala build, change build.sbt to be as follows:
mySettings
You could do it since every build file is automatically imported in *.sbt files and hence accessing vals becomes simple like that. To have the settings - the single myConfigUrl key - available in the project you need to add the Seq[Setting] val.
Do reload and the key should be available as if it was before:
> show myConfigUrl
[info] http://mycoolwebsite.com/config.xml
Given the comment:
I'm particularly interested in a way to let end users of
my-cool-plugin define their own myConfigUrl which will be used instead
of the default one in my-cool-plugin's build.sbt
it's clear on the intent of the key. This is a key of the plugin so just add sbtPlugin := true to the build, publishLocal the project and use addSbtPlugin to declare a plugin dependency on the plugin in another build.
You may want to read about the new feature of sbt 0.13.5 - auto plugins - that further ease setting up the plugin of yours:
As of sbt 0.13.5, there is a new auto plugins feature that enables
plugins to automatically, and safely, ensure their settings and
dependencies are on a project.