Asking for your feedback on sbt + Scala Center announcement

I think having a small(er) number of canonical build templates would help.

A great starting point would be the Scala equivalent of

"stack new my-project"
with option of ‘library’,‘application’,‘multimodule’

The output would be an empty project with default settings and plugins,
e.g. library, would lay out a project (e.g. as per type-level cats/dogs libraries) with core/ docs/ tests / and default scalac options.

Some libraries such as ScalaCheck, ScalaTest should be included by default.

Not only would it make for a much easier build (essentialy most people would fill in the gaps),
it would also encourage good practice. It would ensure that Scala builds are the same across most projects and that would help adoption greatly.

I would go further and suggest things like ‘tut’ and ‘microSites’, ‘pgp’ be standard defaults.

I think these are relatively small changes but would stop ‘sbt’ from being a hinderance to Scala adoption, which I think (rightly or wrongly) is the case for some people.

It would be nice if scala-center could do something to improve the publishing experience. If we want more people to contribute scala projects it would be nice if we asked less of them to get it going. I took a crack at it today, ended up in failure. I am sure I will get it going tomorrow but found the variety of options and configuration made it far more difficult than publishing a package to cargo, brew, rubygems, npm etc.

Ivy, Maven, seach for a tutorial, find a snarky choose your own adventure page explaining (somewhat accurately) how hard publishing is in scala. I asked sonatype or bintray on Gitter/scala, got an answer that they both were equally terrible. Then tried following documentation on http://www.scala-sbt.org/0.13/docs/Bintray-For-Plugins.html which said to name my repo “sbt-plugins” when using the sbt-bintray plugin, then tried publishing in sbt-bintray where it threw an error looking for a repo named “maven”.

I know someone can jump in and give me historical reasons why it’s harder than most environments but what would really be helpful is if we could come up with concrete steps to make it just as easy as it is on the better competing platforms. I am trying to learn it better myself so I can provide more useful feedback, unfortunately this is just an experience report from today when I tried to publish my first sbt plugin. I will say I have easily spent 4 times as long on sbt as I have on the actual code I want to publish which does little to encourage people to share their code.

2 Likes

to achieve the goal of moving to scala 2.12 (IMHO the most important thing to be done), it would be good if the Scala Center helped migrate the sbt plugin ecosystem to sbt 1.0. The new features of 1.0 are small compared to the benefit of a modern scala (allowing FLOSS volunteers to not waste any more time cross building for 2.10)

1 Like

I release to Sonatype and this, to me, was not terrible at all. I followed http://www.scala-sbt.org/0.13/docs/Using-Sonatype.html
In case you want to have a look at a working example, see https://github.com/unic/ScalaWebTest for examples and usage documentation in the readme. Feel free to send a direct message in case I can help you.

PS: I feel that releasing is a bit more complicated, then one would initially expect, because the problem is harder then expected. Artifacts need to contain certain metadata (author, license, …), artifacts have to be signed, release process needs a sign off/staging process to allow to redo a release in case it is incomplete. Hope this helped.

the recursive build thing is cute but it’s basically just more boilerplate to maintain that I would rather was in the build.sbt or supporting .scala files

I have yet to find an non contrived use case for that.

We use the third level of recursion in sbt builds in the Scala.js build. Or rather in the sbt-plugin-test project of the Scala.js build. In that project, we have a project/project/build.sbt containing:

sources in Compile += baseDirectory.value / "../../../ir/src/main/scala/org/scalajs/core/ir/ScalaJSVersions.scala"

This makes it so that, in project/build.sbt, we can use ScalaJSVersions.current:

addSbtPlugin("org.scala-js" % "sbt-scalajs" %
  org.scalajs.core.ir.ScalaJSVersions.current)

to add the current version of the sbt plugin to the plugins of the sbt-plugin-test build. This in turns allows to reference enablePlugins(ScalaJSPlugin) in build.sbt.

In general, this pattern can be reused by any build that defines an sbt plugin, and has a subdirectly containing a test for that version of the sbt plugin.

The minimal valid (and usually complete) .gitignore for an sbt build is:

target/

This is also applicable to multi-project builds, as that gitignore will also ignore foo/target/, as per the rules of .gitignore files.

Ignoring project/project/ (as I’ve seen done in some .gitignore files, including one linked to somewhere in this thread) is incorrect, as project/project/ can contain checked-in files (e.g., the Scala.js build has one). What should be ignored is project/project/target/, but again that is already covered by target/.

4 Likes

Hello,

