How to import unmanaged dependencies into code - scala

I'm trying to use sbt to pull down an existing github project and then (obviously) use it in my code. My abbreviated build.sbt is shown below:
lazy val myProjInGit = RootProject(
uri("git://github.com/me/sheet-ref.git#master"))
lazy val root = (project in file("."))
.dependsOn(myProjInGit)
.settings(
name := "MainProj",
)
libraryDependencies ++= Seq( /*other stuff... */)
This is probably a basic one, but how should I then be importing this into code? Could I use, say, import myProjInGit.SampleObject.sampleFunction in my Main.scala? I can see a disconcerting lack of info on SO about this topic so I'm not sure that I'm not barking up completely the wrong tree. Thanks in advance for any help.
EDIT: some further details here. The project I am trying to import is just a library, so it only contains a package object. To try to debug things a little, I'm trying to import it as a ProjectRef, rather than a RootProject. I've discovered the projects sbt command, and if I run it on the project I'm trying to import (not the main one), it gives me:
sbt:SheetRef> projects
[info] In file:/data/va-projects/sheet-ref/
[info] * SheetRef
So... it seems that external project is called SheetRef. If I try to import SheetRef using
lazy val sheetRef = ProjectRef(
uri("git://github.com/me/sheet-ref.git#master"), "SheetRef")
then I get an sbt error:
[error] No project 'SheetRef' in 'git://github.com/me/sheet-r
ef.git#master'.
[error] Valid project IDs: root
Which feels unintuitive. I can import it as root, but then I seem to be unable to access it from my code - if it requires an import statement, it's not obvious to me what it should be.

The dependency has to be an SBT project, so SBT knows how to build it. If it is, then yes, you access it just like any other dependency in your code, because it's added to the classpath (after being built) just like any other dependency.
Which feels unintuitive. I can import it as root, but then I seem to be unable to access it from my code - if it requires an import statement, it's not obvious to me what it should be.
The thing is, it doesn't matter how you add the dependency; it could be a normal library dependency, an unmanaged dependency, a source dependency, etc. Those are SBT concepts, which have no meaning to the Scala compiler.
So the import statement can't depend on project names, jar names or anything like that. In fact, it's the same as if you just put those files into your own project.

Is there someone that made such a thing work? I am trying the same, and somehow manage to get the git project imported but I have no idea how to access the imported scala components.

Related

How to add com.typesafe.sbt.* dependencies to my project?

