Using sbt plugin from Bintray - scala

I'm experiencing a kind of impedance mismatch between sbt and bintray-sbt plugin. The plugin is published via bintray-sbt at https://bintray.com/artifact/download/synapse/sbt-plugins/me/synapse/my-sbt-plugin/0.0.1/my-sbt-plugin-0.0.1.pom (publishMavenStyle set to true. If set to false a different directory structure is created but still not the one sbt expects). Test project has
resolvers += Resolver.bintrayRepo("synapse", "sbt-plugins")
addSbtPlugin("me.synapse" % "my-sbt-plugin" % "0.0.1")
in project/plugins.sbt and sbt tries to download https://dl.bintray.com/synapse/sbt-plugins/me/synapse/my-sbt-plugin_2.10_0.13/0.0.1/my-sbt-plugin-0.0.1.pom
What settings should be used in plugin build definition to a) be able to test it from current repository and b) to be able to link it to sbt-plugin-releases repo when the time comes?
UPD: It looks like after the package was linked to sbt-plugin-releases it ended up in proper directory structure.

Related

Scala "not found: object com" - should i really add entry in build.sbt if there are no other dependencies?

I have created basic Scala Play application with https://www.playframework.com/getting-started play-scala-seed. This project compiles and runs with sbt run. But I have another Scala project that compiles and runs and which I have submitted to my local Ivy repository with command sbt publishLocal. This other project was saved at C:\Users\tomr\.ivy2\local\com.agiintelligence\scala-isabelle_2.13\master-SNAPSHOT as a result of this command.
Then I imported (exactly so - imported, no just opened) my Play project in IntelliJ and I used Project - Open Module Settings - Project Settings - Libraries to add com.agiintelligence jar from my ivy2 location. After such operations IntelliJ editor recognizes com.agiintelligence classes. That is fine.
But when I am trying to run my Play application with sbt run, I experience the error message not found: object com that is exactly when compiling import com.agiintelligence line in my Scala controller file of Play application.
Of course - such error has been reported and resolved with, e.g. object play not found in scala application
But that solution suggests to append build.sbt file. My build.sbt file is pretty bare:
name := """agiintelligence"""
organization := "com.agiintelligence"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.5"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
// Adds additional packages into Twirl
//TwirlKeys.templateImports += "com.skaraintelligence.controllers._"
// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.skaraintelligence.binders._"
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries' (it shows my com.agiintelligence jar as well), but why should I add my own ivy2 library in build.sbt file if no other libraries are listed here? What is different with my library? It is on my computer, in the repository as expected already?
Of course, I can try to add it build.sbt and issue sbt update and see what happens, but I can not understand this logic? Can someone explain it and provide some clue to intelligible solution of my error message?
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries'
Those are probably just transitive dependencies of your Play dependency, that is why sbt downloaded all of them and put them in your classpath so you could use them without you needing to tell it about them; because the pom of Play already did.
It is not that the build tool or the IDE magically added all those dependencies for you because they read your mind and magically understood you wanted them. And that for some reason the magic stopped working for your own library.
Why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
That is sufficient for the IDE to work, but not for the build tool. The build tool is independent of the IDE; it doesn't know about it. sbt just knows about the dependencies you configured in your definition file.
Even more, you should always configure your dependencies on your build tool and then import that in the IDE; rather than the opposite. IDEs are graphical tools, so their state can not be committed, can not be shared, can not keep track of changes, can not be used in CI / CD environments; additionally, different teammates may want to use different IDEs.
I resolved the error message by adding line in build.sbt file
libraryDependencies += "de.unruh" %% "scala-isabelle" % "master-SNAPSHOT"
and by subsequent run of sbt update.
Error is solved, but the main question still stand - why I had to do this? Why there are tens of dependencies that are not listed in build.sbt and why should I list my dependency in build.sbt and why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
OK, comment by #Luis_Miguel_Mejía_Suárez gave the explanation, that comment is the actual and expected answer to my question.

How to add missing SNAPSHOT dependency to Heroku?

