First cut at debian packaging.

This adds a Debian build section that will create
a new .deb file for the sbt script.  This includes
a new src/debian and src/debian-gzipped directories
for placing files that will be included in the
distribution on debian.

Initial cut at making debian packages
This commit is contained in:
Josh Suereth 2011-11-28 18:52:47 -05:00
parent 0c4df8c2d5
commit 34fed66022
7 changed files with 226 additions and 1 deletions

4
.gitignore vendored
View File

@ -6,4 +6,6 @@ lib_managed
src_managed
/ext
.lib
/template-project/project/boot
/template-project/project/boot
*~

7
project/build.scala Normal file
View File

@ -0,0 +1,7 @@
import sbt._
import Keys._
object SbtExtras extends Build {
// TODO - Detect Debian distribution and enable debian settings for the project.
val root = Project("sbt-extras", file(".")) settings(DebianPkg.settings:_*)
}

94
project/debian.scala Normal file
View File

@ -0,0 +1,94 @@
import sbt._
import Keys._
object DebianPkg {
val Debian = config("debian-pkg")
val makeDebianExplodedPackage = TaskKey[File]("make-debian-exploded-package")
val makeZippedPackageSource = TaskKey[Unit]("make-zipped-package-source")
val genControlFile = TaskKey[File]("generate-control-file")
val lintian = TaskKey[Unit]("lintian", "Displays lintian error messages associated with the package")
val showMan = TaskKey[Unit]("show-man", "shows the sbt program man page")
val settings: Seq[Setting[_]] = Seq(
resourceDirectory in Debian <<= baseDirectory(_ / "src" / "debian"),
resourceDirectory in Debian in makeZippedPackageSource <<= baseDirectory(_ / "src" / "debian-gzipped"),
mappings in Debian <<= resourceDirectory in Debian map { d => (d.*** --- d) x (relativeTo(d)) },
mappings in Debian in makeZippedPackageSource <<= resourceDirectory in Debian in makeZippedPackageSource map { d => (d.*** --- d) x (relativeTo(d)) },
// TODO - put sbt-version into the generated sbt script.
mappings in Debian <+= baseDirectory map { dir => (dir / "sbt" -> "usr/bin/sbt") },
name in Debian := "sbt",
version in Debian <<= (version, sbtVersion) apply { (v, sv) =>
sv + "-build-" + (v split "\\." map (_.toInt) dropWhile (_ == 0) map ("%02d" format _) mkString "")
},
target in Debian <<= (target, name in Debian, version in Debian) apply ((t,n, v) => t / (n +"-"+ v)),
genControlFile <<= (name in Debian, version in Debian, target in Debian) map {
(name, version, dir) =>
val cfile = dir / "DEBIAN" / "control"
IO.writer(cfile, ControlFileContent, java.nio.charset.Charset.defaultCharset, false) { o =>
val out = new java.io.PrintWriter(o)
out println ("Package: %s" format name)
out println ("Version: %s" format version)
out println ControlFileContent
}
cfile
},
makeDebianExplodedPackage <<= (mappings in Debian, genControlFile, target in Debian) map { (files, _, dir) =>
for((file, target) <- files) {
val tfile = dir / target
if(file.isDirectory) IO.createDirectory(tfile)
else IO.copyFile(file,tfile)
}
dir
},
makeZippedPackageSource <<= (mappings in Debian in makeZippedPackageSource, target in Debian) map { (files, dir) =>
for((file, target) <- files) {
val tfile = dir / target
if(file.isDirectory) IO.createDirectory(tfile)
else {
val zipped = new File(tfile.getAbsolutePath + ".gz")
IO delete zipped
IO.copyFile(file,tfile)
Process(Seq("gzip", "--best", tfile.getAbsolutePath), Some(tfile.getParentFile)).!
}
}
dir
},
packageBin in Debian <<= (makeDebianExplodedPackage, makeZippedPackageSource, target in Debian, name in Debian, version in Debian) map { (pkgdir, _, tdir, n, v) =>
// Assign appropriate permissions
val isDirectory = (_: File).isDirectory
val dirs = (tdir.***).get filter isDirectory
val bins = (tdir / "usr" / "bin" ***).get filterNot isDirectory
val data = (tdir / "usr" / "share" ***).get filterNot isDirectory
val perms = Map("0755" -> (dirs ++ bins),
"0644" -> data)
val commands = for {
(perm, files) <- perms
file <- files
p = Process("chmod " + perm + " " + file.getAbsolutePath)
} p.!
// Make the package. We put this in fakeroot, so we can build the package with root owning files.
Process(Seq("fakeroot", "--", "dpkg-deb", "--build", pkgdir.getAbsolutePath), Some(tdir)).!
tdir.getParentFile / (n + "-" + v + ".deb")
},
lintian <<= (packageBin in Debian) map { file =>
println("lintian -c " + file.getName + " on " + file.getParentFile.getAbsolutePath)
Process(Seq("lintian", "-c", "-v", file.getName), Some(file.getParentFile)).!
},
showMan <<= (resourceDirectory in Debian in makeZippedPackageSource) map { dir =>
Process("groff -man -Tascii " + (dir / "usr" / "share" / "man" / "man1" / "sbt.1").getAbsolutePath).!
}
)
// TODO - Use default-jre-headless?
final val ControlFileContent = """Section: java
Priority: optional
Architecture: all
Depends: curl, java2-runtime, bash (>= 2.05a-11)
Recommends: git
Maintainer: Josh Suereth <joshua.suereth@typesafe.com>
Description: Simple Build Tool
This script provides a native way to run the Simple Build Tool,
a build tool for Scala software, also called SBT.
"""
}

