Building packages that use sbt
Overview
This is a quick guide to getting Fedora packages built with sbt
. Since sbt
uses Ivy for dependency resolution, you'll either need to construct a local Ivy repository as part of the build (for F20) or rely on xmvn's improved support for Ivy metadata (in F21 and above after xmvn 2.0 lands). For now, this guide covers building packages on F20 with the climbing-nemesis script.
Eventually, I hope that the best practices around building Scala projects will coalesce into official Scala packaging guidelines, but for now it's sort of the wild west. Your feedback is welcome!
Differences with upstream sbt
sbt
build files are either written in a domain-specific language (*.sbt
files) or are general Scala code that incorporates sbt
as a library, and they typically either live in the root directory of a project's source tree or in the project
directory. Because they aren't XML files, patches against sbt
builds are typically less brittle than patches against Ant build files, and it's more straightforward to carry Fedora-specific build patches as sed
commands.
How sbt
resolves Ivy dependencies is specified by a properties file (see also sbt
resolver specifications). For the Fedora sbt
, this defaults to /etc/sbt/sbt.boot.properties
, but you can override this by setting SBT_BOOT_PROPERTIES
in your environment. Without overriding the properties file, the sbt
script shipping in Fedora will allow you to specify the path to a local Ivy repository (set SBT_IVY_DIR
) and the path to a cache of resolved artifacts that sbt
needs to run (set SBT_BOOT_DIR
). We'll discuss these more later in this document.
General tips and tricks
The Fedora sbt
package is primarily intended to be used for packaging sbt
-based projects in Fedora. While you'll be able to use it to do general Scala development as well, some features that sbt
users expect to have available (most notably, cross-building for incompatible Scala versions and launching different versions of sbt
for different projects) have been removed since it is difficult or impossible to support them while meeting Fedora packaging guidelines.
sbt
build files list dependencies in a particular format: GROUP % ARTIFACT % VERSION
or GROUP % ARTIFACT % VERSION % CONFIG
. You will also occasionally see dependencies of the form GROUP %% ARTIFACT % VERSION
; the double-percent sign indicates that the Scala version should be appended to the artifact name, as is common practice for Scala artifacts in Maven and Ivy repositories.
You'll want to patch the project/build.properties
file, if there is one, to make sure that the project expects the version of sbt
that is packaged in Fedora. You'll also want to make sure that the Scala version expected by this project is exactly the same as the one available in Fedora. If the project expects Scala 2.10.2, you'll need to patch the build files to have it look for 2.10.3 instead.
Helpful macros
The first of these macros, remap_version
, takes a group ID, an artifact ID, a version string, and a sbt
build file and updates the file so that any dependency on the given artifact is for the version specified in the macro invocation and not on whatever version was in the build file.
%global remap_version() sed -i -e 's/"%{1}" %% "%{2}" %% "[^"]*"/"%{1}" %% "%{2}" %% "'%{3}'"/g' %{4}
remap_version_to_installed
takes a group ID, an artifact ID, and a sbt
build file and updates the file so that any dependency on the given artifact is for the version of that artifact installed on the build machine.
%global remap_version_to_installed() sed -i -e 's/"%{1}" %% "%{2}" %% "[^"]*"/"%{1}" %% "%{2}" %% "'$(rpm -q --qf "%%%%{version}" $(rpm -q --whatprovides "mvn(%{1}:%{2})" ))'"/g' %{3}