I have a Scala Play 2.7.x application which I deploy to Heroku. However, the build fails due to a missing dependency "com.github.tototoshi" %% "play-joda-routes-binder" % "1.3.1-SNAPSHOT" and that's correct because this one I built locally. How do I make this missing dependency available to Heroku?
The dependency I need is this one https://github.com/tototoshi/play-joda-routes-binder but it had a bug which I fixed here https://github.com/tototoshi/play-joda-routes-binder/pull/6. However, the author of that project seems afk for several months now. I can build my PR locally but how do I add it to Heroku for my project to work?
You can put the compiled jar into a subfolder in the project for example: /lib. Sbt will automatically look for jars in this directory. If you want to configure it as something else you can define the key unmanagedBase:
unmanagedBase := baseDirectory.value / "custom_lib"
There's more documentation about sbt lib management here: https://www.scala-sbt.org/1.x/docs/Library-Dependencies.html.
Also playframework documents this, but it's basically the same:
https://www.playframework.com/documentation/2.7.1/SBTDependencies
Another solution is to not use the automatic deployment with connection to Github but rather the SBT Heroku CLI and then build / deploy locally and simply upload the binary artifacts to Heroku like so:
sbt stage deployHeroku
heroku open --app myapp
after adding the following two entries into the project/plugins.sbt file (latest versions as of today):
addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.4.1")

SBT Plugin in an unmanaged jar file

