scala using github repo as a libraryDependencies - scala

I was facing one error while trying using RootProject
I need to use gatling snapshot version which is 3.5.0-SNAPSHOT and to enable this I know two options:-
using git clone and then sbt publishLocal finally using this jar as an unmanaged dependency, This works fine but it is rather more manual work, So I moved to the second option.
Using sbt RootProject, so let me first explain the project setup:-
example/Build.sbt
lazy val gatling = RootProject(uri("https://github.com/gatling/gatling.git"))
lazy val root = (project in file("."))
.settings(
name := "example",
version := "0.1",
scalaVersion := "2.13.3"
).dependsOn(gatling)
example/project/plugins.sbt -> These two were added because it was required while building the project
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.21")
libraryDependencies += "org.scala-sbt" %% "io" % "1.4.0"
example/src/main/scala/Main.scala
import io.gatling.core.scenario.Simulation
object Main extends App {
class A extends Simulation
val a = new A
println(a.toString)
}
So after this executing sbt run will result in a successful build.
But the problem starts when I tried to import gatling-highcharts in a similar fashion as:-
lazy val gatling = RootProject(uri("https://github.com/gatling/gatling.git"))
lazy val gatlingHighCharts = RootProject(uri("https://github.com/gatling/gatling-highcharts.git"))
lazy val root: Project = (project in file("."))
.settings(
name := "example",
version := "0.1",
scalaVersion := "2.13.3"
).dependsOn(gatling, gatlingHighCharts)
now executing sbt will result in an error as:-
[error] not found: C:\Users\user\.ivy2\local\io.gatling\gatling-recorder\3.5.0-SNAPSHOT\ivys\ivy.xml
[error] not found: https://repo1.maven.org/maven2/io/gatling/gatling-recorder/3.5.0-SNAPSHOT/gatling-recorder-3.5.0-SNAPSHOT.pom
[error] not found: https://jcenter.bintray.com/io/gatling/gatling-recorder/3.5.0-SNAPSHOT/gatling-recorder-3.5.0-SNAPSHOT.pom
And this was because gatling is being used via dependsOn while actually there is nothing available to do like:-
lazy val gatlingHighCharts = RootProject(uri("https://github.com/gatling/gatling-highcharts.git")).dependsOn(gatling)
This is not possible as there is no method named dependsOn inside RootProject class and I am not able to figure out how to make that work.
Can anyone help me to figure out how can I make that work?
Plus, if somehow exist a way to use github repo jars directly as managed sources instead of unmanaged sources which is something like
libraryDependencies += "io.gatling.highcharts" % "gatling-charts-highcharts" % "3.5.0-SNAPSHOT"
without using dependsOn.

Related

Can I create a proto jar for scalaVersion 2.11/2.12 and use it within the same sbt under different sub-project?