If you are using IntelliJ IDEA, you want to add .idea to .gitignore.
There’s a corresponding folder for Eclipse (I think it’s .eclipse).

 Best, Oliver

No you don’t. You want to add .idea to your global gitignore file. Because even if you use IntelliJ IDEA, I might want to use Eclipse on your codebase. And you never know what crazy editor will use on your codebase, that will create spurious IDE-specific files.

3 Likes

I wanted to add a vote for reproducibility (also called out here: Asking for your feedback on sbt + Scala Center announcement )

At Stripe, we use bazel for scala builds. In bazel, the goal is 100% bit-for-bit reproducibility, and as far as we know (and we have tests for it) we meet that goal. We never have to run clean. We can refactor a large file moving classes from one file to another and have zero issues (no need to run clean). Lastly, we check in the sha hashes of all the jars we are using, so we know exactly which jars each build ran with. Sbt could also compete in this space!

I would really love it if sbt allowed me to commit a lock file with the transitive resolution of all jars (including a sha checksum). This could also be faster since we would not need to walk the pom graph if such a lock file is present.

Secondly, I would love to see a test harness for sbt to make sure we have bit-for-bit reproducibility even after moving file contents around (a common refactoring issue). Maybe such tests exist, but I still see bugs like this with sbt (in 13.15 most recently) and usually I just run clean and nuke the existing state, which is a shame and slows down the next build.

As a functional programming community, I hope we can make more of the build a pure function, and make the entire build fully reproducible by default.

For more information:
https://reproducible-builds.org/
https://bazel.build/ ("{fast, correct} - choose two").

5 Likes

Add support for building libraries from source via Github URL with efficient library caching.

It helps make forking of open source projects easier and eliminates the need for cross-compiling as well as the associated binary compatibility issues.

I’m not familar with ScalaJS, and I’m sure I may be missing some detail, but I wonder whether using a plain-text resource file (version.properties?) with version numbers may be enough, in a hypothetical SBT version lacking recursive builds.

Oh we would find a solution. I’m not saying it’s critical. I’m pointing out that there are non-contrived use cases for the recursive nature of sbt.

2 Likes

I gave a talk about this topic last week at ScalaDays. Here are the slides (as part of the sample project): https://github.com/szeiger/leftpad-template/blob/master/The%20Last%2010%20Percent.pdf

The particular problem of sbt-bintray looking for the “maven” repository would be caused by not setting bintrayRepository := "sbt-plugins" as part of the plugin project.

1 Like

to 1) I found a ugly Solution to add an additional Artifactory (Maven Repo) URL for first start of sbt. :unamused:
You have to extend a configuration file in the sbt jar.
If someone is interested I can document it in more Detail.
I used it with sbt 1.0.0-M5

We use the third level of recursion in sbt builds in the Scala.js build. Or rather in the sbt-plugin-test project of the Scala.js build.

The SBT docs suggest using a system property for this. That is the approach that I have used myself when writing tests for SBT plugins, i.e.

scriptedLaunchOpts := scriptedLaunchOpts.value ++ Seq(
  "-Xmx1024M", "-Dplugin.version=" + version.value
)

and

addSbtPlugin("uk.co.jhc" % "jhc-sbt-plugins" % System.getProperty("plugin.version"))

That seems easier to me than adding part of your project’s sources to the build’s sources. The ScalaJSVersions.current could be provided by sbt-buildinfo.

1 Like

I find myself thinking about SBT and Scala Center again this weekend and am thinking release cadence is a place the Scala Center may be able to help.

Simply put, I propose it is a good thing for the community that the build tool release cadence matches the language release cadence.

I frequently see being on Scala 2.10 touted as an advantage, with the term “long binary compatibility” spoken of as a good thing. I am failing to see the benefit of Scala being on a roughly 18 month release cycle while SBT is on a 36 month cycle. If it’s a one time failed experiment then lets leave it at that, but given that just this month I am continuing to hear how the 36 month cycle was great for SBT I am worried it may be repeated, and feel that the thread of it being repeated alone is enough to discourage contributions in this space.

Can we just have the discussion of whether the separated cycles are preferred by tooling developers and users. Or maybe a poll?

2 Likes

you need https://github.com/fommil/class-monkey

1 Like

Intriguing – I’ll add this to my to-try list. Thanks!

I sent PR on Document scope delegation in detail. Scope delegation (.value lookup) is one of more trickier aspects of build.sbt DSL. This writeup builds on top of the existing Scopes page, and breaks down the notion of scope delegation into rules and a few realistic looking examples.

Comments on PR will be appreciated.

2 Likes

A post was split to a new topic: Reply to sbt feedback