The requirement: an SBT plugin code is in an unmanaged jar, for example in lib/unmanaged-sbt-plugin-0.0.1.jar.
I was expecting the jar file would be picked up by SBT automatically and the plugin would work out-of-the-box, i.e.: the tasks would be accessible from SBT command line, but that is not the case.
The jar file has the sbt/sbt.autoplugins file in it and the plugin works if pulled from a remote repo into the local one and imported via addSbtPlugin(...). Please note I cannot do that - it's a requirement to get it to load from the lib/unmanaged-sbt-plugin-0.0.1.jar and not from the local/remote repo.
Putting the following line in the build.sbt doesn't make the plugin work (there's not error either):
unmanagedJars in Compile += file("lib/unmanaged-sbt-plugin-0.0.1.jar")
The implementation of addSbtPlugin(...) is simply (according to http://www.scala-sbt.org/0.12.2/docs/Getting-Started/Using-Plugins.html):
def addSbtPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
libraryDependencies <+= (sbtBinaryVersion in update, scalaBinaryVersion in update)
{ (sbtV, scalaV) => sbtPluginExtra(dependency, sbtV, scalaV) }
I'm wondering if the above info can be used to resolve my issue?
Thank you in advance!
So you can specify an explicit URL for library dependencies (ModuleID):
addSbtPlugin("org.my-org" % "unmanaged-sbt-plugin" % "0.0.1"
from "file:///./lib/unmanaged-sbt-plugin-0.0.1.jar")
Have been struggling to get this to work.
Could not get it to work with proposed solution using from "file://.." (using sbt 1.0.4).
Got it to work by putting the plugin in project/lib folder and adding all the plugin dependencies to plugins.sbt using libraryDependencies ++= Seq(..) like in build.sbt. You can find the plugin dependencies by looking at the plugin pom file, usually in .ivy2/local/<org>/<pluginname>/poms folder.

Any IDE supporting SBT?

is any IDE supporting SBT in a proper way (like Maven for example)? Because I've found a lot of tools that generate IDE-related configuration files but I haven't found any plugins that give any support of SBT interaction form within IDE.
I want to make an IDE-agnostic project based on SBT, but also I want to be able to use full spectrum of features that IDE provide and not just use it as an editor and do all the other stuff from console.
Does Intellij fit the bill ? It has an SBT plugin (and a Scala plugin, obviously!)
I know this isn't exactly what you're looking for, but putting it here as a work-around for working with SBT in eclipse for whoever is interested.
SBT generates eclipse config files, but after you import it, it works fine from within eclipse. You just need to set up the project for the first time outside of Eclipse, run SBT to resolve dependencies, generate eclipse structure using the eclipse sbt plugin and import into Eclipse. After that, you can run the code directly from Eclipse and it works fine.
Here're the steps in detail:
Create the folder structure as follows:
Create a file called plugins.sbt in the project folder and add the following line to it:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
Create build.sbt in the root directory i.e. ScalaSBTProject with content similar to the following. I'm using akka here, but add and remove libraries as you require:
name := "ScalaSBTProject"
version := "1.0"
scalaVersion := "2.10.0-RC2"
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "com.typesafe.akka" % "akka-cluster-experimental_2.10.0-RC2" % "2.1.0-RC2"
Open command prompt and run sbt in the directory ScalaSBTProject. SBT will download and resolve whatever dependencies are required
Run the command eclipse at the SBT command line. This will generate all the eclipse related project files
Import ScalaSBTProject into Eclipse using File->Import->Existing Project to workspace, and make sure you check Import into workspace
EDIT: Just as a Post-Script, you can quite easily create a batch file to take the name of the project and generate the eclipse compatible project, just a way to speed up the process.

Create Simple Project SBT 0.10.X

(This is a follow up to sbt not creating projects correctly. The question wasn't answered.)
Basically, that question says "I don't know how to create a project under the new sbt. With the old one, I just ran sbt in a new folder and there was a guided wizard that led me through the setup."
The accepted answer does not explain how to create a new project, it just points to the documentation, which also doesn't explicitly say how to create a new project -- only how to write a build.sbt file.
So I tried first writing a build.sbt and then running sbt in the directory with the build.sbt file, but I still don't see a src directory to work with.
Could someone post a simple step-by-step (I'm assuming there are like 3 steps at most) guiding how to create a new project under sbt 0.10.X?
I found the answer I was looking for at this webpage: Scala 2.9.1, sbt 0.10 and ScalaTest step-by-step.
The high-level steps are:
mkdir my_project make a folder for your project
Create a simple my_project/build.sbt file, e.g.:
name := "A Project"
version := "0.1"
scalaVersion := "2.9.1"
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "1.6.1" % "test"
)
Create a file my_project/src/main/scala/HelloWorld.scala, where you create all the directories you need as you go (e.g. create the directory structure src/main/scala/)
object Main extends App {
Console.println("Hello World!")
}
Execute your sbt commands: e.g. sbt run
I am surprised that noone gave another solution which is the closest to the old way (as mentioned by #dsg) to create a simple project in sbt:
Just run sbt in your project directory, then issue the following commands in the sbt REPL:
> set name := "MyProject"
> set version := "1.0"
> set scalaVersion := "2.9.0"
> session save
> exit
Granted, it is only mildly useful as it will just create the build.sbt file (enough to make it a proper sbt project) with the corresponding properties set, and you might as well create the file by hand (I usually prefer to do so myself). It won't create the src directory either.
Just a few days ago np (new project) plugin to sbt was released. It intended to dealt exactly with that problem:
Initial release. Provides a minimal interface for generating new sbt
projects via,... sbt.
Basic use is to install the plugin globally and start up a new project
with
$ sbt
$ np name:my-project org:com.mypackage version:0.1.0-SNAPSHOT
This will generate a simple build.sbt project for you along with the
standard project directory structure for main and test sources.
For more advanced usage, see the project's readme for more info
You can use https://github.com/n8han/giter8 to generate project layout using various templates
In newer versions of sbt, you can just install sbteclipse:
// ~/.sbt/plugins/build.sbt
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
then from sbt's console you can run:
eclipse with-source=true
In version 0.10.x I think this post can help you:
http://dcsobral.blogspot.fr/2011/06/very-quick-guide-to-project-creation-on.html
I've been using https://github.com/ymasory/sbt-prototype skeleton. See also my other answer.
It was the first one that just worked and I've been a quite happy with it since then.
Don't forget the recent sbt 0.13.3 new command:
Example:
First, you need sbt’s launcher version 0.13.13 or above.
Normally the exact version for the sbt launcher does not matter because it will use the version specified by sbt.version in project/build.properties; however for new sbt’s launcher 0.13.13 or above is required as the command functions without a project/build.properties present.
Next, run:
$ sbt new eed3si9n/hello.g8
....
name [hello]:
scala_version [2.11.8]:
Template applied in ./hello
This ran the template eed3si9n/hello.g8 using Giter8, prompted for values for “name” and “scala_version” (which have defaults “hello” and “2.11.8”, which we accepted hitting [Enter]), and created a build under ./hello.
Check out the GitHub repo Scala SBT Template. In particular the buildt.sbt file.
Just clone the repo, go to that directory, then call the sbt command.
$ git clone git://github.com/dph01/scala-sbt-template.git
$ cd scala-sbt-template
$ ./sbt
From inside of sbt, you can type run to execute provided code. Have fun!
An alternative way to generate the project structure using Intellij:
Create the directory for the project and include there a basic sbt file. You just need to specify the project name.
name := "porjectName"
With Intellij import the project. During the process check the options "Use auto-import" and "Create directories for empty content roots automatically"
That will create for you the basic skeleton for the sbt project.