I have a set of .proto files (protobuf) which I generate java from using scalapb. I also have in the same sbt 2 sub-projects, one is scalaVersion 2.11 compatible (can't upgrade it to 2.12 due to missing packages) and the other one is scala 2.12.
I created a sub-project to hold my proto, and by default 2.12 is used and my 2.12 sub-project can use it, but my 2.11 can't.
I set the crossScalaVersions to 2.11/2.12, I compiled my project with both, which passed, but then even then I was unable to get the 2.11 sub-project to find that code.
I am "wondering" if that is something supported, or if there is a track I could use a single location to hold my .proto yet have my 2 sub-projects using the same sbt file use those.
lazy val scala212 = "2.12.13"
lazy val scala211 = "2.11.12"
lazy val supportedScalaVersion = List(scala212, scala211)
ThisBuild / scalaVersion := scala212
lazy val root = (project in file("."))
.aggregate(proto, subproject1, subproject2)
.settigns(
crossScalaVersions := Nil,
publish / skip := true
)
lazy val proto = project
.settings(
crossScalaVersions := supportedScalaVersions,
name := "proto",
libraryDependencies += "com.trueaccord.scalapb" %% "scalapb-runtime" % com.trueaccord.scalapb.compiler.Version.scalapbVersion % "protobuf",
PB.targets in Compile := Seq(
scalapb.gen(grpc = false) -> (sourceManaged in Compile).value / "protobuf"
)
)
lazy val subproject1 = project
.dependsOn(proto)
lazy val subproject2 = project
.settings(
scalaVersion := scala211
)
.dependsOn(proto)
So, from the above, if I do sbt "+ proto" I can compile both versions. If I do sbt subproject1/compile it works too. Using sbt subproject2/compile fails indicating that it cannot find the 2.11:proto jar file.
Either, I would like the above somehow to work nicely, or any other trick that I could generate the code from the same proto location but within subproject1/subproject2 would be appreciated.
You could try the sbt-projectmatrix plugin:
https://github.com/sbt/sbt-projectmatrix
The idea is to have separate sbt subprojects for the different Scala versions, so you can simply reference the relevant subproject when calling dependsOn.
I think this plugin is going to end up in sbt some day as it's a much better solution in general than the current built-in stateful cross compilation support, and it's developed by Eugene Yokota, who is also an sbt developer.

Create a common library in Play framework

I created 3 subprojects in play: A,B, and common
A and B needs to use common subproject.
the code looks like this for the build.sbt:
name := """play"""
organization := "com.play"
version := "1.0-SNAPSHOT"
lazy val common = (project in file("modules/common")).enablePlugins(PlayScala)
lazy val A = (project in file("modules/A")).enablePlugins(PlayScala)
.dependsOn(common).aggregate(common)
lazy val B= (project in file("modules/B")).enablePlugins(PlayScala)
.dependsOn(common).aggregate(common)
lazy val root = (project in file(".")).enablePlugins(PlayScala)
.dependsOn(A).aggregate(A)
.dependsOn(B).aggregate(B)
scalaVersion := "2.11.11"
libraryDependencies += filters
libraryDependencies += evolutions
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "2.0.0" % Test
The package system, I follow the documentation in the Play framework which is like "package.moduleName"
So, the class in model package in my common subproject has a package name called: "model.common"
Now in subproject A, i want to call the library in the common subproject
I call like this:
import model.common.className
I cannot find it
You can put all the classes inside a top level package.
For example for the common project you can put all the classes inside the com.play.common package.
After that you can use the class example(declare in the common project) from the project A using import com.play.common.A.

Why does sbt create layers of projects and src in IDEA?

I am new to SBT and trying to build a project. My Build.scala looks like
lazy val ec = project.in(file("."))
.settings(commonSettings: _*)
.settings(name := "ec")
.aggregate(ahka, currentLogProcessor, main)
lazy val currentLogProcessor = project.in(file("currentLogProcessor"))
.settings(commonSettings: _*)
.settings(name := "currentlogprocessor")
.settings(
libraryDependencies += "com.myorg.util" % "LP" % "0.18.0-SNAPSHOT" % "provided"
)
lazy val main = project
.settings(commonSettings: _*)
.settings(name := "main")
When SBT refreshes in IntelliJ, I see following
As you could see, even if the settings looks same for currentLogProcessor and main, the project structure is very very different.
project inside currentLogProcessor looks good but project under main is layer with project and src
What is the issue here? How can I remove the layers of project inside project?
Thanks
Your projects ec and main share the same folder. Remove main or ec, or change "in file" for one of them.
lazy val main = project in file("another_path") ...
The answer by #ka4eli is correct, but I'd like to point out few issues with the build definition that can make understanding it so much painful.
Defining top-level aggregate project
lazy val ec = project.in(file("."))
.settings(commonSettings: _*)
.settings(name := "ec")
.aggregate(ahka, currentLogProcessor, main)
You don't need it whatsoever as it's defined automatically anyway - you're just repeating what sbt does implicitly. Just remove it from the build and add build.sbt with the following:
commonSettings
Use build.sbt for a project's build definition
lazy val currentLogProcessor = project.in(file("currentLogProcessor"))
.settings(commonSettings: _*)
.settings(name := "currentlogprocessor")
.settings(
libraryDependencies += "com.myorg.util" % "LP" % "0.18.0-SNAPSHOT" % "provided"
)
By default, lazy val's name is used to call a project project macro should point to, i.e. no need for in(file("currentLogProcessor")). The same applies to the name setting - you're using all-lowercase name that may or may not be needed.
Use build.sbt under currentLogProcessor directory to have the same effect:
name := "currentlogprocessor"
commonSettings
libraryDependencies += "com.myorg.util" % "LP" % "0.18.0-SNAPSHOT" % "provided"
It's that simple.
Apply the rules to the main project.
Have fun with sbt = it's so simple that people hardly accept it and mess up build definitions on purpose to claim otherwise :)

How to avoid adding a 'root' scala sbt project in IntelliJ when defining github dependencies?

I'm using IntelliJ with SBT plugin and I've added the following lines to build.sbt in order to add a dependency to a private github repository:
lazy val g = RootProject(uri("ssh://git#github.com/XXXX/myrepo.git"))
lazy val root = project in file("myproject") dependsOn g
After running sbt, my referenced project is successfully cloned, but build fails due to output path clashes between my base project and a root project that is automatically added each time I refresh sbt after modifying build.sbt.
I was having this same issue awhile back.
I'm not sure what causes it but I know that if you use the multi-project setup for sbt (root/project/build.scala) instead of the simple one (root/build.sbt) Intellij respects your settings.
Try the multi-project setup like this and see if it solves your problem:
import sbt.Keys._
import sbt._
lazy val g = RootProject(uri("ssh://git#github.com/XXXX/myrepo.git"))
object MyProjectBuild extends Build {
lazy val project = Project("myproject", file(".")) // <-- Make sure to name your project what you want the module to be named
.settings(
name := "myproject", // <-- Same here
version := "1.0",
scalaVersion := "2.11.4",
libraryDependencies ++=Seq(
"org.scalatest" % "scalatest_2.11" % "2.2.0" % "test",
)
).dependsOn(g)
}

How to set up multi-module build with reference to external local sbt project?

I just started with Scala and Play and I'm trying to set up a multi build with sbt 0.13.5
My project structure is the following:
/AnormCypher
-> /src
->/main
->/scala
->org.anormcypher[package]
->[Some classes]
-> [other dirs/files]
-> build.sbt
/sample
-> /src
->/main
->/scala
->/controllers[package]
->Application.scala
->[Some classes]
-> [other dirs/files]
-> build.sbt
The sample project depends on the AnormCypher project. I tried to set up the dependency following this SO post. My build.sbt in sample looks like this:
name := """sample"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.1"
libraryDependencies ++= Seq(
jdbc,
anorm,
cache,
ws
)
lazy val core = ProjectRef(file("../AnormCypher"), "anormcypher")
val main = root.dependsOn(core)
When I go into my console and type
activator
sbt is able to load the project. But when I try to compile the sources and try to use classes from the org.anormcypher package, they can't be resolved:
object anormcypher is not a member of package org
[error] import org.anormcypher._
[error] ^
Running a clean compile also brought no results.
Change
lazy val root = (project in file(".")).enablePlugins(PlayScala)
to
lazy val root = (project in file(".")).enablePlugins(PlayScala).dependsOn(core)
and remove
val main = root.dependsOn(core)
reload and the project should work fine.