diff --git a/build.sbt b/build.sbt
index f97ca528b..40a6f22cb 100644
--- a/build.sbt
+++ b/build.sbt
@@ -24,6 +24,8 @@ com.typesafe.sbt.SbtSite.SiteKeys.siteMappings <+= (baseDirectory) map { dir =>
site.sphinxSupport()
+site.includeScaladoc()
+
ghpages.settings
git.remoteRepo := "git@github.com:sbt/sbt-native-packager.git"
diff --git a/project/build.properties b/project/build.properties
index be6c454fb..64abd373f 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=0.13.5
+sbt.version=0.13.6
diff --git a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala
index 568e10d43..e2cbb8406 100644
--- a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala
@@ -2,56 +2,139 @@ package com.typesafe.sbt
import packager._
-import debian.Keys.genChanges
-import Keys.{ packageName, packageZipTarball, packageXzTarball }
+import debian.DebianPlugin.autoImport.genChanges
+import universal.UniversalPlugin.autoImport.{ packageZipTarball, packageXzTarball }
import sbt._
-import sbt.Keys.{ normalizedName, packageBin }
-
-object SbtNativePackager extends Plugin
- with linux.LinuxPlugin
- with debian.DebianPlugin
- with rpm.RpmPlugin
- with windows.WindowsPlugin
- with docker.DockerPlugin
- with universal.UniversalPlugin
- with GenericPackageSettings {
-
- val NativePackagerKeys = packager.Keys
-
- val NativePackagerHelper = packager.MappingsHelper
-
- def packagerSettings = linuxSettings ++
- debianSettings ++
- rpmSettings ++
- windowsSettings ++
- dockerSettings ++
- universalSettings ++
- Seq( // Bad defaults that let us at least not explode users who don't care about native packagers
- NativePackagerKeys.maintainer := "",
- NativePackagerKeys.packageDescription := "",
- NativePackagerKeys.packageSummary := "",
- NativePackagerKeys.packageName <<= normalizedName,
- NativePackagerKeys.executableScriptName <<= NativePackagerKeys.packageName
- )
-
- import SettingsHelper._
- def deploymentSettings = makeDeploymentSettings(Debian, packageBin in Debian, "deb") ++
- makeDeploymentSettings(Rpm, packageBin in Rpm, "rpm") ++
- makeDeploymentSettings(Windows, packageBin in Windows, "msi") ++
- makeDeploymentSettings(Universal, packageBin in Universal, "zip") ++
- addPackage(Universal, packageZipTarball in Universal, "tgz") ++
- makeDeploymentSettings(UniversalDocs, packageBin in UniversalDocs, "zip") ++
- addPackage(UniversalDocs, packageXzTarball in UniversalDocs, "txz") ++
- makeDeploymentSettings(Debian, genChanges in Debian, "changes")
+import sbt.Keys.{ name, normalizedName, packageBin }
+
+/**
+ * == SBT Native Packager Plugin ==
+ *
+ * This is the top level plugin for the sbt native packager.
+ * You don't have to enable this by yourself, instead we recommend
+ * using an archetype for this.
+ *
+ * Currently you can choose between
+ *
+ *
+ * - JavaAppPackaging
+ * - JavaServerPackaging
+ * - AkkaAppPackging
+ *
+ *
+ * == Configuration ==
+ *
+ * The are a few settings you should set if you want to build package
+ * no matter what format.
+ *
+ * {{{
+ * maintainer := "Your name "
+ * packageDescription := "A short description of your application"
+ * }}}
+ *
+ * For all other general settings take a look at [[com.typesafe.sbt.packager.NativePackagerKeys]]
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(SbtNativePackager)
+ * }}}
+ *
+ */
+object SbtNativePackager extends AutoPlugin {
+
+ /* === Universal Configuration === */
+ val Universal = universal.UniversalPlugin.autoImport.Universal
+ val UniversalDocs = universal.UniversalPlugin.autoImport.UniversalDocs
+ val UniversalSrc = universal.UniversalPlugin.autoImport.UniversalSrc
+
+ /* === OS Configurations === */
+ val Linux = linux.LinuxPlugin.autoImport.Linux
+ val Debian = debian.DebianPlugin.autoImport.Debian
+ val Rpm = rpm.RpmPlugin.autoImport.Rpm
+ val Windows = windows.WindowsPlugin.autoImport.Windows
+ val Docker = docker.DockerPlugin.autoImport.Docker
+
+ /**
+ * imports all [[com.typesafe.sbt.packager.NativePackagerKeys]] and two objects:
+ *
+ * === NativePackagerKeys ===
+ *
+ * This inclues ''all'' available keys provided by the sbt-native-packager.
+ * Used it if a setting/task key is not in scope.
+ *
+ * {{{
+ * NativePackagerKeys.notAutomaticallyImported := "cool!"
+ * }}}
+ *
+ * === NativePackagerHelper ===
+ *
+ * This object contains a set of helper methods for working with mappings.
+ *
+ */
+ object autoImport extends packager.NativePackagerKeys {
+
+ val NativePackagerKeys = packager.Keys
+ val NativePackagerHelper = packager.MappingsHelper
+
+ import SettingsHelper._
+
+ def deploymentSettings = makeDeploymentSettings(Debian, packageBin in Debian, "deb") ++
+ makeDeploymentSettings(Rpm, packageBin in Rpm, "rpm") ++
+ makeDeploymentSettings(Windows, packageBin in Windows, "msi") ++
+ makeDeploymentSettings(Universal, packageBin in Universal, "zip") ++
+ addPackage(Universal, packageZipTarball in Universal, "tgz") ++
+ makeDeploymentSettings(UniversalDocs, packageBin in UniversalDocs, "zip") ++
+ addPackage(UniversalDocs, packageXzTarball in UniversalDocs, "txz") ++
+ makeDeploymentSettings(Debian, genChanges in Debian, "changes")
+ }
+
+ import autoImport._
+
+ override lazy val projectSettings = Seq(
+ // Bad defaults that let us at least not explode users who don't care about native packagers
+ maintainer := "",
+ packageDescription := name.value,
+ packageSummary := name.value,
+ packageName := normalizedName.value,
+ executableScriptName := normalizedName.value
+
+ )
object packageArchetype {
- private[this] def genericMappingSettings: Seq[Setting[_]] = packagerSettings ++ mapGenericFilesToLinux ++ mapGenericFilesToWindows
+
+ /**
+ * == Recommended usage ==
+ *
+ * {{{
+ * enablePlugins(JavaAppPackaging)
+ * }}}
+ */
+ @deprecated("Use enablePlugins(JavaAppPackaging)", "1.x")
def java_application: Seq[Setting[_]] =
- genericMappingSettings ++ archetypes.JavaAppPackaging.settings
- def akka_application: Seq[Setting[_]] =
- genericMappingSettings ++ archetypes.AkkaApp.settings
- def java_server: Seq[Setting[_]] =
- genericMappingSettings ++ archetypes.JavaServerAppPackaging.settings
+ projectSettings ++
+ universal.UniversalPlugin.projectSettings ++
+ linux.LinuxPlugin.projectSettings ++
+ debian.DebianPlugin.projectSettings ++
+ rpm.RpmPlugin.projectSettings ++
+ docker.DockerPlugin.projectSettings ++
+ windows.WindowsPlugin.projectSettings ++
+ archetypes.JavaAppPackaging.projectSettings
+
+ /**
+ * {{{
+ * enablePlugins(AkkaAppPackaging)
+ * }}}
+ */
+ @deprecated("Use enablePlugins(AkkaAppPackaging)", "1.x")
+ def akka_application: Seq[Setting[_]] = java_application ++ archetypes.AkkaAppPackaging.projectSettings
+
+ /**
+ * {{{
+ * enablePlugins(JavaServerAppPackaging)
+ * }}}
+ */
+ @deprecated("Use enablePlugins(JavaServerAppPackaging)", "1.x")
+ def java_server: Seq[Setting[_]] = java_application ++ archetypes.JavaServerAppPackaging.projectSettings
}
// TODO - Add a few targets that detect the current OS and build a package for that OS.
diff --git a/src/main/scala/com/typesafe/sbt/packager/GenericPackageSettings.scala b/src/main/scala/com/typesafe/sbt/packager/GenericPackageSettings.scala
deleted file mode 100644
index b65f9778d..000000000
--- a/src/main/scala/com/typesafe/sbt/packager/GenericPackageSettings.scala
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.typesafe.sbt
-package packager
-
-import Keys._
-import sbt._
-import sbt.Keys.{ name, mappings, sourceDirectory, normalizedName }
-import linux.LinuxSymlink
-import linux.LinuxPackageMapping
-
-trait GenericPackageSettings
- extends linux.LinuxPlugin
- with debian.DebianPlugin
- with rpm.RpmPlugin
- with windows.WindowsPlugin
- with universal.UniversalPlugin {
-
- import linux.LinuxPlugin.Users
-
- // This method wires a lot of hand-coded generalities about how to map directories
- // into linux, and the conventions we expect.
- // It is by no means 100% accurate, but should be ok for the simplest cases.
- // For advanced users, use the underlying APIs.
- // Right now, it's also pretty focused on command line scripts packages.
-
- /**
- * Maps linux file format from the universal from the conventions:
- *
- * `/src/linux` files are mapped directly into linux packages.
- * `` files are placed under `/usr/share/`
- * `/bin` files are given symlinks in `/usr/bin`
- * `/conf` directory is given a symlink to `/etc/`
- * Files in `conf/` or `etc/` directories are automatically marked as configuration.
- * `../man/...1` files are automatically compressed into .gz files.
- *
- */
- def mapGenericMappingsToLinux(mappings: Seq[(File, String)], user: String, group: String)(rename: String => String): Seq[LinuxPackageMapping] = {
- val (directories, nondirectories) = mappings.partition(_._1.isDirectory)
- val (binaries, nonbinaries) = nondirectories.partition(_._1.canExecute)
- val (manPages, nonManPages) = nonbinaries partition {
- case (file, name) => (name contains "man/") && (name endsWith ".1")
- }
- val compressedManPages =
- for ((file, name) <- manPages)
- yield file -> (name + ".gz")
- val (configFiles, remaining) = nonManPages partition {
- case (file, name) => (name contains "etc/") || (name contains "conf/")
- }
- def packageMappingWithRename(mappings: (File, String)*): LinuxPackageMapping = {
- val renamed =
- for ((file, name) <- mappings)
- yield file -> rename(name)
- packageMapping(renamed: _*)
- }
-
- Seq(
- packageMappingWithRename((binaries ++ directories): _*) withUser user withGroup group withPerms "0755",
- packageMappingWithRename(compressedManPages: _*).gzipped withUser user withGroup group withPerms "0644",
- packageMappingWithRename(configFiles: _*) withConfig () withUser user withGroup group withPerms "0644",
- packageMappingWithRename(remaining: _*) withUser user withGroup group withPerms "0644")
- }
-
- def mapGenericFilesToLinux: Seq[Setting[_]] = Seq(
-
- // First we look at the src/linux files
- linuxPackageMappings <++= (sourceDirectory in Linux) map { dir =>
- mapGenericMappingsToLinux(MappingsHelper contentOf dir, Users.Root, Users.Root)(identity)
- },
- // Now we look at the src/universal files.
- linuxPackageMappings <++= (packageName in Linux, mappings in Universal, defaultLinuxInstallLocation) map {
- (pkg, mappings, installLocation) =>
- // TODO - More windows filters...
- def isWindowsFile(f: (File, String)): Boolean =
- f._2 endsWith ".bat"
-
- mapGenericMappingsToLinux(mappings filterNot isWindowsFile, Users.Root, Users.Root) { name =>
- installLocation + "/" + pkg + "/" + name
- }
- },
- // Now we generate symlinks.
- linuxPackageSymlinks <++= (packageName in Linux, mappings in Universal, defaultLinuxInstallLocation) map { (pkg, mappings, installLocation) =>
- for {
- (file, name) <- mappings
- if !file.isDirectory
- if name startsWith "bin/"
- if !(name endsWith ".bat") // IGNORE windows-y things.
- } yield LinuxSymlink("/usr/" + name, installLocation + "/" + pkg + "/" + name)
- },
- // Map configuration files
- linuxPackageSymlinks <++= (packageName in Linux, mappings in Universal, defaultLinuxInstallLocation, defaultLinuxConfigLocation)
- map { (pkg, mappings, installLocation, configLocation) =>
- val needsConfLink =
- mappings exists {
- case (file, name) =>
- (name startsWith "conf/") && !file.isDirectory
- }
- if (needsConfLink) Seq(LinuxSymlink(
- link = configLocation + "/" + pkg,
- destination = installLocation + "/" + pkg + "/conf"))
- else Seq.empty
- })
-
- def mapGenericFilesToWindows: Seq[Setting[_]] = Seq(
- mappings in Windows <<= mappings in Universal,
- wixFeatures <<= (name in Windows, mappings in Windows) map makeWindowsFeatures)
- // TODO select main script! Filter Config links!
- def makeWindowsFeatures(name: String, mappings: Seq[(File, String)]): Seq[windows.WindowsFeature] = {
- import windows._
-
- val files =
- for {
- (file, name) <- mappings
- if !file.isDirectory
- } yield ComponentFile(name, editable = (name startsWith "conf"))
- val corePackage =
- WindowsFeature(
- id = WixHelper.cleanStringForId(name + "_core").takeRight(38), // Must be no longer
- title = name,
- desc = "All core files.",
- absent = "disallow",
- components = files)
- // TODO - Detect bat files to add paths...
- val addBinToPath =
- // TODO - we may have issues here...
- WindowsFeature(
- id = "AddBinToPath",
- title = "Update Enviornment Variables",
- desc = "Update PATH environment variables (requires restart).",
- components = Seq(AddDirectoryToPath("bin")))
- val configLinks = for {
- (file, name) <- mappings
- if !file.isDirectory
- if name startsWith "conf/"
- } yield name.replaceAll("//", "/").stripSuffix("/").stripSuffix("/")
- val menuLinks =
- WindowsFeature(
- id = "AddConfigLinks",
- title = "Configuration start menu links",
- desc = "Adds start menu shortcuts to edit configuration files.",
- components = Seq(AddShortCuts(configLinks)))
- // TODO - Add feature for shortcuts to binary scripts.
- Seq(corePackage, addBinToPath, menuLinks)
- }
-
-}
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/Keys.scala
index 053ab5372..468774ad9 100644
--- a/src/main/scala/com/typesafe/sbt/packager/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/Keys.scala
@@ -3,37 +3,46 @@ package packager
import sbt._
-object Keys extends linux.Keys
- with debian.DebianKeys
- with rpm.RpmKeys
- with windows.WindowsKeys
- with docker.DockerKeys
- with universal.UniversalKeys {
+/**
+ * General purpose keys for the native packager
+ */
+trait NativePackagerKeys {
- // These keys are used by the JavaApp/JavaServer archetypes.
val packageName = SettingKey[String]("packageName", "Name of the created output package. Used for dirs/scripts.")
- val executableScriptName = SettingKey[String]("executableScriptName", "Name of the executing script.")
- val makeBashScript = TaskKey[Option[File]]("makeBashScript", "Creates or discovers the bash script used by this project.")
- val bashScriptDefines = TaskKey[Seq[String]]("bashScriptDefines", "A list of definitions that should be written to the bash file template.")
- val bashScriptExtraDefines = TaskKey[Seq[String]]("bashScriptExtraDefines", "A list of extra definitions that should be written to the bash file template.")
- val bashScriptConfigLocation = TaskKey[Option[String]]("bashScriptConfigLocation", "The location where the bash script will load default argument configuration from.")
- val batScriptExtraDefines = TaskKey[Seq[String]]("batScriptExtraDefines", "A list of extra definitions that should be written to the bat file template.")
- val scriptClasspathOrdering = TaskKey[Seq[(File, String)]]("scriptClasspathOrdering", "The order of the classpath used at runtime for the bat/bash scripts.")
- val projectDependencyArtifacts = TaskKey[Seq[Attributed[File]]]("projectDependencyArtifacts", "The set of exported artifacts from our dependent projects.")
- val scriptClasspath = TaskKey[Seq[String]]("scriptClasspath", "A list of relative filenames (to the lib/ folder in the distribution) of what to include on the classpath.")
- val makeBatScript = TaskKey[Option[File]]("makeBatScript", "Creates or discovers the bat script used by this project.")
- val batScriptReplacements = TaskKey[Seq[(String, String)]]("batScriptReplacements",
- """|Replacements of template parameters used in the windows bat script.
- | Default supported templates:
- | APP_ENV_NAME - the name of the application for defining _HOME variables
- | APP_NAME - the name of the app
- | APP_DEFINES - the defines to go into the app
- | """.stripMargin)
+ val packageSummary = SettingKey[String]("package-summary", "Summary of the contents of a linux package.")
+ val packageDescription = SettingKey[String]("package-description", "The description of the package. Used when searching.")
+ val maintainer = SettingKey[String]("maintainer", "The name/email address of a maintainer for the native package.")
- // TODO put these into the linux plugin
- val defaultLinuxInstallLocation = SettingKey[String]("defaultLinuxInstallLocation", "The location where we will install generic linux packages.")
- val defaultLinuxLogsLocation = SettingKey[String]("defaultLinuxLogsLocation", "The location where application logs will be stored.")
- val defaultLinuxConfigLocation = SettingKey[String]("defaultLinuxConfigLocation", "The location where application config files will be stored")
- val defaultLinuxStartScriptLocation = SettingKey[String]("defaultLinuxStartScriptLocation", "The location where start script for server application will be stored")
+ val executableScriptName = SettingKey[String]("executableScriptName", "Name of the executing script.")
}
+
+/**
+ * This Keys object can be used for
+ *
+ * - non autoplugin builds
+ * - import single keys, which are not inside the autoImport
+ *
+ *
+ * == Non autoplugin builds ==
+ *
+ * {{{
+ * import com.typesafe.sbt.packager.Keys._
+ *
+ * packageName := ""
+ * }}}
+ *
+ * == autoplugin builds ==
+ *
+ * {{{
+ * NativePackagerKeys.packageName := ""
+ * }}}
+ */
+object Keys extends NativePackagerKeys
+ with universal.UniversalKeys
+ with linux.LinuxKeys
+ with windows.WindowsKeys
+ with docker.DockerKeys
+ with debian.DebianKeys
+ with rpm.RpmKeys
+ with archetypes.JavaAppKeys
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/Stager.scala b/src/main/scala/com/typesafe/sbt/packager/Stager.scala
new file mode 100644
index 000000000..3c3114a60
--- /dev/null
+++ b/src/main/scala/com/typesafe/sbt/packager/Stager.scala
@@ -0,0 +1,43 @@
+package com.typesafe.sbt.packager
+
+import sbt._
+import sbt.Keys.TaskStreams
+import java.io.File
+
+object Stager {
+
+ /**
+ * create a cache and sync files if needed
+ *
+ * @param config - create a configuration specific cache directory
+ * @param cacheDirectory - e.g. streams.value.cacheDirectory
+ * @param stageDirectory - staging directory
+ * @param mappings - staging content
+ *
+ * @example {{{
+ *
+ * }}}
+ */
+ def stageFiles(config: String)(cacheDirectory: File, stageDirectory: File, mappings: Seq[(File, String)]): File = {
+ val cache = cacheDirectory / ("packager-mappings-" + config)
+ val copies = mappings map {
+ case (file, path) => file -> (stageDirectory / path)
+ }
+ Sync(cache, FileInfo.hash, FileInfo.exists)(copies)
+ // Now set scripts to executable using Java's lack of understanding of permissions.
+ // TODO - Config file user-readable permissions....
+ for {
+ (from, to) <- copies
+ if from.canExecute
+ } to.setExecutable(true)
+ stageDirectory
+ }
+
+ /**
+ * @see stageFiles
+ */
+ def stage(config: String)(streams: TaskStreams, stageDirectory: File, mappings: Seq[(File, String)]): File = {
+ stageFiles(config)(streams.cacheDirectory, stageDirectory, mappings)
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala
index 30d62b01c..0578263ad 100644
--- a/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/AkkaApp.scala
@@ -2,10 +2,49 @@ package com.typesafe.sbt
package packager
package archetypes
+import sbt._
+import sbt.Keys.{ target, sourceDirectory }
+
+import packager.Keys.{ executableScriptName }
+import SbtNativePackager.Universal
+
/**
- * Created by max.cai on 2014-09-27.
+ * Provides a new default script for akka-micro-kernel applications.
+ * This plugin requires the [[com.typesafe.sbt.packager.archetypes.JavaAppPackaging]],
+ * which will be automatically enabled.
+ *
+ * @see [[http://doc.akka.io/docs/akka/snapshot/scala/microkernel.html]]
+ * @see [[https://github.com/sbt/sbt-native-packager/pull/363]]
+ *
+ * @example Enable this plugin in your `build.sbt` with
+ *
+ * {{{
+ * enablePlugins(AkkaAppPackaging)
+ * }}}
+ *
+ *
*/
-object AkkaApp extends JavaApp {
+object AkkaAppPackaging extends AutoPlugin with JavaAppStartScript {
+
+ /**
+ * Name of the bash template if user wants to provide custom one
+ */
val bashTemplate = "akka-bash-template"
+
+ /**
+ * Name of the bat template if user wants to provide custom one
+ */
val batTemplate = "akka-bat-template"
+
+ override def requires = JavaAppPackaging
+
+ override def projectSettings = settings
+
+ import JavaAppPackaging.autoImport._
+
+ private def settings: Seq[Setting[_]] = Seq(
+ makeBashScript <<= (bashScriptDefines, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBinScript(bashTemplate),
+ makeBatScript <<= (batScriptReplacements, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBatScript(batTemplate)
+ )
+
}
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala
index a4ca7c991..1a18f2724 100644
--- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala
@@ -2,32 +2,50 @@ package com.typesafe.sbt
package packager
package archetypes
-import Keys._
import sbt._
-import sbt.Project.Initialize
import sbt.Keys.{ mappings, target, name, mainClass, sourceDirectory }
-import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping }
-import SbtNativePackager._
+import packager.Keys.{ packageName, executableScriptName }
+import linux.{ LinuxFileMetaData, LinuxPackageMapping }
+import linux.LinuxPlugin.autoImport.{linuxPackageMappings, defaultLinuxInstallLocation}
+import SbtNativePackager.{ Universal, Debian }
/**
+ * == Java Application ==
+ *
* This class contains the default settings for creating and deploying an archetypical Java application.
- * A Java application archetype is defined as a project that has a main method and is run by placing
- * all of its JAR files on the classpath and calling that main method.
+ * A Java application archetype is defined as a project that has a main method and is run by placing
+ * all of its JAR files on the classpath and calling that main method.
+ *
+ * == Configuration ==
+ *
+ * This plugin adds new settings to configure your packaged application.
+ * The keys are defined in [[com.typesafe.sbt.packager.archetypes.JavaAppKeys]]
*
- * This doesn't create the best of distributions, but it can simplify the distribution of code.
+ * @example Enable this plugin in your `build.sbt` with
*
- * **NOTE: EXPERIMENTAL** This currently only supports universal distributions.
+ * {{{
+ * enablePlugins(JavaAppPackaging)
+ * }}}
*/
-object JavaAppPackaging extends JavaApp {
+object JavaAppPackaging extends AutoPlugin with JavaAppStartScript {
+
+ /**
+ * Name of the bash template if user wants to provide custom one
+ */
val bashTemplate = "bash-template"
+
+ /**
+ * Name of the bat template if user wants to provide custom one
+ */
val batTemplate = "bat-template"
-}
-trait JavaApp {
- val bashTemplate: String
- val batTemplate: String
+ object autoImport extends JavaAppKeys
- def settings: Seq[Setting[_]] = Seq(
+ import JavaAppPackaging.autoImport._
+
+ override def requires = debian.DebianPlugin && rpm.RpmPlugin && docker.DockerPlugin && windows.WindowsPlugin
+
+ override def projectSettings = Seq(
// Here we record the classpath as it's added to the mappings separately, so
// we can use its order to generate the bash/bat scripts.
scriptClasspathOrdering := Nil,
@@ -52,7 +70,7 @@ trait JavaApp {
hasMain getOrElse Nil
},
// TODO - Overridable bash template.
- makeBashScript <<= (bashScriptDefines, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBinScript,
+ makeBashScript <<= (bashScriptDefines, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBinScript(bashTemplate),
batScriptExtraDefines := Nil,
batScriptReplacements <<= (packageName, Keys.mainClass in Compile, scriptClasspath, batScriptExtraDefines) map { (name, mainClass, cp, extras) =>
mainClass map { mc =>
@@ -60,7 +78,7 @@ trait JavaApp {
} getOrElse Nil
},
- makeBatScript <<= (batScriptReplacements, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBatScript,
+ makeBatScript <<= (batScriptReplacements, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBatScript(batTemplate),
mappings in Universal <++= (makeBashScript, executableScriptName) map { (script, name) =>
for {
s <- script.toSeq
@@ -79,7 +97,7 @@ trait JavaApp {
LinuxPackageMapping(Seq(d -> (installLocation + "/" + name)), LinuxFileMetaData())
})
- def makeRelativeClasspathNames(mappings: Seq[(File, String)]): Seq[String] =
+ private def makeRelativeClasspathNames(mappings: Seq[(File, String)]): Seq[String] =
for {
(file, name) <- mappings
} yield {
@@ -89,41 +107,8 @@ trait JavaApp {
else "../" + name
}
- def makeUniversalBinScript(defines: Seq[String], tmpDir: File, name: String, sourceDir: File): Option[File] =
- if (defines.isEmpty) None
- else {
- val defaultTemplateLocation = sourceDir / "templates" / bashTemplate
- val defaultTemplateSource = getClass.getResource(bashTemplate)
-
- val template = if (defaultTemplateLocation.exists)
- defaultTemplateLocation.toURI.toURL
- else defaultTemplateSource
-
- val scriptBits = JavaAppBashScript.generateScript(defines, template)
- val script = tmpDir / "tmp" / "bin" / name
- IO.write(script, scriptBits)
- // TODO - Better control over this!
- script.setExecutable(true)
- Some(script)
- }
-
- def makeUniversalBatScript(replacements: Seq[(String, String)], tmpDir: File, name: String, sourceDir: File): Option[File] =
- if (replacements.isEmpty) None
- else {
- val defaultTemplateLocation = sourceDir / "templates" / batTemplate
- val defaultTemplateSource = getClass.getResource(batTemplate)
- val template = if (defaultTemplateLocation.exists)
- defaultTemplateLocation.toURI.toURL
- else defaultTemplateSource
-
- val scriptBits = JavaAppBatScript.generateScript(replacements, template)
- val script = tmpDir / "tmp" / "bin" / (name + ".bat")
- IO.write(script, scriptBits)
- Some(script)
- }
-
// Constructs a jar name from components...(ModuleID/Artifact)
- def makeJarName(org: String, name: String, revision: String, artifactName: String, artifactClassifier: Option[String]): String =
+ private def makeJarName(org: String, name: String, revision: String, artifactName: String, artifactClassifier: Option[String]): String =
(org + "." +
name + "-" +
Option(artifactName.replace(name, "")).filterNot(_.isEmpty).map(_ + "-").getOrElse("") +
@@ -133,7 +118,7 @@ trait JavaApp {
// Determines a nicer filename for an attributed jar file, using the
// ivy metadata if available.
- def getJarFullFilename(dep: Attributed[File]): String = {
+ private def getJarFullFilename(dep: Attributed[File]): String = {
val filename: Option[String] = for {
module <- dep.metadata.get(AttributeKey[ModuleID]("module-id"))
artifact <- dep.metadata.get(AttributeKey[Artifact]("artifact"))
@@ -142,17 +127,17 @@ trait JavaApp {
}
// Here we grab the dependencies...
- def dependencyProjectRefs(build: sbt.BuildDependencies, thisProject: ProjectRef): Seq[ProjectRef] =
+ private def dependencyProjectRefs(build: sbt.BuildDependencies, thisProject: ProjectRef): Seq[ProjectRef] =
build.classpathTransitive.get(thisProject).getOrElse(Nil)
- def filterArtifacts(artifacts: Seq[(Artifact, File)], config: Option[String]): Seq[(Artifact, File)] =
+ private def filterArtifacts(artifacts: Seq[(Artifact, File)], config: Option[String]): Seq[(Artifact, File)] =
for {
(art, file) <- artifacts
// TODO - Default to compile or default?
if art.configurations.exists(_.name == config.getOrElse("default"))
} yield art -> file
- def extractArtifacts(stateTask: Task[State], ref: ProjectRef): Task[Seq[Attributed[File]]] =
+ private def extractArtifacts(stateTask: Task[State], ref: ProjectRef): Task[Seq[Attributed[File]]] =
stateTask flatMap { state =>
val extracted = Project extract state
// TODO - Is this correct?
@@ -172,13 +157,13 @@ trait JavaApp {
}
// TODO - Should we pull in more than just JARs? How do native packages come in?
- def isRuntimeArtifact(dep: Attributed[File]): Boolean =
+ private def isRuntimeArtifact(dep: Attributed[File]): Boolean =
dep.get(sbt.Keys.artifact.key).map(_.`type` == "jar").getOrElse {
val name = dep.data.getName
!(name.endsWith(".jar") || name.endsWith("-sources.jar") || name.endsWith("-javadoc.jar"))
}
- def findProjectDependencyArtifacts: Def.Initialize[Task[Seq[Attributed[File]]]] =
+ private def findProjectDependencyArtifacts: Def.Initialize[Task[Seq[Attributed[File]]]] =
(sbt.Keys.buildDependencies, sbt.Keys.thisProjectRef, sbt.Keys.state) apply { (build, thisProject, stateTask) =>
val refs = thisProject +: dependencyProjectRefs(build, thisProject)
// Dynamic lookup of dependencies...
@@ -193,7 +178,7 @@ trait JavaApp {
allArtifactsTask
}
- def findRealDep(dep: Attributed[File], projectArts: Seq[Attributed[File]]): Option[Attributed[File]] = {
+ private def findRealDep(dep: Attributed[File], projectArts: Seq[Attributed[File]]): Option[Attributed[File]] = {
if (dep.data.isFile) Some(dep)
else {
projectArts.find { art =>
@@ -211,9 +196,73 @@ trait JavaApp {
}
// Converts a managed classpath into a set of lib mappings.
- def universalDepMappings(deps: Seq[Attributed[File]], projectArts: Seq[Attributed[File]]): Seq[(File, String)] =
+ private def universalDepMappings(deps: Seq[Attributed[File]], projectArts: Seq[Attributed[File]]): Seq[(File, String)] =
for {
dep <- deps
realDep <- findRealDep(dep, projectArts)
} yield realDep.data -> ("lib/" + getJarFullFilename(realDep))
-}
\ No newline at end of file
+}
+
+/**
+ * Mixin this trait to generate startup scripts provided in the classpath of native packager.
+ *
+ * @example A simple plugin definition could look like this
+ *
+ * {{{
+ * object AkkaAppPackaging extends AutoPlugin with JavaAppStartScript {
+ * // templates have to be placed inside the com/typesafe/sbt.packager/archetypes/ resource folder
+ * // the name is also used to find user-defined scripts
+ * val bashTemplate = "your-bash-template"
+ * val batTemplate = "your-bat-template"
+ *
+ * override def requires = JavaAppPackaging
+ *
+ * override def projectSettings = settings
+ *
+ * import JavaAppPackaging.autoImport._
+ *
+ * private def settings: Seq[Setting[_]] = Seq(
+ * makeBashScript <<= (bashScriptDefines, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBinScript(bashTemplate),
+ * makeBatScript <<= (batScriptReplacements, target in Universal, executableScriptName, sourceDirectory) map makeUniversalBatScript(batTemplate)
+ * )
+ * }
+ *
+ * }}}
+ */
+trait JavaAppStartScript {
+
+ def makeUniversalBinScript(bashTemplate: String)(defines: Seq[String], tmpDir: File, name: String, sourceDir: File): Option[File] =
+ if (defines.isEmpty) None
+ else {
+ val defaultTemplateLocation = sourceDir / "templates" / bashTemplate
+ val defaultTemplateSource = getClass getResource bashTemplate
+
+ val template = if (defaultTemplateLocation.exists)
+ defaultTemplateLocation.toURI.toURL
+ else defaultTemplateSource
+
+ val scriptBits = JavaAppBashScript.generateScript(defines, template)
+ val script = tmpDir / "tmp" / "bin" / name
+ IO.write(script, scriptBits)
+ // TODO - Better control over this!
+ script.setExecutable(true)
+ Some(script)
+ }
+
+ def makeUniversalBatScript(batTemplate: String)(replacements: Seq[(String, String)], tmpDir: File, name: String, sourceDir: File): Option[File] =
+ if (replacements.isEmpty) None
+ else {
+ val defaultTemplateLocation = sourceDir / "templates" / batTemplate
+ val defaultTemplateSource = getClass.getResource(batTemplate)
+ val template = if (defaultTemplateLocation.exists)
+ defaultTemplateLocation.toURI.toURL
+ else defaultTemplateSource
+
+ val scriptBits = JavaAppBatScript.generateScript(replacements, template)
+ val script = tmpDir / "tmp" / "bin" / (name + ".bat")
+ IO.write(script, scriptBits)
+ Some(script)
+ }
+
+}
+
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala
new file mode 100644
index 000000000..53c14d092
--- /dev/null
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala
@@ -0,0 +1,27 @@
+package com.typesafe.sbt.packager.archetypes
+
+import sbt._
+
+/**
+ * Available settings/tasks for the [[com.typesafe.sbt.packager.archetypes.JavaAppPackaging]]
+ * and all depending archetypes.
+ */
+trait JavaAppKeys {
+
+ val makeBashScript = TaskKey[Option[File]]("makeBashScript", "Creates or discovers the bash script used by this project.")
+ val bashScriptDefines = TaskKey[Seq[String]]("bashScriptDefines", "A list of definitions that should be written to the bash file template.")
+ val bashScriptExtraDefines = TaskKey[Seq[String]]("bashScriptExtraDefines", "A list of extra definitions that should be written to the bash file template.")
+ val bashScriptConfigLocation = TaskKey[Option[String]]("bashScriptConfigLocation", "The location where the bash script will load default argument configuration from.")
+ val batScriptExtraDefines = TaskKey[Seq[String]]("batScriptExtraDefines", "A list of extra definitions that should be written to the bat file template.")
+ val scriptClasspathOrdering = TaskKey[Seq[(File, String)]]("scriptClasspathOrdering", "The order of the classpath used at runtime for the bat/bash scripts.")
+ val projectDependencyArtifacts = TaskKey[Seq[Attributed[File]]]("projectDependencyArtifacts", "The set of exported artifacts from our dependent projects.")
+ val scriptClasspath = TaskKey[Seq[String]]("scriptClasspath", "A list of relative filenames (to the lib/ folder in the distribution) of what to include on the classpath.")
+ val makeBatScript = TaskKey[Option[File]]("makeBatScript", "Creates or discovers the bat script used by this project.")
+ val batScriptReplacements = TaskKey[Seq[(String, String)]]("batScriptReplacements",
+ """|Replacements of template parameters used in the windows bat script.
+ | Default supported templates:
+ | APP_ENV_NAME - the name of the application for defining _HOME variables
+ | APP_NAME - the name of the app
+ | APP_DEFINES - the defines to go into the app
+ | """.stripMargin)
+}
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala
index a35d4eeea..a7c8e5528 100644
--- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala
@@ -2,13 +2,17 @@ package com.typesafe.sbt
package packager
package archetypes
-import Keys._
import sbt._
import sbt.Keys.{ target, mainClass, sourceDirectory, streams }
-import SbtNativePackager._
-import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink, LinuxPlugin }
-import com.typesafe.sbt.packager.debian.DebianPlugin
-import com.typesafe.sbt.packager.rpm.RpmPlugin
+import SbtNativePackager.{ Debian, Rpm, Universal }
+import packager.Keys.{ packageName }
+import linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink, LinuxPlugin }
+import linux.LinuxPlugin.autoImport._
+import debian.DebianPlugin
+import debian.DebianPlugin.autoImport.{ debianMakePreinstScript, debianMakePostinstScript, debianMakePrermScript, debianMakePostrmScript }
+import rpm.RpmPlugin
+import rpm.RpmPlugin.autoImport.{ rpmPre, rpmPost, rpmPostun, rpmPreun, rpmScriptsDirectory }
+import JavaAppPackaging.autoImport.{ bashScriptConfigLocation }
/**
* This class contains the default settings for creating and deploying an archetypical Java application.
@@ -19,14 +23,18 @@ import com.typesafe.sbt.packager.rpm.RpmPlugin
*
* **NOTE: EXPERIMENTAL** This currently only supports debian upstart scripts.
*/
-object JavaServerAppPackaging {
+object JavaServerAppPackaging extends AutoPlugin {
import ServerLoader._
import LinuxPlugin.Users
+ override def requires = JavaAppPackaging
+
+ override def projectSettings = javaServerSettings
+
val ARCHETYPE = "java_server"
/** These settings will be provided by this archetype*/
- def settings: Seq[Setting[_]] = JavaAppPackaging.settings ++ linuxSettings ++ debianSettings ++ rpmSettings
+ def javaServerSettings: Seq[Setting[_]] = linuxSettings ++ debianSettings ++ rpmSettings
protected def etcDefaultTemplateSource: java.net.URL = getClass.getResource("etc-default-template")
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala
index 1301c0570..e305fea8a 100644
--- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala
@@ -3,10 +3,33 @@ package com.typesafe.sbt.packager.archetypes
import sbt._
import com.typesafe.sbt.packager.archetypes.ServerLoader._
+/**
+ * Loads scripts from the resource path that are associated with
+ *
+ * - an archetype
+ * - a sbt.Configuration
+ *
+ *
+ * @example
+ * {{{
+ * val scriptName: String = "postrm"
+ * val archetype: String = "java_server"
+ * val config: Configuration = SbtNativePackager.Debian
+ * val replacements: Seq[(String,String)] = linuxScriptReplacements.value
+ * val template: Option[URL] = None // user defined override
+ *
+ * val scriptContent = JavaServerBashScript(scriptName, archetype, config, replacements, template) getOrElse {
+ * sys.error(s"Couldn't load [scriptName] for config [{config.name}] in archetype [archetype]")
+ * }
+ * IO.write(scriptFile, scriptContent)
+ * }}}
+ * @see [[com.typesafe.sbt.packager.archetypes.JavaServerAppPackaging]]
+ */
object JavaServerBashScript {
/**
*
+ * @param script - script name
* @param templateName - DebianPlugin.Names for maintainer scripts and "start"
* @param loader - which startup system
* @param replacements - default replacements
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala
index 89158fc2e..d6728a47b 100644
--- a/src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala
@@ -3,6 +3,11 @@ package com.typesafe.sbt.packager.archetypes
import java.io.File
import java.net.URL
+/**
+ * Stores the available types of server loaders.
+ *
+ * @note not all packaging systems support all server loaders
+ */
object ServerLoader extends Enumeration {
type ServerLoader = Value
val Upstart = Value("upstart")
diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala
index 76aeeb7eb..f9a7fef28 100644
--- a/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala
@@ -1,5 +1,27 @@
package com.typesafe.sbt.packager.archetypes
+/**
+ * This object provides methods to generate scripts from templates. This involves
+ *
+ *
+ * - procesing - replacing a placeholders with actual values
+ * - TODO: validating - check the script if there are no remaining placeholders
+ *
+ *
+ * @example a bash script can be generated like this
+ * {{{
+ * val template = getClass getResource "template-your-bashscript"
+ * val replacements = Seq("name" -> "your-app", "custom" -> "1")
+ * TemplateWriter.generateScript(template, replacements)
+ * }}}
+ *
+ * @example a bat script can be generated like this
+ * {{{
+ * val template = getClass getResource "template-your-batscript"
+ * val replacements = Seq("name" -> "your-app", "custom" -> "1")
+ * TemplateWriter.generateScript(template, replacements, "\r\n", TemplateWriter.batFriendlyKeySurround)
+ * }}}
+ */
object TemplateWriter {
def defaultCharset: java.nio.charset.Charset = java.nio.charset.Charset.forName("UTF-8")
diff --git a/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala
index d18200fe1..c37969cb2 100644
--- a/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala
@@ -2,26 +2,91 @@ package com.typesafe.sbt
package packager
package debian
-import Keys._
import sbt._
-import sbt.Keys.{ target, name, TaskStreams }
+import sbt.Keys.{ streams, name, version, sourceDirectory, target, packageBin, TaskStreams }
+import packager.Keys._
+import packager.Hashing
+import linux.LinuxPlugin.autoImport.{
+ packageArchitecture,
+ linuxScriptReplacements,
+ linuxPackageMappings,
+ linuxPackageSymlinks,
+ serverLoading,
+ daemonShell
+}
import linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink }
-import linux.Keys.{ linuxScriptReplacements, daemonShell }
-import com.typesafe.sbt.packager.Hashing
-import com.typesafe.sbt.packager.archetypes.TemplateWriter
-import com.typesafe.sbt.packager.linux.LinuxPackageMapping
+import linux.LinuxPlugin.Users
+import universal.Archives
+import archetypes.TemplateWriter
+import SbtNativePackager.{ Universal, Linux }
-trait DebianPlugin extends Plugin with linux.LinuxPlugin with NativePackaging with JDebPackaging {
- val Debian = config("debian") extend Linux
- val UserNamePattern = "^[a-z][-a-z0-9_]*$".r
+/**
+ * == Debian Plugin ==
+ *
+ * This plugin provides the ability to build ''.deb'' packages.
+ *
+ * == Configuration ==
+ *
+ * In order to configure this plugin take a look at the available [[com.typesafe.sbt.packager.debian.DebianKeys]]
+ *
+ * @example Enable the plugin in the `build.sbt`. By default this will use
+ * the native debian packaging implementation [[com.typesafe.sbt.packager.debian.DebianNativePackaging]].
+ * {{{
+ * enablePlugins(DebianPlugin)
+ * }}}
+ *
+ */
+object DebianPlugin extends AutoPlugin with DebianNativePackaging {
+
+ override def requires = linux.LinuxPlugin
+ override def trigger = allRequirements
+
+ object autoImport extends DebianKeys {
+ val Debian = config("debian") extend Linux
+ }
+
+ import autoImport._
+
+ /** Debian constants */
+ object Names {
+ val DebianSource = "debian"
+ val Debian = "DEBIAN"
+
+ //maintainer script names
+ val Postinst = "postinst"
+ val Postrm = "postrm"
+ val Prerm = "prerm"
+ val Preinst = "preinst"
+
+ val Control = "control"
+ val Conffiles = "conffiles"
+
+ val Changelog = "changelog"
+ val Files = "files"
+ }
- import com.typesafe.sbt.packager.universal.Archives
- import DebianPlugin.Names
- import DebianPlugin.defaultMaintainerScript
- import linux.LinuxPlugin.Users
- import SbtNativePackager.Universal
+ val CHOWN_REPLACEMENT = "chown-paths"
- def debianSettings: Seq[Setting[_]] = Seq(
+ def defaultMaintainerScript(name: String, replacements: Seq[(String, String)], tmpDir: File): Option[File] = {
+ val url = Option(getClass getResource s"$name-template")
+ url map { source =>
+ val scriptBits = TemplateWriter.generateScript(source, replacements)
+ val script = tmpDir / "tmp" / "etc" / "default" / name
+ IO.write(script, scriptBits)
+ script
+ }
+ }
+
+ // TODO maybe we can put settings/debiansettings together
+ /**
+ * Enables native packaging by default
+ */
+ override lazy val projectSettings = settings ++ inConfig(Debian)(debianSettings) ++ debianNativeSettings
+
+ /**
+ * the default debian settings for the debian namespaced settings
+ */
+ private def settings = Seq(
/* ==== Debian default settings ==== */
debianPriority := "optional",
debianSection := "java",
@@ -51,110 +116,124 @@ trait DebianPlugin extends Plugin with linux.LinuxPlugin with NativePackaging wi
debianMaintainerScripts <++= (debianMakePrermScript, debianControlScriptsDirectory) map scriptMapping(Names.Prerm),
debianMaintainerScripts <++= (debianMakePreinstScript, debianControlScriptsDirectory) map scriptMapping(Names.Preinst),
debianMaintainerScripts <++= (debianMakePostinstScript, debianControlScriptsDirectory) map scriptMapping(Names.Postinst),
- debianMaintainerScripts <++= (debianMakePostrmScript, debianControlScriptsDirectory) map scriptMapping(Names.Postrm)) ++
- /* ==== Debian scoped settings ==== */
- inConfig(Debian)(
- Seq(
- packageArchitecture := "all",
- debianPackageInfo <<=
- (packageName, version, maintainer, packageSummary, packageDescription) apply PackageInfo,
- debianPackageMetadata <<=
- (debianPackageInfo, debianPriority, packageArchitecture, debianSection,
- debianPackageDependencies, debianPackageRecommends) apply PackageMetaData,
- debianPackageInstallSize <<= linuxPackageMappings map { mappings =>
- (for {
- LinuxPackageMapping(files, _, zipped) <- mappings
- (file, _) <- files
- if !file.isDirectory && file.exists
- // TODO - If zipped, heuristically figure out a reduction factor.
- } yield file.length).sum / 1024
- },
- 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
+ debianMaintainerScripts <++= (debianMakePostrmScript, debianControlScriptsDirectory) map scriptMapping(Names.Postrm))
+
+ /**
+ * == Debian scoped settings ==
+ * Everything used inside the debian scope
+ *
+ */
+ private def debianSettings: Seq[Setting[_]] = inConfig(Debian)(
+ Seq(
+ packageArchitecture := "all",
+ debianPackageInfo <<= (packageName, version, maintainer, packageSummary, packageDescription) apply PackageInfo,
+ debianPackageMetadata <<= (debianPackageInfo, debianPriority, packageArchitecture, debianSection,
+ debianPackageDependencies, debianPackageRecommends) apply PackageMetaData,
+ debianPackageInstallSize <<= linuxPackageMappings map { mappings =>
+ (for {
+ LinuxPackageMapping(files, _, zipped) <- mappings
+ (file, _) <- files
+ if !file.isDirectory && file.exists
+ // TODO - If zipped, heuristically figure out a reduction factor.
+ } yield file.length).sum / 1024
+ },
+ 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)
- chmod(cfile, "0644")
- cfile
- },
- debianConffilesFile <<= (linuxPackageMappings, target) map {
- (mappings, dir) =>
- val cfile = dir / Names.Debian / Names.Conffiles
- val conffiles = for {
- LinuxPackageMapping(files, meta, _) <- mappings
- if meta.config != "false"
- (file, name) <- files
- if file.isFile
- } yield name
- IO.writeLines(cfile, conffiles)
- chmod(cfile, "0644")
- cfile
- },
- debianMD5sumsFile <<= (debianExplodedPackage, target) map {
- (mappings, dir) =>
- val md5file = dir / Names.Debian / "md5sums"
- val md5sums = for {
- (file, name) <- (dir.*** --- dir pair relativeTo(dir))
- if file.isFile
- if !(name startsWith Names.Debian)
- if !(name contains "debian-binary")
- // TODO - detect symlinks with Java7 (when we can) rather than hackery...
- if file.getCanonicalPath == file.getAbsolutePath
- fixedName = if (name startsWith "/") name drop 1 else name
- } yield Hashing.md5Sum(file) + " " + fixedName
- IO.writeLines(md5file, md5sums)
- chmod(md5file, "0644")
- md5file
+ }
+ val cfile = dir / Names.Debian / Names.Control
+ IO.write(cfile, data.makeContent(size), java.nio.charset.Charset.defaultCharset)
+ chmod(cfile, "0644")
+ cfile
+ },
+ debianConffilesFile <<= (linuxPackageMappings, target) map {
+ (mappings, dir) =>
+ val cfile = dir / Names.Debian / Names.Conffiles
+ val conffiles = for {
+ LinuxPackageMapping(files, meta, _) <- mappings
+ if meta.config != "false"
+ (file, name) <- files
+ if file.isFile
+ } yield name
+ IO.writeLines(cfile, conffiles)
+ chmod(cfile, "0644")
+ cfile
+ },
+ debianMD5sumsFile <<= (debianExplodedPackage, target) map {
+ (mappings, dir) =>
+ val md5file = dir / Names.Debian / "md5sums"
+ val md5sums = for {
+ (file, name) <- (dir.*** --- dir pair relativeTo(dir))
+ if file.isFile
+ if !(name startsWith Names.Debian)
+ if !(name contains "debian-binary")
+ // TODO - detect symlinks with Java7 (when we can) rather than hackery...
+ if file.getCanonicalPath == file.getAbsolutePath
+ fixedName = if (name startsWith "/") name drop 1 else name
+ } yield Hashing.md5Sum(file) + " " + fixedName
+ IO.writeLines(md5file, md5sums)
+ chmod(md5file, "0644")
+ md5file
+ },
+ debianMakeChownReplacements <<= (linuxPackageMappings, streams) map makeChownReplacements,
+ debianExplodedPackage <<= (linuxPackageMappings, debianControlFile, debianMaintainerScripts, debianConffilesFile, debianChangelog, daemonShell in Linux,
+ linuxScriptReplacements, debianMakeChownReplacements, linuxPackageSymlinks, target, streams)
+ map { (mappings, _, maintScripts, _, changelog, shell, replacements, chown, symlinks, t, streams) =>
+
+ // Create files and directories
+ mappings foreach {
+ case LinuxPackageMapping(paths, perms, zipped) =>
+ val (dirs, files) = paths.partition(_._1.isDirectory)
+ dirs map {
+ case (_, name) => t / name
+ } foreach { targetDir =>
+ targetDir mkdirs ()
+ chmod(targetDir, perms.permissions)
+ }
+
+ files map {
+ case (file, name) => (file, t / name)
+ } foreach {
+ case (source, target) => copyAndFixPerms(source, target, perms, zipped)
+ }
+ }
+ // Now generate relative symlinks
+ LinuxSymlink.makeSymLinks(symlinks, t, false)
+
+ // Put the maintainer files in `dir / "DEBIAN"` named as specified.
+ // Valid values for the name are preinst,postinst,prerm,postrm
+ for ((file, name) <- maintScripts) {
+ val targetFile = t / Names.Debian / name
+ copyAndFixPerms(file, targetFile, LinuxFileMetaData())
+ filterAndFixPerms(targetFile, chown +: replacements, LinuxFileMetaData())
+ }
+ t
},
- debianMakeChownReplacements <<= (linuxPackageMappings, streams) map makeChownReplacements,
- debianExplodedPackage <<= (linuxPackageMappings, debianControlFile, debianMaintainerScripts, debianConffilesFile, debianChangelog, daemonShell in Linux,
- linuxScriptReplacements, debianMakeChownReplacements, linuxPackageSymlinks, target, streams)
- map { (mappings, _, maintScripts, _, changelog, shell, replacements, chown, symlinks, t, streams) =>
-
- // Create files and directories
- mappings foreach {
- case LinuxPackageMapping(paths, perms, zipped) =>
- val (dirs, files) = paths.partition(_._1.isDirectory)
- dirs map {
- case (_, name) => t / name
- } foreach { targetDir =>
- targetDir mkdirs ()
- chmod(targetDir, perms.permissions)
- }
-
- files map {
- case (file, name) => (file, t / name)
- } foreach {
- case (source, target) => copyAndFixPerms(source, target, perms, zipped)
- }
- }
- // Now generate relative symlinks
- LinuxSymlink.makeSymLinks(symlinks, t, false)
-
- // Put the maintainer files in `dir / "DEBIAN"` named as specified.
- // Valid values for the name are preinst,postinst,prerm,postrm
- for ((file, name) <- maintScripts) {
- val targetFile = t / Names.Debian / name
- copyAndFixPerms(file, targetFile, LinuxFileMetaData())
- filterAndFixPerms(targetFile, chown +: replacements, LinuxFileMetaData())
- }
- t
- },
- // Setting the packaging strategy
- packageBin <<= debianNativePackaging,
- // Replacement for ${{header}} as debian control scripts are bash scripts
- linuxScriptReplacements += ("header" -> "#!/bin/sh\n")
-
- // Adding package specific implementation settings
- ) ++ debianNativeSettings ++ debianJDebSettings)
-
- /* ============================================= */
- /* ========== Debian Helper Methods ============ */
- /* ============================================= */
+ // Replacement for ${{header}} as debian control scripts are bash scripts
+ linuxScriptReplacements += ("header" -> "#!/bin/sh\n")
+
+ // Adding package specific implementation settings
+ ))
+
+}
+
+/**
+ * == Debian Helper Methods ==
+ *
+ * This trait provides a set of helper methods for debian packaging
+ * implementations.
+ *
+ * Most of the methods are for java 6 file permission handling and
+ * debian script adjustements.
+ *
+ */
+trait DebianPluginLike {
+
+ /** validate group and usernames for debian systems */
+ val UserNamePattern = "^[a-z][-a-z0-9_]*$".r
private[debian] final def copyAndFixPerms(from: File, to: File, perms: LinuxFileMetaData, zipped: Boolean = false): Unit = {
if (zipped) {
@@ -218,14 +297,6 @@ trait DebianPlugin extends Plugin with linux.LinuxPlugin with NativePackaging wi
}
}
- private[debian] def archiveFilename(appName: String, version: String, arch: String): String = {
- appName + "_" + version + "_" + arch + ".deb"
- }
-
- private[debian] def changesFilename(appName: String, version: String, arch: String): String = {
- appName + "_" + version + "_" + arch + ".changes"
- }
-
/**
* Debian assumes the application chowns the necessary files and directories in the
* control scripts (Pre/Postinst).
@@ -239,12 +310,12 @@ trait DebianPlugin extends Plugin with linux.LinuxPlugin with NativePackaging wi
* @return (CHOWN_REPLACEMENT -> ".. list of chown commands")
*/
private[debian] def makeChownReplacements(mappings: Seq[LinuxPackageMapping], streams: TaskStreams): (String, String) = {
- // how to create the chownCmd. TODO maybe configurable?
+ // how to create the chownCmd. TODO maybe configurable?
def chownCmd(user: String, group: String)(path: String): String = s"chown $user:$group $path"
val header = "# Chown definitions created by SBT Native Packager\n"
- // Check for non root user/group and create chown commands
- // filter all root mappings, map to (user,group) key, group by, append everything
+ // Check for non root user/group and create chown commands
+ // filter all root mappings, map to (user,group) key, group by, append everything
val chowns = mappings filter {
case LinuxPackageMapping(_, LinuxFileMetaData(Users.Root, Users.Root, _, _, _), _) => false
case _ => true
@@ -255,45 +326,18 @@ trait DebianPlugin extends Plugin with linux.LinuxPlugin with NativePackaging wi
validateUserGroupNames(user, streams)
validateUserGroupNames(group, streams)
val chown = chownCmd(user, group) _
- // remove key, flatten it and then use mapping path (_.2) to create chown command
+ // remove key, flatten it and then use mapping path (_.2) to create chown command
pathList.map(_._2).flatten map (m => chown(m._2))
}
val replacement = header :: chowns.flatten.toList mkString "\n"
DebianPlugin.CHOWN_REPLACEMENT -> replacement
}
-}
-
-/**
- * Contains debian specific constants
- */
-object DebianPlugin {
- object Names {
- val DebianSource = "debian"
- val Debian = "DEBIAN"
-
- //maintainer script names
- val Postinst = "postinst"
- val Postrm = "postrm"
- val Prerm = "prerm"
- val Preinst = "preinst"
-
- val Control = "control"
- val Conffiles = "conffiles"
-
- val Changelog = "changelog"
- val Files = "files"
+ private[debian] def archiveFilename(appName: String, version: String, arch: String): String = {
+ appName + "_" + version + "_" + arch + ".deb"
}
- val CHOWN_REPLACEMENT = "chown-paths"
-
- def defaultMaintainerScript(name: String, replacements: Seq[(String, String)], tmpDir: File): Option[File] = {
- val url = Option(getClass getResource s"$name-template")
- url map { source =>
- val scriptBits = TemplateWriter.generateScript(source, replacements)
- val script = tmpDir / "tmp" / "etc" / "default" / name
- IO.write(script, scriptBits)
- script
- }
+ private[debian] def changesFilename(appName: String, version: String, arch: String): String = {
+ appName + "_" + version + "_" + arch + ".changes"
}
}
diff --git a/src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala b/src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala
index 12e289840..ebb11305b 100644
--- a/src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala
@@ -2,39 +2,45 @@ package com.typesafe.sbt
package packager
package debian
-import Keys._
import sbt._
-import sbt.Keys.{ target, normalizedName }
-import linux.{ LinuxSymlink }
-import com.typesafe.sbt.packager.linux.LinuxPackageMapping
+import sbt.Keys.{ target, normalizedName, version, streams, mappings, packageBin }
+import linux.{ LinuxSymlink, LinuxPackageMapping }
+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._
-import DebianPlugin.Names
+import DebianPlugin.{ Names }
+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
- *
- * {{
- * packageBin in Debian <<= debianJDebPackaging in Debian
- * }}
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(JDebPackaging)
+ * }}}
*
* @author Nepomuk Seiler
- * @see https://github.com/tcurdt/jdeb/blob/master/src/main/java/org/vafer/jdeb/maven/DebMojo.java#L503
+ * @see [[https://github.com/tcurdt/jdeb/blob/master/src/main/java/org/vafer/jdeb/maven/DebMojo.java#L503]]
*
*/
-trait JDebPackaging { this: DebianPlugin with linux.LinuxPlugin =>
+object JDebPackaging extends AutoPlugin with DebianPluginLike {
+
+ override def requires = DebianPlugin
+
+ override lazy val projectSettings = inConfig(Debian)(jdebSettings)
- private[debian] def debianJDebSettings: Seq[Setting[_]] = Seq(
+ def jdebSettings = Seq(
/**
* Depends on the 'debianExplodedPackage' task as this creates all the files
* which are defined in the mappings.
*/
- debianJDebPackaging <<= (debianExplodedPackage, linuxPackageMappings, linuxPackageSymlinks,
+ packageBin <<= (debianExplodedPackage, linuxPackageMappings, linuxPackageSymlinks,
debianControlFile, debianMaintainerScripts, debianConffilesFile,
normalizedName, version, packageArchitecture, target, streams) map {
(_, mappings, symlinks, controlfile, controlscripts, conffile,
diff --git a/src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala
index 2475f1527..93fdf5db4 100644
--- a/src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala
@@ -16,8 +16,6 @@ trait DebianKeys {
val debianPackageMetadata = SettingKey[PackageMetaData]("debian-package-metadata", "Meta data used when constructing a debian package.")
val debianChangelog = SettingKey[Option[File]]("debian-changelog", "The changelog for this deb file")
// Package building
- val debianNativePackaging = TaskKey[File]("debian-packaging-native", "Builds the debian package with native cli tools")
- val debianJDebPackaging = TaskKey[File]("debian-packaging-jdeb", "Builds the debian package with jdeb (java-based)")
val debianControlFile = TaskKey[File]("debian-control-file", "Makes the debian package control file.")
val debianMaintainerScripts = TaskKey[Seq[(File, String)]]("debian-maintainer-scripts", "Makes the debian maintainer scripts.")
@@ -42,30 +40,5 @@ trait DebianKeys {
val debianMakePostrmScript = TaskKey[Option[File]]("makePostrmScript", "Creates or discovers the postrm script used by this project")
val debianMakeChownReplacements = TaskKey[(String, String)]("debianMakeChownReplacements", "Creates the chown commands for correct own files and directories")
-}
-
-/** Keys used for Debian specific settings. */
-object Keys extends DebianKeys {
- // Metadata keys
- def name = sbt.Keys.name
- def packageName = linux.Keys.packageName
- def executableScriptName = linux.Keys.executableScriptName
- def version = sbt.Keys.version
- def maintainer = linux.Keys.maintainer
- def packageArchitecture = linux.Keys.packageArchitecture
- def packageDescription = linux.Keys.packageDescription
- def packageSummary = linux.Keys.packageSummary
-
- // Package building
- def sourceDirectory = sbt.Keys.sourceDirectory
- def linuxPackageMappings = linux.Keys.linuxPackageMappings
- def linuxPackageSymlinks = linux.Keys.linuxPackageSymlinks
- def packageBin = sbt.Keys.packageBin
- def target = sbt.Keys.target
- def streams = sbt.Keys.streams
-
- //init script parameters
- def serverLoading = linux.Keys.serverLoading
-
val debianPackageInstallSize = TaskKey[Long]("debian-installed-size")
-}
+}
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/debian/NativePackaging.scala b/src/main/scala/com/typesafe/sbt/packager/debian/NativePackaging.scala
index ce922a3f7..2fdc47e6b 100644
--- a/src/main/scala/com/typesafe/sbt/packager/debian/NativePackaging.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/debian/NativePackaging.scala
@@ -2,32 +2,47 @@ package com.typesafe.sbt
package packager
package debian
-import Keys._
import sbt._
-import sbt.Keys.{ target, name, TaskStreams }
+import sbt.Keys.{ packageBin, target, name, version, streams }
+import packager.Hashing
+import packager.archetypes.TemplateWriter
import linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink }
-import linux.Keys.{ linuxScriptReplacements, daemonShell }
-import com.typesafe.sbt.packager.Hashing
-import com.typesafe.sbt.packager.archetypes.TemplateWriter
+import linux.LinuxPlugin.autoImport.packageArchitecture
+
+import DebianPlugin.autoImport._
/**
+ * == Native Packaging ==
+ *
* This provides a dpgk based implementation for debian packaging.
- * Your machine must have dpkg installed to use this.
*
- * {{
- * packageBin in Debian <<= debianNativePackaging in Debian
- * }}
+ * == Requirements ==
+ *
+ * You need the debian dpkg toolchain installed. This includes
+ *
+ * - fakeroot
+ * - dpkg-deb
+ * - dpkg-genchanges
+ *
*
*
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(DebianNativePackaging)
+ * }}}
*
*/
-trait NativePackaging { this: DebianPlugin with linux.LinuxPlugin =>
+trait DebianNativePackaging extends DebianPluginLike {
import com.typesafe.sbt.packager.universal.Archives
import DebianPlugin.Names
import linux.LinuxPlugin.Users
- private[debian] def debianNativeSettings: Seq[Setting[_]] = Seq(
+ /**
+ * Using the native installed dpkg-build tools to build the debian
+ * package.
+ */
+ private[debian] def debianNativeSettings: Seq[Setting[_]] = inConfig(Debian)(Seq(
genChanges <<= (packageBin, target, debianChangelog, name, version, debianPackageMetadata) map {
(pkg, tdir, changelog, name, version, data) =>
changelog match {
@@ -66,7 +81,7 @@ trait NativePackaging { this: DebianPlugin with linux.LinuxPlugin =>
},
/** Implementation of the actual packaging */
- debianNativePackaging <<= (debianExplodedPackage, debianMD5sumsFile, debianSection, debianPriority, name, version, packageArchitecture, target, streams) map {
+ packageBin <<= (debianExplodedPackage, debianMD5sumsFile, debianSection, debianPriority, name, version, packageArchitecture, target, streams) map {
(pkgdir, _, section, priority, name, version, arch, tdir, s) =>
s.log.info("Building debian package with native implementation")
// Make the package. We put this in fakeroot, so we can build the package with root owning files.
@@ -77,22 +92,16 @@ trait NativePackaging { this: DebianPlugin with linux.LinuxPlugin =>
}
tdir / ".." / archive
}
- )
+ ))
}
-/**
- * This provides the task for building a debian packaging with
- * native tools
- *
- */
-object Native {
-
- /* static assets definitions */
+object DebianNativePackaging {
private[debian] def postinstGroupaddTemplateSource: java.net.URL = getClass.getResource("postinst-groupadd")
private[debian] def postinstUseraddTemplateSource: java.net.URL = getClass.getResource("postinst-useradd")
private[debian] def postinstChownTemplateSource: java.net.URL = getClass.getResource("postinst-chown")
private[debian] def postrmPurgeTemplateSource: java.net.URL = getClass.getResource("postrm-purge")
private[debian] def headerSource: java.net.URL = getClass.getResource("header")
-}
\ No newline at end of file
+}
+
diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala
index 60baa8c0c..03b4a09bb 100644
--- a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala
@@ -1,12 +1,111 @@
package com.typesafe.sbt
package packager
package docker
-import Keys._
-import universal._
+
import sbt._
+import sbt.Keys.{
+ name,
+ version,
+ target,
+ mappings,
+ publish,
+ publishLocal,
+ publishArtifact,
+ sourceDirectory,
+ streams,
+ cacheDirectory
+}
+import packager.Keys._
+import linux.LinuxPlugin.autoImport.{ daemonUser, defaultLinuxInstallLocation }
+import universal.UniversalPlugin.autoImport.stage
+import SbtNativePackager.Universal
+
+/**
+ * == Docker Plugin ==
+ *
+ * This plugin helps you build docker containers.
+ *
+ * == Configuration ==
+ *
+ * In order to configure this plugin take a look at the available [[com.typesafe.sbt.packager.docker.DockerKeys]]
+ *
+ * == Requirements ==
+ *
+ * You need docker to have docker installed on your system and be able to execute commands.
+ * Check with a single command:
+ *
+ * {{{
+ * docker version
+ * }}}
+ *
+ * Future versions of the Docker Plugin may use the REST API, so you don't need docker installed
+ * locally.
+ *
+ * @note this plugin is not inteded to build very customizable docker images, but turn your mappings
+ * configuration in a docker image with almost no ''any'' configuration.
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(DockerPlugin)
+ * }}}
+ */
+object DockerPlugin extends AutoPlugin {
+
+ object autoImport extends DockerKeys {
+ val Docker = config("docker") extend Universal
+ }
-trait DockerPlugin extends Plugin with UniversalPlugin {
- val Docker = config("docker") extend Universal
+ import autoImport._
+
+ override def requires = universal.UniversalPlugin
+
+ override def trigger = allRequirements
+
+ override lazy val projectSettings = Seq(
+ dockerBaseImage := "dockerfile/java:latest",
+ name in Docker <<= name,
+ packageName in Docker <<= packageName,
+ executableScriptName in Docker <<= executableScriptName,
+ dockerRepository := None,
+ dockerUpdateLatest := false,
+ sourceDirectory in Docker <<= sourceDirectory apply (_ / "docker"),
+ target in Docker <<= target apply (_ / "docker")
+
+ ) ++ mapGenericFilesToDocker ++ inConfig(Docker)(Seq(
+ daemonUser := "daemon",
+ defaultLinuxInstallLocation := "/opt/docker",
+ dockerExposedPorts := Seq(),
+ dockerExposedVolumes := Seq(),
+ dockerPackageMappings <<= (sourceDirectory) map { dir =>
+ MappingsHelper contentOf dir
+ },
+ mappings <++= dockerPackageMappings,
+ stage <<= (dockerGenerateConfig, dockerGenerateContext, streams) map {
+ (dockerfile, contextDir, s) =>
+ s.log.success("created docker file: " + dockerfile.getPath)
+ contextDir
+ },
+ dockerGenerateConfig <<= (dockerBaseImage, defaultLinuxInstallLocation,
+ maintainer, daemonUser, executableScriptName,
+ dockerExposedPorts, dockerExposedVolumes, target) map generateDockerConfig,
+ dockerGenerateContext := Stager.stage("docker")(streams.value, target.value / "files", mappings.value),
+ dockerTarget <<= (dockerRepository, packageName, version) map {
+ (repo, name, version) =>
+ repo.map(_ + "/").getOrElse("") + name + ":" + version
+ },
+ publishLocal <<= (dockerGenerateConfig, dockerGenerateContext, dockerTarget, dockerUpdateLatest, streams) map {
+ (config, _, target, updateLatest, s) =>
+ publishLocalDocker(config, target, updateLatest, s.log)
+ },
+ publish <<= (publishLocal, dockerTarget, dockerUpdateLatest, streams) map {
+ (_, target, updateLatest, s) =>
+ publishDocker(target, s.log)
+ if (updateLatest) {
+ val name = target.substring(0, target.lastIndexOf(":")) + ":latest"
+ publishDocker(name, s.log)
+ }
+ }
+ ))
private[this] final def makeDockerContent(dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, execScript: String, exposedPorts: Seq[Int], exposedVolumes: Seq[String]) = {
val headerCommands = Seq(
@@ -155,52 +254,4 @@ trait DockerPlugin extends Plugin with UniversalPlugin {
log.info("Published image " + tag)
}
- def dockerSettings: Seq[Setting[_]] = Seq(
- dockerBaseImage := "dockerfile/java:latest",
- name in Docker <<= name,
- packageName in Docker <<= packageName,
- executableScriptName in Docker <<= executableScriptName,
- dockerRepository := None,
- dockerUpdateLatest := false,
- sourceDirectory in Docker <<= sourceDirectory apply (_ / "docker"),
- target in Docker <<= target apply (_ / "docker"),
-
- // TODO this must be changed, when there is a setting for the startScripts name
- dockerGenerateConfig <<=
- (dockerBaseImage in Docker, defaultLinuxInstallLocation in Docker, maintainer in Docker, daemonUser in Docker,
- executableScriptName /* this is not scoped!*/ , dockerExposedPorts in Docker, dockerExposedVolumes in Docker, target in Docker) map
- generateDockerConfig
- ) ++ mapGenericFilesToDocker ++ inConfig(Docker)(Seq(
- daemonUser := "daemon",
- defaultLinuxInstallLocation := "/opt/docker",
- dockerExposedPorts := Seq(),
- dockerExposedVolumes := Seq(),
- dockerPackageMappings <<= (sourceDirectory) map { dir =>
- MappingsHelper contentOf dir
- },
- mappings <++= dockerPackageMappings,
- stage <<= (dockerGenerateConfig, dockerGenerateContext) map { (configFile, contextDir) => () },
- dockerGenerateContext <<= (cacheDirectory, mappings, target) map {
- (cacheDirectory, mappings, t) =>
- val contextDir = t / "files"
- stageFiles("docker")(cacheDirectory, contextDir, mappings)
- contextDir
- },
- dockerTarget <<= (dockerRepository, packageName, version) map {
- (repo, name, version) =>
- repo.map(_ + "/").getOrElse("") + name + ":" + version
- },
- publishLocal <<= (dockerGenerateConfig, dockerGenerateContext, dockerTarget, dockerUpdateLatest, streams) map {
- (config, _, target, updateLatest, s) =>
- publishLocalDocker(config, target, updateLatest, s.log)
- },
- publish <<= (publishLocal, dockerTarget, dockerUpdateLatest, streams) map {
- (_, target, updateLatest, s) =>
- publishDocker(target, s.log)
- if (updateLatest) {
- val name = target.substring(0, target.lastIndexOf(":")) + ":latest"
- publishDocker(name, s.log)
- }
- }
- ))
}
diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala
index 753bf0351..03ef6b015 100644
--- a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala
@@ -4,6 +4,9 @@ package docker
import sbt._
+/**
+ * Docker settings
+ */
trait DockerKeys {
val dockerGenerateConfig = TaskKey[File]("docker-generate-config", "Generates configuration file for Docker.")
val dockerGenerateContext = TaskKey[File]("docker-generate-context", "Generates context directory for Docker.")
@@ -17,21 +20,3 @@ trait DockerKeys {
val dockerUpdateLatest = SettingKey[Boolean]("dockerUpdateLatest", "Set to update latest tag")
}
-object Keys extends DockerKeys {
- def cacheDirectory = sbt.Keys.cacheDirectory
- def mappings = sbt.Keys.mappings
- def name = sbt.Keys.name
- def packageName = universal.Keys.packageName
- def executableScriptName = universal.Keys.executableScriptName
- def stage = universal.Keys.stage
- def publish = sbt.Keys.publish
- def publishArtifact = sbt.Keys.publishArtifact
- def publishLocal = sbt.Keys.publishLocal
- def sourceDirectory = sbt.Keys.sourceDirectory
- def streams = sbt.Keys.streams
- def target = sbt.Keys.target
- def version = sbt.Keys.version
- def defaultLinuxInstallLocation = packager.Keys.defaultLinuxInstallLocation
- def daemonUser = linux.Keys.daemonUser
- def maintainer = linux.Keys.maintainer
-}
diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala b/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala
index afc76608d..3165141dc 100644
--- a/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala
@@ -2,14 +2,51 @@ package com.typesafe.sbt
package packager
package docker
+/**
+ * a single line in a dockerfile. See subclasses for more detail
+ *
+ */
trait CmdLike {
+
+ /**
+ * Creates the command which can be placed inside a Dockerfile.
+ *
+ * @return the docker command
+ */
def makeContent: String
}
+/**
+ * Executable command
+ *
+ * @example {{{
+ * ExecCmd("RUN", "chown", "-R", daemonUser, ".")
+ * }}}
+ *
+ * @example {{{
+ * ExecCmd("ENTRYPOINT", "bin/%s" format execScript),
+ * }}}
+ *
+ * @example {{{
+ * ExecCmd("CMD")
+ * }}}
+ *
+ * @example {{{
+ * ExecCmd("VOLUME", exposedVolumes: _*)
+ * }}}
+ */
case class ExecCmd(cmd: String, args: String*) extends CmdLike {
def makeContent = "%s [%s]\n" format (cmd, args.map('"' + _ + '"').mkString(", "))
}
+/**
+ * An arbitrary command
+ *
+ * @example
+ * {{{
+ * val add = Cmd("ADD", "src/resource/LICENSE.txt /opt/docker/LICENSE.txt")
+ * }}}
+ */
case class Cmd(cmd: String, arg: String) extends CmdLike {
def makeContent = "%s %s\n" format (cmd, arg)
}
diff --git a/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala
index a1023608a..16ef46871 100644
--- a/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala
@@ -6,11 +6,8 @@ import sbt._
import com.typesafe.sbt.packager.archetypes.ServerLoader.ServerLoader
/** Linux packaging generic build targets. */
-trait Keys {
+trait LinuxKeys {
val packageArchitecture = SettingKey[String]("package-architecture", "The architecture used for this linux package.")
- val packageSummary = SettingKey[String]("package-summary", "Summary of the contents of a linux package.")
- val packageDescription = SettingKey[String]("package-description", "The description of the package. Used when searching.")
- val maintainer = SettingKey[String]("maintainer", "The name/email address of a maintainer for the native package.")
val daemonUser = SettingKey[String]("daemon-user", "User to start application daemon")
val daemonGroup = SettingKey[String]("daemon-group", "Group to start application daemon")
val daemonShell = SettingKey[String]("daemon-shell", "Shell provided for the daemon user")
@@ -42,11 +39,10 @@ trait Keys {
""".stripMargin)
val makeEtcDefault = TaskKey[Option[File]]("makeEtcDefault", "Creates or discovers the /etc/default/ script")
-}
-object Keys extends Keys {
- def name = sbt.Keys.name
- def packageName = packager.Keys.packageName
- def executableScriptName = packager.Keys.executableScriptName
- def sourceDirectory = sbt.Keys.sourceDirectory
-}
\ No newline at end of file
+ val defaultLinuxInstallLocation = SettingKey[String]("defaultLinuxInstallLocation", "The location where we will install generic linux packages.")
+ val defaultLinuxLogsLocation = SettingKey[String]("defaultLinuxLogsLocation", "The location where application logs will be stored.")
+ val defaultLinuxConfigLocation = SettingKey[String]("defaultLinuxConfigLocation", "The location where application config files will be stored")
+ val defaultLinuxStartScriptLocation = SettingKey[String]("defaultLinuxStartScriptLocation", "The location where start script for server application will be stored")
+
+}
diff --git a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxMappingDSL.scala b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxMappingDSL.scala
new file mode 100644
index 000000000..bfdbe2d13
--- /dev/null
+++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxMappingDSL.scala
@@ -0,0 +1,34 @@
+package com.typesafe.sbt.packager.linux
+
+import sbt._
+
+trait LinuxMappingDSL {
+
+ /** DSL for packaging files into .deb */
+ def packageMapping(files: (File, String)*) = LinuxPackageMapping(files)
+
+ /**
+ * @param dir - use some directory, e.g. target.value
+ * @param files
+ */
+ def packageTemplateMapping(files: String*)(dir: File = new File(sys.props("java.io.tmpdir"))) = LinuxPackageMapping(files map ((dir, _)))
+
+ // TODO can the packager.MappingsHelper be used here?
+ /**
+ * @see #mapDirectoryAndContents
+ * @param dirs - directories to map
+ */
+ def packageDirectoryAndContentsMapping(dirs: (File, String)*) = LinuxPackageMapping(mapDirectoryAndContents(dirs: _*))
+
+ /**
+ * This method includes files and directories.
+ *
+ * @param dirs - directories to map
+ */
+ def mapDirectoryAndContents(dirs: (File, String)*): Seq[(File, String)] = for {
+ (src, dest) <- dirs
+ path <- (src ***).get
+ } yield path -> path.toString.replaceFirst(src.toString, dest)
+}
+
+object Mapper extends LinuxMappingDSL
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPackageMapping.scala b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPackageMapping.scala
index 1a7915354..5c91d28f0 100644
--- a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPackageMapping.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPackageMapping.scala
@@ -28,7 +28,7 @@ case class LinuxPackageMapping(
def withGroup(group: String) = copy(fileData = fileData withGroup group)
def withPerms(perms: String) = copy(fileData = fileData withPerms perms)
def withConfig(c: String = "true") = copy(fileData = fileData withConfig c)
- def withContents() = copy(mappings = SbtNativePackager.mapDirectoryAndContents(mappings.toSeq: _*))
+ def withContents() = copy(mappings = Mapper.mapDirectoryAndContents(mappings.toSeq: _*))
def asDocs() = copy(fileData = fileData asDocs ())
/** Modifies the current package mapping to have gzipped data. */
diff --git a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala
index c741e245a..ff9462267 100644
--- a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala
@@ -2,25 +2,46 @@ package com.typesafe.sbt
package packager
package linux
-import Keys._
import sbt._
-import sbt.Keys.{ normalizedName }
-import packager.Keys.{
- defaultLinuxInstallLocation,
- defaultLinuxConfigLocation,
- defaultLinuxLogsLocation
-}
-import com.typesafe.sbt.packager.linux.LinuxPlugin.Users
-import com.typesafe.sbt.packager.archetypes.{ ServerLoader, TemplateWriter }
+import sbt.Keys.{ name, normalizedName, mappings, sourceDirectory }
+import linux.LinuxPlugin.Users
+import packager.Keys._
+import packager.archetypes.{ ServerLoader, TemplateWriter }
+import SbtNativePackager.Universal
/**
- * Plugin trait containing all the generic values used for
+ * Plugin containing all the generic values used for
* packaging linux software.
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(LinuxPlugin)
+ * }}}
*/
-trait LinuxPlugin extends Plugin {
- // TODO - is this needed
- val Linux = config("linux")
+object LinuxPlugin extends AutoPlugin {
+
+ override def requires = universal.UniversalPlugin
+ override def trigger = allRequirements
+ override lazy val projectSettings = linuxSettings ++ mapGenericFilesToLinux
+
+ object autoImport extends LinuxKeys with LinuxMappingDSL {
+ val Linux = config("linux")
+ }
+
+ import autoImport._
+
+ /** default users available for */
+ object Users {
+ val Root = "root"
+ }
+ /** key for replacement in linuxScriptReplacements */
+ val CONTROL_FUNCTIONS = "control-functions"
+ def controlFunctions(): URL = getClass getResource CONTROL_FUNCTIONS
+
+ /**
+ * default linux settings
+ */
def linuxSettings: Seq[Setting[_]] = Seq(
linuxPackageMappings := Seq.empty,
linuxPackageSymlinks := Seq.empty,
@@ -66,31 +87,51 @@ trait LinuxPlugin extends Plugin {
)
- /** DSL for packaging files into .deb */
- def packageMapping(files: (File, String)*) = LinuxPackageMapping(files)
-
/**
- * @param dir - use some directory, e.g. target.value
- * @param files
+ * maps the `mappings` content into `linuxPackageMappings` and
+ * `linuxPackageSymlinks`.
*/
- def packageTemplateMapping(files: String*)(dir: File = new File(sys.props("java.io.tmpdir"))) = LinuxPackageMapping(files map ((dir, _)))
+ def mapGenericFilesToLinux: Seq[Setting[_]] = Seq(
+
+ // First we look at the src/linux files
+ linuxPackageMappings <++= (sourceDirectory in Linux) map { dir =>
+ mapGenericMappingsToLinux(MappingsHelper contentOf dir, Users.Root, Users.Root)(identity)
+ },
+ // Now we look at the src/universal files.
+ linuxPackageMappings <++= (packageName in Linux, mappings in Universal, defaultLinuxInstallLocation) map {
+ (pkg, mappings, installLocation) =>
+ // TODO - More windows filters...
+ def isWindowsFile(f: (File, String)): Boolean =
+ f._2 endsWith ".bat"
+
+ mapGenericMappingsToLinux(mappings filterNot isWindowsFile, Users.Root, Users.Root) { name =>
+ installLocation + "/" + pkg + "/" + name
+ }
+ },
+ // Now we generate symlinks.
+ linuxPackageSymlinks <++= (packageName in Linux, mappings in Universal, defaultLinuxInstallLocation) map { (pkg, mappings, installLocation) =>
+ for {
+ (file, name) <- mappings
+ if !file.isDirectory
+ if name startsWith "bin/"
+ if !(name endsWith ".bat") // IGNORE windows-y things.
+ } yield LinuxSymlink("/usr/" + name, installLocation + "/" + pkg + "/" + name)
+ },
+ // Map configuration files
+ linuxPackageSymlinks <++= (packageName in Linux, mappings in Universal, defaultLinuxInstallLocation, defaultLinuxConfigLocation)
+ map { (pkg, mappings, installLocation, configLocation) =>
+ val needsConfLink =
+ mappings exists {
+ case (file, name) =>
+ (name startsWith "conf/") && !file.isDirectory
+ }
+ if (needsConfLink) Seq(LinuxSymlink(
+ link = configLocation + "/" + pkg,
+ destination = installLocation + "/" + pkg + "/conf"))
+ else Seq.empty
+ })
- // TODO can the packager.MappingsHelper be used here?
- /**
- * @see #mapDirectoryAndContents
- * @param dirs - directories to map
- */
- def packageDirectoryAndContentsMapping(dirs: (File, String)*) = LinuxPackageMapping(mapDirectoryAndContents(dirs: _*))
- /**
- * This method includes files and directories.
- *
- * @param dirs - directories to map
- */
- def mapDirectoryAndContents(dirs: (File, String)*): Seq[(File, String)] = for {
- (src, dest) <- dirs
- path <- (src ***).get
- } yield path -> path.toString.replaceFirst(src.toString, dest)
/**
*
@@ -143,13 +184,48 @@ trait LinuxPlugin extends Plugin {
/** Create a ascii friendly string for a man page. */
final def makeMan(file: File): String =
Process("groff -man -Tascii " + file.getAbsolutePath).!!
-}
-object LinuxPlugin {
- object Users {
- val Root = "root"
+ // This method wires a lot of hand-coded generalities about how to map directories
+ // into linux, and the conventions we expect.
+ // It is by no means 100% accurate, but should be ok for the simplest cases.
+ // For advanced users, use the underlying APIs.
+ // Right now, it's also pretty focused on command line scripts packages.
+
+ /**
+ * Maps linux file format from the universal from the conventions:
+ *
+ * `/src/linux` files are mapped directly into linux packages.
+ * `` files are placed under `/usr/share/`
+ * `/bin` files are given symlinks in `/usr/bin`
+ * `/conf` directory is given a symlink to `/etc/`
+ * Files in `conf/` or `etc/` directories are automatically marked as configuration.
+ * `../man/...1` files are automatically compressed into .gz files.
+ *
+ */
+ def mapGenericMappingsToLinux(mappings: Seq[(File, String)], user: String, group: String)(rename: String => String): Seq[LinuxPackageMapping] = {
+ val (directories, nondirectories) = mappings.partition(_._1.isDirectory)
+ val (binaries, nonbinaries) = nondirectories.partition(_._1.canExecute)
+ val (manPages, nonManPages) = nonbinaries partition {
+ case (file, name) => (name contains "man/") && (name endsWith ".1")
+ }
+ val compressedManPages =
+ for ((file, name) <- manPages)
+ yield file -> (name + ".gz")
+ val (configFiles, remaining) = nonManPages partition {
+ case (file, name) => (name contains "etc/") || (name contains "conf/")
+ }
+ def packageMappingWithRename(mappings: (File, String)*): LinuxPackageMapping = {
+ val renamed =
+ for ((file, name) <- mappings)
+ yield file -> rename(name)
+ packageMapping(renamed: _*)
+ }
+
+ Seq(
+ packageMappingWithRename((binaries ++ directories): _*) withUser user withGroup group withPerms "0755",
+ packageMappingWithRename(compressedManPages: _*).gzipped withUser user withGroup group withPerms "0644",
+ packageMappingWithRename(configFiles: _*) withConfig () withUser user withGroup group withPerms "0644",
+ packageMappingWithRename(remaining: _*) withUser user withGroup group withPerms "0644")
}
- val CONTROL_FUNCTIONS = "control-functions"
- def controlFunctions(): URL = getClass getResource CONTROL_FUNCTIONS
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/com/typesafe/sbt/packager/rpm/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/rpm/Keys.scala
index c97dfbb83..e1cdc82d9 100644
--- a/src/main/scala/com/typesafe/sbt/packager/rpm/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/rpm/Keys.scala
@@ -59,33 +59,3 @@ trait RpmKeys {
val rpmLint = TaskKey[Unit]("rpm-lint", "Runs rpmlint program against the genreated RPM, if available.")
}
-
-/** Keys used in RPM Settings. */
-object Keys extends RpmKeys {
- // METADATA keys.
- def name = sbt.Keys.name
- def packageName = packager.Keys.packageName
- def executableScriptName = linux.Keys.executableScriptName
- def version = sbt.Keys.version
- def maintainer = linux.Keys.maintainer
- def packageArchitecture = linux.Keys.packageArchitecture
- def packageDescription = linux.Keys.packageDescription
- def packageSummary = linux.Keys.packageSummary
-
- // DESCRIPTION KEYS
-
- // DEPENDENCIES
-
- // SPEC
- def linuxPackageMappings = linux.Keys.linuxPackageMappings
- def linuxPackageSymlinks = linux.Keys.linuxPackageSymlinks
-
- // Building
- def target = sbt.Keys.target
- def packageBin = sbt.Keys.packageBin
-
- //init script parameters
- def serverLoading = linux.Keys.serverLoading
-
- def streams = sbt.Keys.streams
-}
diff --git a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala
index 38ef8a6cb..15d931194 100644
--- a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala
@@ -3,18 +3,47 @@ package packager
package rpm
import sbt._
-import sbt.Keys.sourceDirectory
-import rpm.Keys._
import linux._
import java.nio.charset.Charset
+import SbtNativePackager.Linux
-/** Plugin trait containing all generic values used for packaging linux software. */
-trait RpmPlugin extends Plugin with LinuxPlugin {
- val Rpm = config("rpm") extend Linux
+import sbt.Keys.{ name, version, sourceDirectory, target, packageBin, streams }
+import linux.LinuxPlugin.autoImport.{ linuxPackageMappings, linuxPackageSymlinks, serverLoading, packageArchitecture }
+import packager.Keys._
- import RpmPlugin.Names
+/**
+ * Plugin containing all generic values used for packaging rpms.
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(RpmPlugin)
+ * }}}
+ */
+object RpmPlugin extends AutoPlugin {
- def rpmSettings: Seq[Setting[_]] = Seq(
+ override def requires = LinuxPlugin
+ override def trigger = allRequirements
+
+ object autoImport extends RpmKeys {
+ val Rpm = config("rpm") extend Linux
+ }
+
+ import autoImport._
+
+ def osPostInstallMacro: java.net.URL = getClass getResource "brpJavaRepackJar"
+
+ /** RPM specific names */
+ object Names {
+ val Scriptlets = "scriptlets"
+
+ //maintainer script names
+ val Post = "postinst"
+ val Pre = "preinst"
+ val Postun = "postun"
+ val Preun = "preun"
+ }
+
+ override lazy val projectSettings = Seq(
rpmOs := "Linux", // TODO - default to something else?
rpmRelease := "0",
rpmPrefix := None,
@@ -80,17 +109,3 @@ trait RpmPlugin extends Plugin with LinuxPlugin {
))
}
-object RpmPlugin {
-
- def osPostInstallMacro: java.net.URL = getClass getResource "brpJavaRepackJar"
-
- object Names {
- val Scriptlets = "scriptlets"
-
- //maintainer script names
- val Post = "postinst"
- val Pre = "preinst"
- val Postun = "postun"
- val Preun = "preun"
- }
-}
diff --git a/src/main/scala/com/typesafe/sbt/packager/universal/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/universal/Keys.scala
index 0adda621a..bba14759c 100644
--- a/src/main/scala/com/typesafe/sbt/packager/universal/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/universal/Keys.scala
@@ -8,21 +8,7 @@ trait UniversalKeys {
val packageZipTarball = TaskKey[File]("package-zip-tarball", "Creates a tgz package.")
val packageXzTarball = TaskKey[File]("package-xz-tarball", "Creates a txz package.")
val packageOsxDmg = TaskKey[File]("package-osx-dmg", "Creates a dmg package for OSX (only on osx).")
- val stage = TaskKey[Unit]("stage", "Create a local directory with all the files laid out as they would be in the final distribution.")
+ val stage = TaskKey[File]("stage", "Create a local directory with all the files laid out as they would be in the final distribution.")
val dist = TaskKey[File]("dist", "Creates the distribution packages.")
val stagingDirectory = SettingKey[File]("stagingDirectory", "Directory where we stage distributions/releases.")
}
-
-object Keys extends UniversalKeys {
- def mappings = sbt.Keys.mappings
- def packageBin = sbt.Keys.packageBin
- def packageSrc = sbt.Keys.packageSrc
- def packageDoc = sbt.Keys.packageDoc
- def name = sbt.Keys.name
- def packageName = packager.Keys.packageName
- def executableScriptName = packager.Keys.executableScriptName
- def target = sbt.Keys.target
- def sourceDirectory = sbt.Keys.sourceDirectory
- def streams = sbt.Keys.streams
- def version = sbt.Keys.version
-}
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala
index 4ba702df2..917dadfdb 100644
--- a/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala
@@ -3,34 +3,74 @@ package packager
package universal
import sbt._
-import sbt.Keys.cacheDirectory
-import Keys._
+import sbt.Keys.{
+ cacheDirectory,
+ name,
+ normalizedName,
+ version,
+ mappings,
+ packageBin,
+ packageSrc,
+ packageDoc,
+ target,
+ sourceDirectory,
+ streams
+}
+import packager.Keys._
import Archives._
import sbt.Keys.TaskStreams
-/** Defines behavior to construct a 'universal' zip for installation. */
-trait UniversalPlugin extends Plugin {
- val Universal = config("universal")
- val UniversalDocs = config("universal-docs")
- val UniversalSrc = config("universal-src")
+/**
+ * == Universal Plugin ==
+ *
+ * Defines behavior to construct a 'universal' zip for installation.
+ *
+ * == Configuration ==
+ *
+ * In order to configure this plugin take a look at the available [[com.typesafe.sbt.packager.universal.UniversalKeys]]
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(UniversalPlugin)
+ * }}}
+ */
+object UniversalPlugin extends AutoPlugin {
+
+ object autoImport extends UniversalKeys {
+ val Universal = config("universal")
+ val UniversalDocs = config("universal-docs")
+ val UniversalSrc = config("universal-src")
+
+ /**
+ * Use native zipping instead of java based zipping
+ */
+ def useNativeZip: Seq[Setting[_]] =
+ makePackageSettings(packageBin, Universal)(makeNativeZip) ++
+ makePackageSettings(packageBin, UniversalDocs)(makeNativeZip) ++
+ makePackageSettings(packageBin, UniversalSrc)(makeNativeZip)
+ }
+
+ import autoImport._
+
+ override def requires = SbtNativePackager
+ override def trigger = allRequirements
/** The basic settings for the various packaging types. */
- def universalSettings: Seq[Setting[_]] =
- Seq[Setting[_]](
- // For now, we provide delegates from dist/stage to universal...
- dist <<= dist in Universal,
- stage <<= stage in Universal,
- // TODO - New default to naming, is this right?
- // TODO - We may need to do this for UniversalSrcs + UnviersalDocs
- name in Universal <<= name,
- name in UniversalDocs <<= name in Universal,
- name in UniversalSrc <<= name in Universal,
- packageName in Universal <<= packageName,
- executableScriptName in Universal <<= executableScriptName
- ) ++
- makePackageSettingsForConfig(Universal) ++
- makePackageSettingsForConfig(UniversalDocs) ++
- makePackageSettingsForConfig(UniversalSrc)
+ override lazy val projectSettings = Seq[Setting[_]](
+ // For now, we provide delegates from dist/stage to universal...
+ dist <<= dist in Universal,
+ stage <<= stage in Universal,
+ // TODO - New default to naming, is this right?
+ // TODO - We may need to do this for UniversalSrcs + UnviersalDocs
+ name in Universal <<= name,
+ name in UniversalDocs <<= name in Universal,
+ name in UniversalSrc <<= name in Universal,
+ packageName in Universal <<= packageName,
+ executableScriptName in Universal <<= executableScriptName
+ ) ++
+ makePackageSettingsForConfig(Universal) ++
+ makePackageSettingsForConfig(UniversalDocs) ++
+ makePackageSettingsForConfig(UniversalSrc)
/** Creates all package types for a given configuration */
private[this] def makePackageSettingsForConfig(config: Configuration): Seq[Setting[_]] =
@@ -43,17 +83,12 @@ trait UniversalPlugin extends Plugin {
mappings <<= sourceDirectory map findSources,
dist <<= (packageBin, streams) map printDist,
stagingDirectory <<= target apply (_ / "stage"),
- stage <<= (cacheDirectory, stagingDirectory, mappings) map stageFiles(config.name)
+ stage <<= (streams, stagingDirectory, mappings) map Stager.stage(config.name)
)) ++ Seq(
sourceDirectory in config <<= sourceDirectory apply (_ / config.name),
target in config <<= target apply (_ / config.name)
)
- def useNativeZip: Seq[Setting[_]] =
- makePackageSettings(packageBin, Universal)(makeNativeZip) ++
- makePackageSettings(packageBin, UniversalDocs)(makeNativeZip) ++
- makePackageSettings(packageBin, UniversalSrc)(makeNativeZip)
-
private[this] def printDist(dist: File, streams: TaskStreams): File = {
streams.log.info("")
streams.log.info("Your package is ready in " + dist.getCanonicalPath)
@@ -61,20 +96,6 @@ trait UniversalPlugin extends Plugin {
dist
}
- def stageFiles(config: String)(cacheDirectory: File, to: File, mappings: Seq[(File, String)]): Unit = {
- val cache = cacheDirectory / ("packager-mappings-" + config)
- val copies = mappings map {
- case (file, path) => file -> (to / path)
- }
- Sync(cache)(copies)
- // Now set scripts to executable using Java's lack of understanding of permissions.
- // TODO - Config file user-readable permissions....
- for {
- (from, to) <- copies
- if from.canExecute
- } to.setExecutable(true)
- }
-
private type Packager = (File, String, Seq[(File, String)]) => File
/** Creates packaging settings for a given package key, configuration + archive type. */
private[this] def makePackageSettings(packageKey: TaskKey[File], config: Configuration)(packager: Packager): Seq[Setting[_]] =
@@ -90,6 +111,6 @@ trait UniversalPlugin extends Plugin {
/** Finds all sources in a source directory. */
private[this] def findSources(sourceDir: File): Seq[(File, String)] =
- sourceDir.*** --- sourceDir x relativeTo(sourceDir)
+ sourceDir.*** --- sourceDir pair relativeTo(sourceDir)
}
diff --git a/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala
index 361e3a66e..05104a41a 100644
--- a/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala
@@ -4,6 +4,7 @@ package windows
import sbt._
+/** windows settings */
trait WindowsKeys {
val wixProductId = SettingKey[String]("wix-product-id", "The uuid of the windows package.")
@@ -14,23 +15,6 @@ trait WindowsKeys {
val wixProductConfig = TaskKey[xml.Node]("wix-product-xml", "The WIX XML configuration for a product (nested in Wix/Product elements).")
val wixConfig = TaskKey[xml.Node]("wix-xml", "The WIX XML configuration for this package.")
val wixFile = TaskKey[File]("wix-file", "The WIX XML file to package with.")
- @deprecated("use packageBin instead!", "0.7.0")
- val packageMsi = TaskKey[File]("package-msi", "creates a new windows CAB file containing everything for the installation.")
val candleOptions = SettingKey[Seq[String]]("candle-options", "Options to pass to the candle.exe program.")
val lightOptions = SettingKey[Seq[String]]("light-options", "Options to pass to the light.exe program.")
}
-
-object Keys extends WindowsKeys {
- def version = sbt.Keys.version
- def target = sbt.Keys.target
- def mappings = sbt.Keys.mappings
- def name = sbt.Keys.name
- def packageName = packager.Keys.packageName
- def executableScriptName = packager.Keys.executableScriptName
- def streams = sbt.Keys.streams
- def sourceDirectory = sbt.Keys.sourceDirectory
- def packageBin = sbt.Keys.packageBin
- def maintainer = packager.Keys.maintainer
- def packageSummary = packager.Keys.packageSummary
- def packageDescription = packager.Keys.packageDescription
-}
\ No newline at end of file
diff --git a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala
index b18709552..5ccaaaa8e 100644
--- a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala
+++ b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala
@@ -2,19 +2,53 @@ package com.typesafe.sbt
package packager
package windows
-import Keys._
import sbt._
-import sbt.Keys.{ normalizedName }
+import sbt.Keys.{ normalizedName, name, version, sourceDirectory, target, mappings, packageBin, streams }
+import packager.Keys.{ packageName, maintainer, packageSummary, packageDescription }
+import SbtNativePackager.Universal
-trait WindowsPlugin extends Plugin {
- val Windows = config("windows")
+/**
+ * == Windows Plugin ==
+ *
+ * This plugin generates ''msi'' packages that can be installed on windows systems.
+ *
+ * == Configuration ==
+ *
+ * In order to configure this plugin take a look at the available [[com.typesafe.sbt.packager.windows.WindowsKeys]]
+ *
+ * == Requirements ==
+ *
+ *
+ * - Windows System
+ * - Wix Toolset ([[http://wixtoolset.org/]]) installed
+ *
+ *
+ * @example Enable the plugin in the `build.sbt`
+ * {{{
+ * enablePlugins(WindowsPlugin)
+ * }}}
+ */
+object WindowsPlugin extends AutoPlugin {
+ object autoImport extends WindowsKeys {
+ val Windows = config("windows")
+ }
+
+ import autoImport._
+
+ override lazy val projectSettings = windowsSettings ++ mapGenericFilesToWindows
+ override def requires = universal.UniversalPlugin
+ override def trigger = allRequirements
+
+ /**
+ * default windows settings
+ */
def windowsSettings: Seq[Setting[_]] = Seq(
sourceDirectory in Windows <<= sourceDirectory(_ / "windows"),
target in Windows <<= target apply (_ / "windows"),
// TODO - Should this use normalized name like the linux guys?
name in Windows <<= name,
- packageName in Windows <<= normalizedName,
+ packageName in Windows <<= packageName,
// Defaults so that our simplified building works
candleOptions := Seq("-ext", "WixUtilExtension"),
lightOptions := Seq("-ext", "WixUIExtension",
@@ -63,13 +97,7 @@ trait WindowsPlugin extends Plugin {
f
}
) ++ inConfig(Windows)(Seq(
- // Disable windows generation by default.
- mappings := Seq.empty,
- mappings in packageBin <<= mappings,
- // TODO - Remove packageMsi after next major release.
- mappings in packageMsi <<= mappings in packageBin,
- packageMsi <<= packageBin,
- packageBin <<= (mappings in packageMsi, wixFile, name, target, candleOptions, lightOptions, streams) map { (m, f, n, t, co, lo, s) =>
+ packageBin <<= (mappings, wixFile, name, target, candleOptions, lightOptions, streams) map { (m, f, n, t, co, lo, s) =>
val msi = t / (n + ".msi")
// First we have to move everything (including the wix file) to our target directory.
val wix = t / (n + ".wix")
@@ -94,4 +122,57 @@ trait WindowsPlugin extends Plugin {
msi
}
))
+
+ /**
+ * set the `mappings in Windows` and the `wixFeatures`
+ */
+ def mapGenericFilesToWindows: Seq[Setting[_]] = Seq(
+ mappings in Windows <<= mappings in Universal,
+ wixFeatures <<= (packageName in Windows, mappings in Windows) map makeWindowsFeatures)
+
+ /**
+ * Generates the wix configuration features
+ *
+ * @param name - title of the core package
+ * @param mappings - use to generate different features
+ * @return windows features
+ */
+ def makeWindowsFeatures(name: String, mappings: Seq[(File, String)]): Seq[windows.WindowsFeature] = {
+ // TODO select main script! Filter Config links!
+ import windows._
+
+ val files =
+ for {
+ (file, name) <- mappings
+ if !file.isDirectory
+ } yield ComponentFile(name, editable = (name startsWith "conf"))
+ val corePackage =
+ WindowsFeature(
+ id = WixHelper.cleanStringForId(name + "_core").takeRight(38), // Must be no longer
+ title = name,
+ desc = "All core files.",
+ absent = "disallow",
+ components = files)
+ // TODO - Detect bat files to add paths...
+ val addBinToPath =
+ // TODO - we may have issues here...
+ WindowsFeature(
+ id = "AddBinToPath",
+ title = "Update Enviornment Variables",
+ desc = "Update PATH environment variables (requires restart).",
+ components = Seq(AddDirectoryToPath("bin")))
+ val configLinks = for {
+ (file, name) <- mappings
+ if !file.isDirectory
+ if name startsWith "conf/"
+ } yield name.replaceAll("//", "/").stripSuffix("/").stripSuffix("/")
+ val menuLinks =
+ WindowsFeature(
+ id = "AddConfigLinks",
+ title = "Configuration start menu links",
+ desc = "Adds start menu shortcuts to edit configuration files.",
+ components = Seq(AddShortCuts(configLinks)))
+ // TODO - Add feature for shortcuts to binary scripts.
+ Seq(corePackage, addBinToPath, menuLinks)
+ }
}
\ No newline at end of file
diff --git a/src/sbt-test/cygwin/java-app-archetype/build.sbt b/src/sbt-test/cygwin/java-app-archetype/build.sbt
index 22d3cb7f4..86d83ae27 100644
--- a/src/sbt-test/cygwin/java-app-archetype/build.sbt
+++ b/src/sbt-test/cygwin/java-app-archetype/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaServerAppPackaging)
name := "windows-test"
diff --git a/src/sbt-test/debian/daemon-user-deb/build.sbt b/src/sbt-test/debian/daemon-user-deb/build.sbt
index 9a33baac5..dad7b630b 100644
--- a/src/sbt-test/debian/daemon-user-deb/build.sbt
+++ b/src/sbt-test/debian/daemon-user-deb/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.Upstart
diff --git a/src/sbt-test/debian/daemon-user-shell-deb/build.sbt b/src/sbt-test/debian/daemon-user-shell-deb/build.sbt
index 90afa2886..f5157d658 100644
--- a/src/sbt-test/debian/daemon-user-shell-deb/build.sbt
+++ b/src/sbt-test/debian/daemon-user-shell-deb/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.Upstart
diff --git a/src/sbt-test/debian/gen-changes/build.sbt b/src/sbt-test/debian/gen-changes/build.sbt
index dff9b9351..dd46a812f 100644
--- a/src/sbt-test/debian/gen-changes/build.sbt
+++ b/src/sbt-test/debian/gen-changes/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(SbtNativePackager)
name := "debian-test"
diff --git a/src/sbt-test/debian/java-app-archetype/build.sbt b/src/sbt-test/debian/java-app-archetype/build.sbt
index fb9163f5c..6d7c12f06 100644
--- a/src/sbt-test/debian/java-app-archetype/build.sbt
+++ b/src/sbt-test/debian/java-app-archetype/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaServerAppPackaging)
name := "debian-test"
diff --git a/src/sbt-test/debian/jdeb-dir-mappings/build.sbt b/src/sbt-test/debian/jdeb-dir-mappings/build.sbt
index a59e4f1d3..49b7247f2 100644
--- a/src/sbt-test/debian/jdeb-dir-mappings/build.sbt
+++ b/src/sbt-test/debian/jdeb-dir-mappings/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(JavaServerAppPackaging, JDebPackaging)
name := "debian-test"
@@ -25,8 +21,6 @@ linuxPackageMappings in Debian += packageDirectoryAndContentsMapping(
linuxPackageMappings in Debian += packageDirectoryAndContentsMapping(
(baseDirectory.value / "src" / "resources" / "empty") -> "/var/empty")
-packageBin in Debian <<= debianJDebPackaging in Debian
-
TaskKey[Unit]("check-dir-mappings") <<= (target, streams) map { (target, out) =>
// val tmpDir = java.nio.file.Files.createTempDirectory("jdeb")
val extracted = file("/tmp/jdeb" + System.currentTimeMillis().toString)
diff --git a/src/sbt-test/debian/log-directory/build.sbt b/src/sbt-test/debian/log-directory/build.sbt
index 30b643a5c..bd7191f31 100644
--- a/src/sbt-test/debian/log-directory/build.sbt
+++ b/src/sbt-test/debian/log-directory/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.Upstart
diff --git a/src/sbt-test/debian/override-control-files/build.sbt b/src/sbt-test/debian/override-control-files/build.sbt
index 48cd4b449..7a31729dd 100644
--- a/src/sbt-test/debian/override-control-files/build.sbt
+++ b/src/sbt-test/debian/override-control-files/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
mainClass in Compile := Some("empty")
diff --git a/src/sbt-test/debian/simple-deb/build.sbt b/src/sbt-test/debian/simple-deb/build.sbt
index a856482cd..4a33180f3 100644
--- a/src/sbt-test/debian/simple-deb/build.sbt
+++ b/src/sbt-test/debian/simple-deb/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(DebianPlugin)
name := "debian-test"
diff --git a/src/sbt-test/debian/simple-jdeb/build.sbt b/src/sbt-test/debian/simple-jdeb/build.sbt
index 9351893a3..091996703 100644
--- a/src/sbt-test/debian/simple-jdeb/build.sbt
+++ b/src/sbt-test/debian/simple-jdeb/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(JDebPackaging)
name := "debian-test"
@@ -18,5 +14,3 @@ packageDescription := """A fun package description of our software,
debianPackageDependencies in Debian ++= Seq("java2-runtime", "bash (>= 2.05a-11)")
debianPackageRecommends in Debian += "git"
-
-packageBin in Debian <<= debianJDebPackaging in Debian
diff --git a/src/sbt-test/debian/systemd-deb/build.sbt b/src/sbt-test/debian/systemd-deb/build.sbt
index 16ce883b8..8a8366df4 100644
--- a/src/sbt-test/debian/systemd-deb/build.sbt
+++ b/src/sbt-test/debian/systemd-deb/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.Systemd
diff --git a/src/sbt-test/debian/sysvinit-deb/build.sbt b/src/sbt-test/debian/sysvinit-deb/build.sbt
index 09f83fa64..7ae94b82b 100644
--- a/src/sbt-test/debian/sysvinit-deb/build.sbt
+++ b/src/sbt-test/debian/sysvinit-deb/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.SystemV
diff --git a/src/sbt-test/debian/test-executableScriptName/build.sbt b/src/sbt-test/debian/test-executableScriptName/build.sbt
index 8384e6597..d2ac73a2d 100644
--- a/src/sbt-test/debian/test-executableScriptName/build.sbt
+++ b/src/sbt-test/debian/test-executableScriptName/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "debian-test"
diff --git a/src/sbt-test/debian/test-mapping-helpers/build.sbt b/src/sbt-test/debian/test-mapping-helpers/build.sbt
index 0e7c61a08..744ba548b 100644
--- a/src/sbt-test/debian/test-mapping-helpers/build.sbt
+++ b/src/sbt-test/debian/test-mapping-helpers/build.sbt
@@ -1,9 +1,6 @@
-import NativePackagerKeys._
import NativePackagerHelper._
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(SbtNativePackager)
name := "debian-test"
diff --git a/src/sbt-test/debian/test-mapping/build.sbt b/src/sbt-test/debian/test-mapping/build.sbt
index 67ab0c4df..c816c071a 100644
--- a/src/sbt-test/debian/test-mapping/build.sbt
+++ b/src/sbt-test/debian/test-mapping/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(DebianPlugin)
name := "debian-test"
diff --git a/src/sbt-test/debian/test-packageName/build.sbt b/src/sbt-test/debian/test-packageName/build.sbt
index 8c85d3f35..dd15839ea 100644
--- a/src/sbt-test/debian/test-packageName/build.sbt
+++ b/src/sbt-test/debian/test-packageName/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "debian-test"
diff --git a/src/sbt-test/debian/upstart-deb-facilities/build.sbt b/src/sbt-test/debian/upstart-deb-facilities/build.sbt
index 246baf489..8b7b14855 100644
--- a/src/sbt-test/debian/upstart-deb-facilities/build.sbt
+++ b/src/sbt-test/debian/upstart-deb-facilities/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.Upstart
diff --git a/src/sbt-test/debian/upstart-deb/build.sbt b/src/sbt-test/debian/upstart-deb/build.sbt
index e2b6fe53c..54aa7fbb9 100644
--- a/src/sbt-test/debian/upstart-deb/build.sbt
+++ b/src/sbt-test/debian/upstart-deb/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Debian := ServerLoader.Upstart
diff --git a/src/sbt-test/docker/simple-docker/build.sbt b/src/sbt-test/docker/simple-docker/build.sbt
index 9d13ebcbe..f812fe56d 100644
--- a/src/sbt-test/docker/simple-docker/build.sbt
+++ b/src/sbt-test/docker/simple-docker/build.sbt
@@ -1,7 +1,4 @@
-import com.typesafe.sbt.SbtNativePackager._
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "docker-test"
diff --git a/src/sbt-test/docker/staging/build.sbt b/src/sbt-test/docker/staging/build.sbt
index 8c687dea6..3f024b51e 100644
--- a/src/sbt-test/docker/staging/build.sbt
+++ b/src/sbt-test/docker/staging/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(SbtNativePackager)
name := "simple-test"
diff --git a/src/sbt-test/docker/staging/test b/src/sbt-test/docker/staging/test
index 23231c0b6..430b59004 100644
--- a/src/sbt-test/docker/staging/test
+++ b/src/sbt-test/docker/staging/test
@@ -1,4 +1,4 @@
# Stage the distribution and ensure files show up.
-> show docker:stage
+> docker:stage
$ exists target/docker/Dockerfile
$ exists target/docker/files
diff --git a/src/sbt-test/docker/test-executableScriptName/build.sbt b/src/sbt-test/docker/test-executableScriptName/build.sbt
index c2c5eb358..c08a67139 100644
--- a/src/sbt-test/docker/test-executableScriptName/build.sbt
+++ b/src/sbt-test/docker/test-executableScriptName/build.sbt
@@ -1,7 +1,4 @@
-import com.typesafe.sbt.SbtNativePackager._
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "docker-test"
diff --git a/src/sbt-test/docker/test-packageName-universal/build.sbt b/src/sbt-test/docker/test-packageName-universal/build.sbt
index fa360f39e..fdb6f8ee7 100644
--- a/src/sbt-test/docker/test-packageName-universal/build.sbt
+++ b/src/sbt-test/docker/test-packageName-universal/build.sbt
@@ -1,11 +1,8 @@
-import com.typesafe.sbt.SbtNativePackager._
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "docker-test"
-packageName := "docker-package" // sets the executable script, too
+packageName := "docker-package"
version := "0.1.0"
@@ -13,7 +10,7 @@ maintainer := "Gary Coady "
TaskKey[Unit]("check-dockerfile") <<= (target, streams) map { (target, out) =>
val dockerfile = IO.read(target / "docker" / "Dockerfile")
- assert(dockerfile.contains("ENTRYPOINT [\"bin/docker-package\"]\n"), "dockerfile doesn't contain ENTRYPOINT [\"docker-package\"]\n" + dockerfile)
+ assert(dockerfile.contains("ENTRYPOINT [\"bin/docker-test\"]\n"), "dockerfile doesn't contain ENTRYPOINT [\"docker-test\"]\n" + dockerfile)
out.log.success("Successfully tested control script")
()
}
\ No newline at end of file
diff --git a/src/sbt-test/docker/test-packageName-universal/test b/src/sbt-test/docker/test-packageName-universal/test
index c1208e7f4..857cfe0ac 100644
--- a/src/sbt-test/docker/test-packageName-universal/test
+++ b/src/sbt-test/docker/test-packageName-universal/test
@@ -1,6 +1,6 @@
# Generate the Docker image locally
> docker:publishLocal
$ exists target/docker/Dockerfile
-$ exists target/docker/files/opt/docker/bin/docker-package
+$ exists target/docker/files/opt/docker/bin/docker-test
> check-dockerfile
$ exec bash -c 'docker run docker-package:0.1.0 | grep -q "Hello world"'
\ No newline at end of file
diff --git a/src/sbt-test/docker/test-packageName/build.sbt b/src/sbt-test/docker/test-packageName/build.sbt
index 5592141fd..8b4d929fe 100644
--- a/src/sbt-test/docker/test-packageName/build.sbt
+++ b/src/sbt-test/docker/test-packageName/build.sbt
@@ -1,7 +1,4 @@
-import com.typesafe.sbt.SbtNativePackager._
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "docker-test"
diff --git a/src/sbt-test/docker/update-latest/build.sbt b/src/sbt-test/docker/update-latest/build.sbt
index c47083808..dfcd240e1 100644
--- a/src/sbt-test/docker/update-latest/build.sbt
+++ b/src/sbt-test/docker/update-latest/build.sbt
@@ -1,7 +1,4 @@
-import com.typesafe.sbt.SbtNativePackager._
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "docker-test"
diff --git a/src/sbt-test/docker/volumes/build.sbt b/src/sbt-test/docker/volumes/build.sbt
index e04a596cd..72989d106 100644
--- a/src/sbt-test/docker/volumes/build.sbt
+++ b/src/sbt-test/docker/volumes/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(SbtNativePackager)
name := "simple-test"
diff --git a/src/sbt-test/rpm/changelog-test/build.sbt b/src/sbt-test/rpm/changelog-test/build.sbt
index 23938119e..24da95e94 100644
--- a/src/sbt-test/rpm/changelog-test/build.sbt
+++ b/src/sbt-test/rpm/changelog-test/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/scriptlets-override-build-rpm/build.sbt b/src/sbt-test/rpm/scriptlets-override-build-rpm/build.sbt
index 36cf88397..149cb9903 100644
--- a/src/sbt-test/rpm/scriptlets-override-build-rpm/build.sbt
+++ b/src/sbt-test/rpm/scriptlets-override-build-rpm/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt b/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt
index e7e4231d3..aa68c95a1 100644
--- a/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt
+++ b/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt
@@ -1,7 +1,5 @@
-import NativePackagerKeys._
-
// only works with java_server archetype
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/scriptlets-rpm/build.sbt b/src/sbt-test/rpm/scriptlets-rpm/build.sbt
index 0f9b0fd47..a85e3eb43 100644
--- a/src/sbt-test/rpm/scriptlets-rpm/build.sbt
+++ b/src/sbt-test/rpm/scriptlets-rpm/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(SbtNativePackager)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/simple-rpm/build.sbt b/src/sbt-test/rpm/simple-rpm/build.sbt
index 38bbcd9aa..81bea06e5 100644
--- a/src/sbt-test/rpm/simple-rpm/build.sbt
+++ b/src/sbt-test/rpm/simple-rpm/build.sbt
@@ -1,8 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
-
-mapGenericFilesToLinux
+enablePlugins(SbtNativePackager)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/systemd-rpm/build.sbt b/src/sbt-test/rpm/systemd-rpm/build.sbt
index e0e7d9b19..b8c8e7759 100644
--- a/src/sbt-test/rpm/systemd-rpm/build.sbt
+++ b/src/sbt-test/rpm/systemd-rpm/build.sbt
@@ -1,7 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.archetypes.ServerLoader
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
serverLoading in Rpm := ServerLoader.Systemd
diff --git a/src/sbt-test/rpm/sysvinit-rpm/build.sbt b/src/sbt-test/rpm/sysvinit-rpm/build.sbt
index f9e3909a2..1ab3d6296 100644
--- a/src/sbt-test/rpm/sysvinit-rpm/build.sbt
+++ b/src/sbt-test/rpm/sysvinit-rpm/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/test-executableScriptName/build.sbt b/src/sbt-test/rpm/test-executableScriptName/build.sbt
index 8acf73577..c208ff9d5 100644
--- a/src/sbt-test/rpm/test-executableScriptName/build.sbt
+++ b/src/sbt-test/rpm/test-executableScriptName/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "rpm-test"
diff --git a/src/sbt-test/rpm/test-packageName/build.sbt b/src/sbt-test/rpm/test-packageName/build.sbt
index 3f7397033..f7d44f2b9 100644
--- a/src/sbt-test/rpm/test-packageName/build.sbt
+++ b/src/sbt-test/rpm/test-packageName/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_server
+enablePlugins(JavaServerAppPackaging)
name := "rpm-test"
diff --git a/src/sbt-test/universal/clear-stage-dir/build.sbt b/src/sbt-test/universal/clear-stage-dir/build.sbt
index 8c687dea6..3f024b51e 100644
--- a/src/sbt-test/universal/clear-stage-dir/build.sbt
+++ b/src/sbt-test/universal/clear-stage-dir/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(SbtNativePackager)
name := "simple-test"
diff --git a/src/sbt-test/universal/dist/build.sbt b/src/sbt-test/universal/dist/build.sbt
index 8c687dea6..3f024b51e 100644
--- a/src/sbt-test/universal/dist/build.sbt
+++ b/src/sbt-test/universal/dist/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(SbtNativePackager)
name := "simple-test"
diff --git a/src/sbt-test/universal/multiproject-classifiers/project/Build.scala b/src/sbt-test/universal/multiproject-classifiers/project/Build.scala
index f89ce14f2..7e2ae497f 100644
--- a/src/sbt-test/universal/multiproject-classifiers/project/Build.scala
+++ b/src/sbt-test/universal/multiproject-classifiers/project/Build.scala
@@ -1,6 +1,7 @@
import sbt._
import Keys._
import com.typesafe.sbt.SbtNativePackager._
+import com.typesafe.sbt.packager.Keys._
object MutliBuild extends Build {
diff --git a/src/sbt-test/universal/publish/build.sbt b/src/sbt-test/universal/publish/build.sbt
index 3e4cc1b36..66429d0bd 100644
--- a/src/sbt-test/universal/publish/build.sbt
+++ b/src/sbt-test/universal/publish/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(SbtNativePackager)
deploymentSettings
diff --git a/src/sbt-test/universal/staging-custom-main/build.sbt b/src/sbt-test/universal/staging-custom-main/build.sbt
index 130d8bc5e..78a8361b0 100644
--- a/src/sbt-test/universal/staging-custom-main/build.sbt
+++ b/src/sbt-test/universal/staging-custom-main/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "stage-custom-main"
diff --git a/src/sbt-test/universal/staging/build.sbt b/src/sbt-test/universal/staging/build.sbt
index 8c687dea6..3f024b51e 100644
--- a/src/sbt-test/universal/staging/build.sbt
+++ b/src/sbt-test/universal/staging/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(SbtNativePackager)
name := "simple-test"
diff --git a/src/sbt-test/universal/test-akka/build.sbt b/src/sbt-test/universal/test-akka/build.sbt
index dbf3afefd..d260fe601 100644
--- a/src/sbt-test/universal/test-akka/build.sbt
+++ b/src/sbt-test/universal/test-akka/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.akka_application
+enablePlugins(AkkaAppPackaging)
name := """test-akka"""
diff --git a/src/sbt-test/universal/test-executableScriptName/build.sbt b/src/sbt-test/universal/test-executableScriptName/build.sbt
index e59fb9447..6e8f4e3f6 100644
--- a/src/sbt-test/universal/test-executableScriptName/build.sbt
+++ b/src/sbt-test/universal/test-executableScriptName/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "simple-test"
diff --git a/src/sbt-test/universal/test-mapping-helpers/build.sbt b/src/sbt-test/universal/test-mapping-helpers/build.sbt
index 12f5c4243..34fe6002b 100644
--- a/src/sbt-test/universal/test-mapping-helpers/build.sbt
+++ b/src/sbt-test/universal/test-mapping-helpers/build.sbt
@@ -1,9 +1,6 @@
-import NativePackagerKeys._
import com.typesafe.sbt.packager.MappingsHelper._
-packagerSettings
-
-packagerSettings
+enablePlugins(JavaAppPackaging)
name := "simple-test"
diff --git a/src/sbt-test/universal/test-native-zip/build.sbt b/src/sbt-test/universal/test-native-zip/build.sbt
index 94d2c3997..95cbe0949 100644
--- a/src/sbt-test/universal/test-native-zip/build.sbt
+++ b/src/sbt-test/universal/test-native-zip/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(JavaAppPackaging)
name := "simple-test"
diff --git a/src/sbt-test/universal/test-packageName/build.sbt b/src/sbt-test/universal/test-packageName/build.sbt
index d49aa28d7..a2a05de59 100644
--- a/src/sbt-test/universal/test-packageName/build.sbt
+++ b/src/sbt-test/universal/test-packageName/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "simple-test"
diff --git a/src/sbt-test/universal/test-zips/build.sbt b/src/sbt-test/universal/test-zips/build.sbt
index 8c687dea6..b72e96af7 100644
--- a/src/sbt-test/universal/test-zips/build.sbt
+++ b/src/sbt-test/universal/test-zips/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-packagerSettings
+enablePlugins(JavaAppPackaging)
name := "simple-test"
diff --git a/src/sbt-test/windows/java-app-archetype/build.sbt b/src/sbt-test/windows/java-app-archetype/build.sbt
index 6523ceee6..1ab1dcab1 100644
--- a/src/sbt-test/windows/java-app-archetype/build.sbt
+++ b/src/sbt-test/windows/java-app-archetype/build.sbt
@@ -1,6 +1,6 @@
import NativePackagerKeys._
-packageArchetype.java_application
+enablePlugins(JavaAppPackaging)
name := "windows-test"
diff --git a/test-project-simple/build.sbt b/test-project-simple/build.sbt
new file mode 100644
index 000000000..85b2a6b06
--- /dev/null
+++ b/test-project-simple/build.sbt
@@ -0,0 +1,19 @@
+name := "test-project-simple"
+version := "0.2.0"
+libraryDependencies ++= Seq(
+ "com.typesafe" % "config" % "1.2.1"
+)
+
+mainClass in Compile := Some("ExampleApp")
+
+enablePlugins(JavaAppPackaging, JDebPackaging)
+
+maintainer := "Josh Suereth "
+packageSummary := "Minimal Native Packager"
+packageDescription := """A fun package description of our software,
+ with multiple lines."""
+
+// RPM SETTINGS
+rpmVendor := "typesafe"
+rpmLicense := Some("BSD")
+rpmChangelogFile := Some("changelog.txt")
diff --git a/test-project-simple/project/build.properties b/test-project-simple/project/build.properties
new file mode 100644
index 000000000..39d2a9a80
--- /dev/null
+++ b/test-project-simple/project/build.properties
@@ -0,0 +1 @@
+sbt.version=0.13.7-M3
diff --git a/test-project-simple/project/plugins.sbt b/test-project-simple/project/plugins.sbt
new file mode 100644
index 000000000..5070c4644
--- /dev/null
+++ b/test-project-simple/project/plugins.sbt
@@ -0,0 +1,3 @@
+lazy val root = Project("plugins", file(".")) dependsOn(packager)
+
+lazy val packager = file("..").getAbsoluteFile.toURI
diff --git a/test-project-simple/src/main/scala/ExampleApp.scala b/test-project-simple/src/main/scala/ExampleApp.scala
new file mode 100644
index 000000000..66a697b6e
--- /dev/null
+++ b/test-project-simple/src/main/scala/ExampleApp.scala
@@ -0,0 +1,4 @@
+object ExampleApp extends App {
+
+ println("Hello, world!")
+}
diff --git a/test-project/README.md b/test-project/README.md
index 4f66576cd..1daf39cd5 100644
--- a/test-project/README.md
+++ b/test-project/README.md
@@ -1,3 +1,5 @@
+> This project is based on play and won't work on the current master. Use the test-project-simple
+
This is a test project. If you run sbt here, it will pull in the sbt-native-packager local repo as a *source* dependency
and allow you to make source changes, `reload` and exercise them in this build. A good way to test, and gives people an
example project to look at.
diff --git a/test-project/build.sbt b/test-project/build.sbt
index 449a44ef1..59df27145 100644
--- a/test-project/build.sbt
+++ b/test-project/build.sbt
@@ -1,6 +1,4 @@
-import NativePackagerKeys._
-
-play.Project.playScalaSettings
+enablePlugins(PlayScala)
name := "dtest"
@@ -12,7 +10,7 @@ val dtestProj = ProjectRef(buildLoc, "np")
version in dtestProj := "0.2.0"
-packageArchetype.java_server
+enablePlugins(JDebPackaging)
maintainer := "Josh Suereth "
@@ -20,10 +18,10 @@ packageSummary := "Test debian package"
packageDescription := """A fun package description of our software,
with multiple lines."""
-
-debianPackageDependencies in Debian ++= Seq("java2-runtime", "bash (>= 2.05a-11)")
-
-debianPackageRecommends in Debian += "git"
+//
+//debianPackageDependencies in Debian ++= Seq("java2-runtime", "bash (>= 2.05a-11)")
+//
+//debianPackageRecommends in Debian += "git"
rpmVendor := "typesafe"
@@ -31,9 +29,6 @@ rpmLicense := Some("BSD")
rpmChangelogFile := Some("changelog.txt")
-//debianMakePrermScript := Some(sourceDirectory.value / "deb" / "control" / "prerm") //change defaults
-
-
TaskKey[Unit]("check-script") <<= (NativePackagerKeys.stagingDirectory in Universal, target in Debian, name, version, maintainer in Debian, streams) map {
(dir, debTarget, name, version, author, streams) =>
val script = dir / "bin" / name
@@ -59,5 +54,4 @@ TaskKey[Unit]("check-script") <<= (NativePackagerKeys.stagingDirectory in Univer
val prermOutput = Process("bash " + prerm.getAbsolutePath).!!
val prermExpected = "removing ${{name}}-${{version}} from ${{author}}"
assert(prermOutput contains prermExpected, s"Failed to correctly run the prerm script!. Found [${prermOutput}] wanted [${prermExpected}]")
-}
-
+}
\ No newline at end of file
diff --git a/test-project/project/build.properties b/test-project/project/build.properties
index be6c454fb..64abd373f 100644
--- a/test-project/project/build.properties
+++ b/test-project/project/build.properties
@@ -1 +1 @@
-sbt.version=0.13.5
+sbt.version=0.13.6
diff --git a/test-project/project/plugins.sbt b/test-project/project/plugins.sbt
index 3edf28d10..90db06313 100644
--- a/test-project/project/plugins.sbt
+++ b/test-project/project/plugins.sbt
@@ -1,4 +1,4 @@
resolvers += Resolver.typesafeRepo("releases")
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.4")