I was playing with one sbt web plugin and I wanted to reuse the code in my project. Unfortunately I wasn't even able to compile the original code in my project because of missing dependencies. These are the imports:
import com.typesafe.sbt.jse.SbtJsTask
import com.typesafe.sbt.web.{CompileProblems, LineBasedProblem}
import sbt.Keys._
import sbt._
import xsbti.Severity
None of these could be resolved. The build fails with messages like not found: object sbt. I checked the original project's build.sbt file but there was nothing relevant in libraryDependencies.
I'm using Intellij Idea and the strange thing is that when I expand External Libraries in the Project View I can find all the required stuff under SBT: sbt-and-plugins (for example object com.typesafe.sbt.web.CompileProblems is there and I can see its definition in the class file).
It seems to me that the stuff I need is a core part of sbt but somehow it won't load to the project. What am I doing wrong?
short answer: from here
EDIT (3): answer:
use a custom ivy resolver:
resolvers += Resolver.url("SBT Plugins", url("https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
libraryDependencies += ("com.typesafe.sbt" % "sbt-js-engine" % "1.0.2")
.extra(
sbt.mavenint.PomExtraDependencyAttributes.SbtVersionKey -> sbtBinaryVersion.value,
sbt.mavenint.PomExtraDependencyAttributes.ScalaVersionKey -> scalaBinaryVersion.value)
.copy(crossVersion = CrossVersion.Disabled)
how to find plugin jars:
to figure out from where exactly sbt downloads the jars, I used this (somewhat awkward) process:
first, I wanted to see where sbt stores the file localy. so:
sbt "reload plugins" "show fullClasspath" | sed s/\),\ Attributed\(/\\n/g
and I searched the output (or you can use grep).
then, I deleted the file, and executed sbt again with: reload plugins, update & last update to see the full update log.
searching the log, I found a line saying where sbt got the plugin from.

What is the issue with this sbt file?

When I import a SBT project into intelliJ, the build.sbt file is showing lot of errors as shown in the following screenshot. Wondering what might be the issue
IDEA Version 13.1.4
I also see the following
The following source roots are outside of the corresponding base directories:
C:\Users\p0c\Downloads\recfun\src\main\resources
C:\Users\p0c\Downloads\recfun\src\test\java
C:\Users\p0c\Downloads\recfun\src\test\scala
C:\Users\p0c\Downloads\recfun\src\test\resources
These source roots cannot be included in the IDEA project model. Please consider using shared SBT projects instead of shared source roots.
I think the question perhaps does not provide all the required information to answer conclusively, but I'll give it a spin anyways -
Since sbt runs correctly when invoked from the shell, we know the sbt file is fine. I use Idea for my Scala and sbt projects and I am sure the Idea sbt support works very well, but! Idea is far more restrictive than sbt when it comes to project structure. It is really easy to create a valid sbt project structure that Idea can't support very well.
Given that the source roots error indicates that the recfun/src folder is not in the project folder, it seems clear that this error is not emitted during the processing of recfun/build.sbt. The screenshot shows you have at least three different sbt files, progfun-recfun, submission and scala-recfun. Since Idea will also create projects like submission-build, and you have an assignment-build project there, something is probably broken in the project structure, not from the sbt viewpoint - there you're fine, you can build - but from the Idea viewpoint, which is more restrictive.
My suggestion to resolve this would be to change your project structure as follows. First, have a top level project with a build.sbt. Then create a sub-project for each src folder you want. Do not put a src folder in your top level project. Each sub-project needs a build.sbt as well.
Second, make sure the sub-projects build correctly with sbt when run from the shell. Arrange the sub-project build.sbt files with the proper dependencies, using this syntax:
lazy val a = ProjectRef(file("../a"), "a")
lazy val b = ProjectRef(file("../b"), "b")
lazy val root = Project(id = "c", base = file(".")) dependsOn (a, b)
(This example has three sister projects a, b and c, where c depends on a and b. The three projects are placed in directories with the same name, within the root directory. The code snippet is from the build file for c.)
Third, arrange your top level build.sbt to aggregate the sub-projects, using this syntax in the top level build.sbt:
lazy val a = ProjectRef(file("a"), "a")
lazy val b = ProjectRef(file("b"), "b")
lazy val c = ProjectRef(file("c"), "c")
lazy val root = (project in file(".")).
aggregate(a, b, c)
Building this top level project will build each of the sub-projects a, b and c, and the dependencies established in the sub-project build files will ensure they are built in the right order.
Fourth, import the top level project into Idea, and all should be well.
You can get fancy with the file structure if you want, because the project references use relative paths, but it's usually nice to at least start simple.
I had a lot of frustration with sbt and Idea at the start, I hope this helps :)

IntelliJ Idea sbt managed source file

I am using sbt-buildinfo plugin that generates Scala source from my build definitions, allowing me to reference project name, version, etc. from my Scala code.
It does this by generating a file BuiltInfo.scala with the following contents:
package hello
case object BuildInfo {
val name = "helloworld"
val version = "0.1-SNAPSHOT"
val scalaVersion = "2.10.3"
val sbtVersion = "0.13.2"
}
in
target/scala-2.10/src_managed/main/sbt-buildinfo/BuildInfo.scala.
Everything compiles and I can reference those vals.
However, IntelliJ Idea doesn't recognize BuildInfo.scala as a managed source file, so that it would stop showing me errors. Any idea how to do that?
Thanks!
Grega, are you working in a Play Framework project? Or do you have any SBT sub-projects? I don't have a complete answer, but may have a lead.
This same problem shows up in my IDEA projects when using sbt-buildinfo and sbt-scalaxb. Frustratingly, it has worked intermittently—usually after lots of tinkering around, but inexplicably stops.
I wound up digging a bit deeper (and eventually issued bug report SCL-7182 to JetBrains), and noticed the root cause was having a sub-project. When present, IDEA doesn't correctly identify src_managed for the root project, but does for the sub-project.
A work-around, for now, is to manually add the correct src_managed directory to your project's sources using the Project Structure dialog.
For reference, I'm running version 0.38.437 of the Scala plugin on IntelliJ IDEA 13.1.3.

Custom SBT Build file to not compile views in Play 2.0

I have a Play 1.2.4 app that I'm trying to migrate to Play 2.0.2. I currently have a structure in Play 1.2.4 like this:
Website depends on Frontend
Catalog depends on Frontend
Frontend depends on (a routes file being defined when compiling views)
Where Frontend contains a bunch of views that are used by both Website and Catalog. This decision was made because Catalog is really lightweight and is used for quick development of Frontend. While Website has a lot more code in it and takes longer to code/compile/test.
I cannot setup these projects as subprojects like is decribed here http://www.playframework.org/documentation/2.0/SBTSubProjects because there is a circular dependency. The views use Asset.of which requires the routes file to be defined. But the Website and Catalog each define a routes file and Play 2.0 does not support routes files from dependencies (this is supposed to come in Play 2.1). And in the Catalog the views are referenced in the controllers.
I was thinking that if I could change my build logic for Frontend to not try to compile the views, but instead just publish an artifact containing them then I could have Website and Catalog add those artifacts to the views it defines and build them together. This would break the circular dependency I have.
Has anyone else done this before? I'm too much of a beginner with SBT to even know if this is possible. Could anyone tell me how I could modify the Build.scala file to stop compiling the views but export them instead? Would it make sense for me to make this an SBT plugin? Of if you know of any code that shows how to do this another could you post a link to the code?
I used the play new to create two projects. The LDAPInterface was an interface to LDAP that we wanted to use across several applications. The Second Project was the Access manger. In the AccessManager\project\build.scala file, we structured it this way in order to use the LDAPInterface project. In eclipse, we just included the LDAPInterface in the project dependency section so we could debug. You could always compile a jar file and include that, but ... not as good if you want to drill down on project dependencies within eclipse. If we used play.Project it recognized it as a web project. If we just used Project it seemed to think it was a console application.
import sbt._
import Keys._
import play.Project._
object LDAPInterface {
lazy val depProject = RootProject(file("../LDAPInterface"))
}
object ApplicationBuild extends Build {
val appName = "AccessManager"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
//Add your project dependencies here,
javaCore,
javaJdbc,
javaEbean
)
// lazy val root = Project(id = "AccessManager",
// base = file(".")
//).dependsOn(LDAPInterface.depProject)
lazy val main = play.Project(appName, appVersion, appDependencies).settings(
// Add your own project settings here
).dependsOn(LDAPInterface.depProject)
}

What is the best way to handle multiple run targets in SBT?

I'm attempting to create a Build.scala that has multiple projects/targets for the run action. I had started trying to define it as a sub-project like:
val this_one = Project(
id = "Main",
base = file(".")
settings = ...
)
My first guess is that I have the wrong settings stuff, or the config doesn't belong in a Project definition like this.
To elaborate a little, I have more than one main() I want to run in a single source tree. There are a couple of tools that go with the main project itself, and I would like to be able to execute them selectively from the sbt console.
Turns out SBT is just smart enough to figure it out by itself! If you have multiple classes with a main(), it gives you a choice when you type "run" at the SBT prompt!
You can specify the main class using run-main. Something like:
sbt "run-main com.company.project.Main1"
sbt "run-main com.company.project.Main2"