View File

@ -0,0 +1,6 @@
sbt (0.11.2-build-0100)
* First debian package release
-- Joshua Suereth <joshua.suereth@typesafe.com> 2011-11-29

View File

@ -0,0 +1,2 @@
sbt Debian maintainer and upstream author are identical.
Therefore see also normal changelog file for Debian changes.

View File

@ -0,0 +1,92 @@
.\" Process this file with
.\" groff -man -Tascii sbt.1
.\"
.TH SBT 1 "NOVEMBER 2011" Linux "User Manuals"
.SH NAME
sbt \- Simple Build Tool
.SH SYNOPSIS
.B sbt [-h] [-sbt-version
.I sbt-version
.B ]
.I <commands>
.B ...
.SH DESCRIPTION
.B sbt
Runs the Simple Build Tool using the currently installed
.BR java (1)
The current directory is assumed to be the project.
.SH OPTIONS
.IP -h
Show help options.
.IP "-verbose | -v"
turn up the noise
.IP "-debug or -d"
set sbt log level to debug
.IP -no-colors
disable ANSI color codes
.IP -sbt-create
start sbt even if current directory contains no sbt project
.IP "-sbt-dir <path>"
path to global settings/plugins directory (default: ~/.sbt)
.IP "-sbt-boot <path>"
path to shared boot directory (default: ~/.sbt/boot in 0.11 series)
.IP "-ivy <path>"
path to local Ivy repository (default: ~/.ivy2)
.IP "-mem <integer>"
set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem))
.IP "-no-share"
use all local caches; no sharing
.IP -offline
put sbt in offline mode
.SH SBT Version Options
.IP "-sbt-version <sbt-version>"
Use the alternate system wide
.I sbt-version
The Simple Build Tool version to use. This script will
download necessary versions using the
.BR curl (1)
tool.
.IP "-sbt-jar <path>"
use the specified jar as the sbt launcher
.IP "-sbt-rc"
use an RC version of sbt
.IP -sbt-snapshot
use a snapshot version of sbt
.SH Scala Options
.IP -28
use latest 2.8.x Scala release
.IP -29
use latest 2.9.x release
.IP -210
use latest 2.10.x release
.IP "-scala-home <path>"
use the scala build at the specified directory
.IP "-scala-version <version>"
use the specified version of scala
.SH Java Options
.IP "-java-home <path>"
alternate JAVA_HOME
.IP "-Dkey=val"
pass -Dkey=val directly to the java runtime
.IP -J-X
pass option -X directly to the java runtime (-J is stripped)
.SH FILES
.I ~/.sbt
.RS
The user configuration file.
.RE
.I ".sbtopts"
.RS
If this file exists in the sbt root, it is prepended to the
runner args.
.SH ENVIRONMENT
.IP JAVAOPTS
If non-null a set of arguments passed to java.
.IP SBTOPTS
environment variable, if unset uses "$default_sbt_opts".
.SH EXAMPLES
Most users of this script will only have to call "sbt" on the command line.
.SH AUTHOR
Paul Phillips <paulp@typesafe.com>

View File

@ -0,0 +1,22 @@
sbt
Copyright: Typesafe, Inc.
2011-11-28
The home page of sbt package is at:
http://github.com/paulp/sbt-extras
The entire code base may be distributed under the terms of the BSD license, which appears immediately below.
Copyright (c) 2011, Typesafe, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.