Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX #388 remove dependencies to chmod. #399

Merged
merged 1 commit into from
Nov 6, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 86 additions & 40 deletions src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ package debian

import sbt._
import sbt.Keys.{ target, normalizedName, version, streams, mappings, packageBin }
import linux.{ LinuxSymlink, LinuxPackageMapping }
import linux.{ LinuxSymlink, LinuxPackageMapping, LinuxFileMetaData }
import linux.LinuxPlugin.autoImport.{ linuxPackageMappings, linuxPackageSymlinks, packageArchitecture }
import scala.collection.JavaConversions._

import org.vafer.jdeb.{ DebMaker, DataProducer }
import org.vafer.jdeb.mapping._
import org.vafer.jdeb.producers._
Expand All @@ -18,7 +17,7 @@ import DebianPlugin.autoImport._
* == JDeb Plugin ==
* This provides a java based debian packaging implementation based
* on the jdeb maven-plugin. To use this, put this into your build.sbt
*
*
* @example Enable the plugin in the `build.sbt`
* {{{
* enablePlugins(JDebPackaging)
Expand All @@ -36,63 +35,110 @@ object JDebPackaging extends AutoPlugin with DebianPluginLike {

def jdebSettings = Seq(

// FIXME do nothing. Java7 posix needed
debianConffilesFile := {
target.value / Names.Debian / Names.Conffiles
},

// FIXME copied from the debian plugin. Java7 posix needed
debianControlFile <<= (debianPackageMetadata, debianPackageInstallSize, target) map {
(data, size, dir) =>
if (data.info.description == null || data.info.description.isEmpty) {
sys.error(
"""packageDescription in Debian cannot be empty. Use
packageDescription in Debian := "My package Description"""")
}
val cfile = dir / Names.Debian / Names.Control
IO.write(cfile, data.makeContent(size), java.nio.charset.Charset.defaultCharset)
cfile
},

/**
* Depends on the 'debianExplodedPackage' task as this creates all the files
* which are defined in the mappings.
*/
packageBin <<= (debianExplodedPackage, linuxPackageMappings, linuxPackageSymlinks,
debianControlFile, debianMaintainerScripts, debianConffilesFile,
normalizedName, version, packageArchitecture, target, streams) map {
(_, mappings, symlinks, controlfile, controlscripts, conffile,
name, version, arch, target, s) =>
s.log.info("Building debian package with java based implementation 'jdeb'")
val console = new JDebConsole(s.log)
val archive = archiveFilename(name, version, arch)
val debianFile = target.getParentFile / archive
val debMaker = new DebMaker(console,
fileAndDirectoryProducers(mappings, target) ++ linkProducers(symlinks),
conffileProducers()
)
debMaker setDeb debianFile
debMaker setControl (target / Names.Debian)

// TODO set compression, gzip is default
// TODO add signing with setKeyring, setKey, setPassphrase, setSignPackage, setSignMethod, setSignRole
debMaker validate ()
debMaker makeDeb ()
debianFile
})
packageBin := {
val targetDir = target.value
val log = streams.value.log
val mappings = linuxPackageMappings.value
val symlinks = linuxPackageSymlinks.value

// unused, but needed as dependency
val controlDir = targetDir / Names.Debian
val control = debianControlFile.value
val conffile = debianConffilesFile.value

val controlScripts = debianMaintainerScripts.value
controlScripts foreach { case (file, script) => IO.copyFile(file, controlDir / script) }

log.info("Building debian package with java based implementation 'jdeb'")
val console = new JDebConsole(log)
val archive = archiveFilename(normalizedName.value, version.value, packageArchitecture.value)
val debianFile = targetDir.getParentFile / archive
val debMaker = new DebMaker(console,
fileAndDirectoryProducers(mappings, targetDir) ++ linkProducers(symlinks),
conffileProducers(mappings, targetDir)
)
debMaker setDeb debianFile
debMaker setControl (targetDir / Names.Debian)

// TODO set compression, gzip is default
// TODO add signing with setKeyring, setKey, setPassphrase, setSignPackage, setSignMethod, setSignRole
debMaker validate ()
debMaker makeDeb ()
debianFile
})

/**
* Creating file and directory producers. These "produce" the
* files for the debian packaging
* files for the debian packaging.
*
* May create duplicates together with the conffileProducers.
* This will be an performance improvement (reducing IO)
*/
private[debian] def fileAndDirectoryProducers(mappings: Seq[LinuxPackageMapping], target: File): Seq[DataProducer] = mappings.map {
case LinuxPackageMapping(paths, perms, zipped) =>
paths map {
case (path, name) if path.isDirectory =>
val permMapper = new PermMapper(-1, -1, perms.user, perms.group, null, perms.permissions, -1, null)
val dirName = if (name.startsWith("/")) name.drop(1) else name
new DataProducerDirectory(target, Array(dirName), null, Array(permMapper))
case (path, name) =>
val permMapper = new PermMapper(-1, -1, perms.user, perms.group, perms.permissions, null, -1, null)
new DataProducerFile(target / name, name, null, null, Array(permMapper))
}
case LinuxPackageMapping(paths, perms, zipped) => paths map {
// Directories need to be created so jdeb can pick them up
case (path, name) if path.isDirectory =>
val permMapper = new PermMapper(-1, -1, perms.user, perms.group, null, perms.permissions, -1, null)
(target / cleanPath(name)) mkdirs ()
new DataProducerDirectory(target, Array(cleanPath(name)), null, Array(permMapper))

// Files are just referenced
case (path, name) => new DataProducerFile(path, cleanPath(name), null, null, Array(filePermissions(perms)))
}
}.flatten

/**
* Creating link producers for symlinks.
*/
private[debian] def linkProducers(symlinks: Seq[LinuxSymlink]): Seq[DataProducer] = symlinks map {
case LinuxSymlink(link, destination) =>
new DataProducerLink(link, destination, true, null, null, null)
case LinuxSymlink(link, destination) => new DataProducerLink(link, destination, true, null, null, null)
}

/**
* Creating the files which should be added as conffiles.
* This is currently handled by the debian plugin itself.
*/
private[debian] def conffileProducers(): Seq[DataProducer] = Seq.empty
private[debian] def conffileProducers(linuxMappings: Seq[LinuxPackageMapping], target: File): Seq[DataProducer] = {

val producers = linuxMappings map {
case mapping @ LinuxPackageMapping(mappings, perms, _) if perms.config == "true" =>
mappings collect {
case (path, name) if path.isFile =>
val permMapper = filePermissions(perms.withPerms("0644"))
new DataProducerFile(path, cleanPath(name), null, null, Array(permMapper))
}
case _ => Seq.empty
}

producers.flatten
}

private[debian] def cleanPath(path: String): String =
if (path startsWith "/") path drop 1 else path

private[this] def filePermissions(perms: LinuxFileMetaData): PermMapper =
new PermMapper(-1, -1, perms.user, perms.group, perms.permissions, null, -1, null)

}

Expand Down