diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template index 8b453525b..11d2412a5 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template @@ -1,10 +1,11 @@ -${{header}} -${{loader-functions}} -${{control-functions}} - -addGroup ${{daemon_group}} "${{daemon_group_gid}}" -addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} user-daemon" "${{daemon_shell}}" - -${{chown-paths}} +# ------------------------------------------------------------------------------------ +# ____ _ _ _ +# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ +# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ +# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ +# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| +# |___/|_| +# ------------------------------------------------------------------------------------ +${{loader-functions}} startService ${{app_name}} || echo "${{app_name}} could not be registered or started" diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template index 3b6ecf338..d63a46751 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template @@ -1,17 +1,10 @@ -${{header}} -${{control-functions}} +# ------------------------------------------------------------------------------------ +# ____ _ _ _ +# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ +# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ +# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ +# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| +# |___/|_| +# ------------------------------------------------------------------------------------ -# Deleting user: ${{daemon_user}} and group: ${{daemon_group}} -case "$1" in - remove|failed-upgrade|abort-upgrade|abort-install|disappear) - ;; - purge) - deleteUser ${{daemon_user}} - deleteGroup ${{daemon_group}} - ;; - upgrade) - ;; - *) - echo "postinst called with unknown argument \`\$1'" >&2 - ;; -esac +# empty \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template index aa20152c1..d63a46751 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template @@ -1,2 +1,10 @@ -${{header}} -${{control-functions}} +# ------------------------------------------------------------------------------------ +# ____ _ _ _ +# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ +# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ +# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ +# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| +# |___/|_| +# ------------------------------------------------------------------------------------ + +# empty \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template index cceb045f6..b4e318141 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template @@ -1,4 +1,12 @@ -${{header}} +# ------------------------------------------------------------------------------------ +# ____ _ _ _ +# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ +# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ +# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ +# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| +# |___/|_| +# ------------------------------------------------------------------------------------ + ${{loader-functions}} stopService ${{app_name}} || echo "${{app_name}} wasn't even running!" \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/postinst-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/post-template similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/postinst-template rename to src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/post-template diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/preinst-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/pre-template similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/preinst-template rename to src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/pre-template diff --git a/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template b/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template index 07561bfec..30b7aa9a4 100644 --- a/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template +++ b/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template @@ -2,6 +2,6 @@ ${{header}} ${{control-functions}} addGroup ${{daemon_group}} "${{daemon_group_gid}}" -addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} daemon-user" ${{daemon_shell}} +addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} daemon-user" "${{daemon_shell}}" ${{chown-paths}} diff --git a/src/main/resources/com/typesafe/sbt/packager/debian/preinst-template b/src/main/resources/com/typesafe/sbt/packager/debian/preinst-template index 8c58988f0..aa20152c1 100644 --- a/src/main/resources/com/typesafe/sbt/packager/debian/preinst-template +++ b/src/main/resources/com/typesafe/sbt/packager/debian/preinst-template @@ -1 +1,2 @@ ${{header}} +${{control-functions}} diff --git a/src/main/resources/com/typesafe/sbt/packager/debian/prerm-template b/src/main/resources/com/typesafe/sbt/packager/debian/prerm-template index 8c58988f0..aa20152c1 100644 --- a/src/main/resources/com/typesafe/sbt/packager/debian/prerm-template +++ b/src/main/resources/com/typesafe/sbt/packager/debian/prerm-template @@ -1 +1,2 @@ ${{header}} +${{control-functions}} diff --git a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala index 08bca70f1..ab7704552 100644 --- a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala @@ -97,7 +97,8 @@ object SbtNativePackager extends AutoPlugin { packageDescription := name.value, packageSummary := name.value, packageName := normalizedName.value, - executableScriptName := normalizedName.value + executableScriptName := normalizedName.value, + maintainerScripts := Map() ) diff --git a/src/main/scala/com/typesafe/sbt/packager/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/Keys.scala index 468774ad9..ae175195d 100644 --- a/src/main/scala/com/typesafe/sbt/packager/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/Keys.scala @@ -15,6 +15,8 @@ trait NativePackagerKeys { val executableScriptName = SettingKey[String]("executableScriptName", "Name of the executing script.") + val maintainerScripts = TaskKey[Map[String, Seq[String]]]("maintainerScripts", "Scripname to content lines") + } /** 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 e9e622104..146c06af4 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala @@ -44,7 +44,7 @@ object JavaAppPackaging extends AutoPlugin with JavaAppStartScript { */ val appIniLocation = "${app_home}/../conf/application.ini" - object autoImport extends JavaAppKeys + object autoImport extends JavaAppKeys with MaintainerScriptHelper import JavaAppPackaging.autoImport._ @@ -131,6 +131,7 @@ object JavaAppPackaging extends AutoPlugin with JavaAppStartScript { d.mkdirs() LinuxPackageMapping(Seq(d -> (installLocation + "/" + name)), LinuxFileMetaData()) } + ) private def makeRelativeClasspathNames(mappings: Seq[(File, String)]): Seq[String] = diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala index 91b795a2a..5e5462678 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala @@ -29,4 +29,5 @@ trait JavaAppKeys { | 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 2794dce11..943a6c968 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala @@ -5,13 +5,13 @@ package archetypes import sbt._ import sbt.Keys.{ target, mainClass, sourceDirectory, streams, javaOptions, run } import SbtNativePackager.{ Debian, Rpm, Universal } -import packager.Keys.{ packageName } +import packager.Keys.{ packageName, maintainerScripts } 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, rpmDaemonLogFile } +import rpm.RpmPlugin.autoImport.{ rpmPre, rpmPost, rpmPostun, rpmPreun, rpmScriptsDirectory, rpmDaemonLogFile, RpmConstants } import rpm.RpmPlugin.Names.RpmDaemonLogFileReplacement import JavaAppPackaging.autoImport.{ bashScriptConfigLocation, bashScriptEnvConfigLocation } @@ -105,18 +105,27 @@ object JavaServerAppPackaging extends AutoPlugin { linuxScriptReplacements in Debian, target in Universal, serverLoading in Debian) map makeStartScript, - linuxPackageMappings <++= (packageName, linuxMakeStartScript, serverLoading, defaultLinuxStartScriptLocation, linuxStartScriptName) map startScriptMapping + linuxPackageMappings <++= (packageName, linuxMakeStartScript, serverLoading, defaultLinuxStartScriptLocation, linuxStartScriptName) map startScriptMapping, + + // === Maintainer scripts === + maintainerScripts := { + val scripts = (maintainerScripts in Debian).value + val replacements = (linuxScriptReplacements in Debian).value + val contentOf = getScriptContent(Debian, replacements) _ + + scripts ++ Map( + Preinst -> (scripts.getOrElse(Preinst, Nil) :+ contentOf(Preinst)), + Postinst -> (scripts.getOrElse(Postinst, Nil) :+ contentOf(Postinst)), + Prerm -> (scripts.getOrElse(Prerm, Nil) :+ contentOf(Prerm)), + Postrm -> (scripts.getOrElse(Postrm, Nil) :+ contentOf(Postrm)) + ) + } )) ++ Seq( // === Daemon User and Group === daemonUser in Debian <<= daemonUser in Linux, daemonUserUid in Debian <<= daemonUserUid in Linux, daemonGroup in Debian <<= daemonGroup in Linux, - daemonGroupGid in Debian <<= daemonGroupGid in Linux, - // === Maintainer scripts === - debianMakePreinstScript <<= (target in Universal, serverLoading in Debian, linuxScriptReplacements) map makeMaintainerScript(Preinst), - debianMakePostinstScript <<= (target in Universal, serverLoading in Debian, linuxScriptReplacements) map makeMaintainerScript(Postinst), - debianMakePrermScript <<= (target in Universal, serverLoading in Debian, linuxScriptReplacements) map makeMaintainerScript(Prerm), - debianMakePostrmScript <<= (target in Universal, serverLoading in Debian, linuxScriptReplacements) map makeMaintainerScript(Postrm) + daemonGroupGid in Debian <<= daemonGroupGid in Linux ) } @@ -163,19 +172,7 @@ object JavaServerAppPackaging extends AutoPlugin { linuxPackageMappings in Rpm <++= (packageName in Rpm, linuxMakeStartScript in Rpm, serverLoading in Rpm, defaultLinuxStartScriptLocation in Rpm, linuxStartScriptName in Rpm) map startScriptMapping, // == Maintainer scripts === - // TODO this is very basic - align debian and rpm plugin - rpmPre <<= (rpmScriptsDirectory, rpmPre, linuxScriptReplacements in Rpm, serverLoading in Rpm) apply { - (dir, pre, replacements, loader) => rpmScriptletContent(dir, Pre, replacements, pre) - }, - rpmPost <<= (rpmScriptsDirectory, rpmPost, linuxScriptReplacements in Rpm, serverLoading in Rpm) apply { - (dir, post, replacements, loader) => rpmScriptletContent(dir, Post, replacements, post) - }, - rpmPostun <<= (rpmScriptsDirectory, rpmPostun, linuxScriptReplacements in Rpm, serverLoading in Rpm) apply { - (dir, postun, replacements, loader) => rpmScriptletContent(dir, Postun, replacements, postun) - }, - rpmPreun <<= (rpmScriptsDirectory, rpmPreun, linuxScriptReplacements in Rpm, serverLoading in Rpm) apply { - (dir, preun, replacements, loader) => rpmScriptletContent(dir, Preun, replacements, preun) - } + maintainerScripts in Rpm := rpmScriptletContents(rpmScriptsDirectory.value, (maintainerScripts in Rpm).value, (linuxScriptReplacements in Rpm).value) ) } @@ -186,7 +183,7 @@ object JavaServerAppPackaging extends AutoPlugin { private[this] def defaultTemplateName(loader: ServerLoader, config: Configuration): String = (loader, config.name) match { // SystemV has two different start scripts case (SystemV, name) => s"start-$name-template" - case _ => "start-template" + case _ => "start-template" } @@ -204,7 +201,7 @@ object JavaServerAppPackaging extends AutoPlugin { // Upstart cannot handle empty values val (startOn, stopOn) = loader match { case Upstart => (requiredStartFacilities.map("start on started " + _), requiredStopFacilities.map("stop on stopping " + _)) - case _ => (requiredStartFacilities, requiredStopFacilities) + case _ => (requiredStartFacilities, requiredStopFacilities) } Seq( "start_runlevels" -> startRunlevels.getOrElse(""), @@ -264,16 +261,17 @@ object JavaServerAppPackaging extends AutoPlugin { Some(script) } - protected def makeMaintainerScript( - scriptName: String, - template: Option[URL] = None, archetype: String = ARCHETYPE, config: Configuration = Debian)( - tmpDir: File, loader: ServerLoader, replacements: Seq[(String, String)]): Option[File] = { - val scriptBits = JavaServerBashScript(scriptName, archetype, config, replacements, template) getOrElse { - sys.error(s"Couldn't load [$scriptName] for config [${config.name}] in archetype [$archetype]") + /** + * + * @param config for which plugin (Debian, Rpm) + * @param replacements for the placeholders + * @param scriptName that should be loaded + * @return script lines + */ + private[this] def getScriptContent(config: Configuration, replacements: Seq[(String, String)])(scriptName: String): String = { + JavaServerBashScript(scriptName, ARCHETYPE, config, replacements) getOrElse { + sys.error(s"Couldn't load [$scriptName] for config [${config.name}] in archetype [$ARCHETYPE]") } - val script = tmpDir / "tmp" / "bin" / (config.name + scriptName) - IO.write(script, scriptBits) - Some(script) } /** @@ -295,15 +293,44 @@ object JavaServerAppPackaging extends AutoPlugin { Some(script) } - protected def rpmScriptletContent(dir: File, script: String, - replacements: Seq[(String, String)], definedScript: Option[String], archetype: String = ARCHETYPE, config: Configuration = Rpm): Option[String] = { - val file = (dir / script) - val template = if (file exists) Some(file.toURI.toURL) else None + /** + * + * + * @param scriptDirectory + * @param scripts + * @param replacements + */ + protected def rpmScriptletContents(scriptDirectory: File, scripts: Map[String, Seq[String]], replacements: Seq[(String, String)]): Map[String, Seq[String]] = { + import RpmConstants._ + val predefined = List(Pre, Post, Preun, Postun) + val predefinedScripts = predefined.foldLeft(scripts) { + case (scripts, script) => + val userDefined = Option(scriptDirectory / script) collect { + case file if file.exists && file.isFile => file.toURI.toURL + } + // generate content + val content = JavaServerBashScript(script, ARCHETYPE, Rpm, replacements, userDefined).map { + script => TemplateWriter generateScriptFromString (script, replacements) + }.toSeq + // add new content + val newContent = scripts.getOrElse(script, Nil) ++ content.toSeq + scripts + (script -> newContent) + } + + // used to override template + val rpmScripts = Option(scriptDirectory.listFiles) getOrElse Array.empty - val content = definedScript.map(_ + "\n").getOrElse("") + // remove all non files and already processed templates + rpmScripts.diff(predefined).filter(_.isFile).foldLeft(predefinedScripts) { + case (scripts, scriptlet) => + val script = scriptlet.getName + val existingContent = scripts.getOrElse(script, Nil) - JavaServerBashScript(script, archetype, config, replacements, template) map { - case script => TemplateWriter generateScriptFromString (content + script, replacements) + val loadedContent = JavaServerBashScript(script, ARCHETYPE, Rpm, replacements, Some(scriptlet.toURI.toURL)).map { + script => TemplateWriter generateScriptFromString (script, replacements) + }.toSeq + // add the existing and loaded content + scripts + (script -> (existingContent ++ loadedContent)) } } } diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala new file mode 100644 index 000000000..5bce9bfe9 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala @@ -0,0 +1,88 @@ +package com.typesafe.sbt.packager.archetypes + +import sbt._ +import com.typesafe.sbt.SbtNativePackager.autoImport.maintainerScripts + +/** + * == Maintainer Script Helper == + * + * Provides utility methods to configure package maintainerScripts. + */ +trait MaintainerScriptHelper { + + /** + * Use this method to override preexisting configurations with custom file + * definitions. + * + * @example {{{ + * import DebianConstants._ + * maintainerScripts in Debian := maintainerScriptsFromDirectory( + * sourceDirectory.value / DebianSource / DebianMaintainerScripts, + * Seq(Preinst, Postinst, Prerm, Postrm) + * ) + * }}} + * @param dir from where to load files + * @param scripts - a list of script names that should be used + * @return filename to content mapping + */ + def maintainerScriptsFromDirectory(dir: File, scripts: Seq[String]): Map[String, Seq[String]] = { + scripts.map(dir / _) + .filter(_.exists) + .map { script => + script.getName -> IO.readLines(script) + }.toMap + } + + /** + * Use this method to append additional script content to specific maintainer scripts. + * + * @example Adding content from a string + * {{{ + * import RpmConstants._ + * maintainerScripts in Rpm := maintainerScriptsAppend((maintainerScripts in Rpm).value)( + * Pretrans -> "echo 'hello, world'", + * Post -> s"echo 'installing ${(packageName in Rpm).value}'" + * ) + * }}} + * + * + * @param current maintainer scripts + * @param scripts scriptName -> scriptContent pairs + * @return maintainerScripts with appended `scripts` + * @see [[maintainerScriptsAppendFromFile]] + */ + def maintainerScriptsAppend(current: Map[String, Seq[String]] = Map.empty)(scripts: (String, String)*): Map[String, Seq[String]] = { + val appended = scripts.map { + case (key, script) => key -> (current.getOrElse(key, Seq.empty) :+ script) + }.toMap + current ++ appended + } + + /** + * Use this method to append additional script content to specific maintainer scripts. + * Note that you won't have any scriptReplacements available. + * + * @example Adding content from a string + * {{{ + * import RpmConstants._ + * maintainerScripts in Rpm := maintainerScriptsAppendFromFile((maintainerScripts in Rpm).value)( + * Pretrans -> (sourceDirectory.value / "rpm" / "pretrans"), + * Post -> (sourceDirectory.value / "rpm" / "posttrans") + * ) + * }}} + * + * + * @param current maintainer scripts + * @param scripts scriptName -> scriptFile pairs + * @return maintainerScripts with appended `scripts` + * @see [[maintainerScriptsAppend]] for pure strings where you can insert arbitrary settings and tasks values + */ + def maintainerScriptsAppendFromFile(current: Map[String, Seq[String]] = Map.empty)(scripts: (String, File)*): Map[String, Seq[String]] = { + val appended = scripts.map { + case (key, script) if script.exists && script.isFile => key -> (current.getOrElse(key, Seq.empty) ++ IO.readLines(script)) + case (key, script) => sys.error(s"The maintainer script $key doesn't exist here: ${script.getAbsolutePath}") + }.toMap + current ++ appended + } + +} \ No newline at end of file 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 6bf8d940f..2ae58397f 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala @@ -53,6 +53,10 @@ object TemplateWriter { sb toString } + private def replaceValues(lines: Seq[String], replacements: Seq[(String, String)], keySurround: String => String): Seq[String] = { + lines.map(line => replace(line, replacements, keySurround)) + } + def generateScript( source: java.net.URL, replacements: Seq[(String, String)], @@ -71,4 +75,18 @@ object TemplateWriter { charset: java.nio.charset.Charset = defaultCharset): String = { replaceValues(source split eol, replacements, eol, keySurround) } + + /** + * @param lines + * @param replacements + * @param keySurround defaults to bashFriendlyKeySurround + * @param charset defaults to UTF-8 + */ + def generateScriptFromLines( + lines: Seq[String], + replacements: Seq[(String, String)], + keySurround: String => String = bashFriendlyKeySurround, + charset: java.nio.charset.Charset = defaultCharset): Seq[String] = { + replaceValues(lines, replacements, keySurround) + } } \ No newline at end of file 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 056854910..6fe43e539 100644 --- a/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala @@ -21,27 +21,28 @@ import archetypes.TemplateWriter import SbtNativePackager.{ Universal, Linux } /** - * == 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) - * }}} - * - */ + * == 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 object autoImport extends DebianKeys { val Debian = config("debian") extend Linux + val DebianConstants = Names } import autoImport._ @@ -49,7 +50,7 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { /** Debian constants */ object Names { val DebianSource = "debian" - val Debian = "DEBIAN" + val DebianMaintainerScripts = "DEBIAN" //maintainer script names val Postinst = "postinst" @@ -66,25 +67,15 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { 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 - } - } - // TODO maybe we can put settings/debiansettings together /** - * Enables native packaging by default - */ - override lazy val projectSettings = settings ++ inConfig(Debian)(debianSettings) ++ debianNativeSettings + * Enables native packaging by default + */ + override lazy val projectSettings = settings ++ debianSettings ++ debianNativeSettings /** - * the default debian settings for the debian namespaced settings - */ + * the default debian settings for the debian namespaced settings + */ private def settings = Seq( /* ==== Debian default settings ==== */ debianPriority := "optional", @@ -94,6 +85,7 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { debianSignRole := "builder", target in Debian <<= (target, name in Debian, version in Debian) apply ((t, n, v) => t / (n + "-" + v)), name in Debian <<= (name in Linux), + maintainerScripts in Debian <<= (maintainerScripts in Linux), packageName in Debian <<= (packageName in Linux), executableScriptName in Debian <<= (executableScriptName in Linux), version in Debian <<= (version in Linux), @@ -103,26 +95,71 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { maintainer in Debian <<= maintainer in Linux, /* ==== Debian configuration settings ==== */ - debianControlScriptsDirectory <<= (sourceDirectory) apply (_ / "debian" / Names.Debian), + debianControlScriptsDirectory <<= (sourceDirectory) apply (_ / "debian" / Names.DebianMaintainerScripts), debianMaintainerScripts := Seq.empty, - debianMakePreinstScript := defaultMaintainerScript(Names.Preinst, linuxScriptReplacements.value, (target in Universal).value), - debianMakePrermScript := defaultMaintainerScript(Names.Prerm, linuxScriptReplacements.value, (target in Universal).value), - debianMakePostinstScript := defaultMaintainerScript(Names.Postinst, linuxScriptReplacements.value, (target in Universal).value), - debianMakePostrmScript := defaultMaintainerScript(Names.Postrm, linuxScriptReplacements.value, (target in Universal).value), + debianMakePreinstScript := None, + debianMakePrermScript := None, + debianMakePostinstScript := None, + debianMakePostrmScript := None, debianChangelog := None, - /* ==== Debian maintainer scripts ==== */ - 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) + /* === new debian scripts implementation */ + maintainerScripts in Debian := { + val replacements = (linuxScriptReplacements in Debian).value + val scripts = Map( + Names.Prerm -> defaultMaintainerScript(Names.Prerm).toSeq.flatten, + Names.Preinst -> defaultMaintainerScript(Names.Preinst).toSeq.flatten, + Names.Postinst -> defaultMaintainerScript(Names.Postinst).toSeq.flatten, + Names.Postrm -> defaultMaintainerScript(Names.Postrm).toSeq.flatten + ) + + // this is for legacy purposes to keep old behaviour + // --- legacy starts + def readContent(scriptFiles: Seq[(File, String)]): Map[String, Seq[String]] = scriptFiles.map { + case (scriptFile, scriptName) => scriptName -> IO.readLines(scriptFile) + }.toMap + + val userProvided = readContent(Seq( + debianMakePreinstScript.value.map(script => script -> Names.Preinst), + debianMakePostinstScript.value.map(script => script -> Names.Postinst), + debianMakePrermScript.value.map(script => script -> Names.Prerm), + debianMakePostrmScript.value.map(script => script -> Names.Postrm) + ).flatten) + + // these things get appended. Don't check for nonexisting keys as they are already in the default scripts map + val appendedScripts = scripts.map { + case (scriptName, content) => scriptName -> (content ++ userProvided.getOrElse(scriptName, Nil)) + } + // override and merge with the user defined scripts. Will change in the future + val controlScriptsDir = debianControlScriptsDirectory.value + val overridenScripts = scripts ++ readContent(Seq( + scriptMapping(Names.Prerm, debianMakePrermScript.value, controlScriptsDir), + scriptMapping(Names.Preinst, debianMakePreinstScript.value, controlScriptsDir), + scriptMapping(Names.Postinst, debianMakePostinstScript.value, controlScriptsDir), + scriptMapping(Names.Postrm, debianMakePostrmScript.value, controlScriptsDir) + ).flatten) + // --- legacy ends + + // TODO remove the overridenScripts + val content = appendedScripts ++ overridenScripts + + // apply all replacements + content.mapValues { lines => + TemplateWriter.generateScriptFromLines(lines, replacements) + } + }, + debianMaintainerScripts := generateDebianMaintainerScripts( + (maintainerScripts in Debian).value, + (linuxScriptReplacements in Debian).value, + (target in Universal).value + ) ) /** - * == Debian scoped settings == - * Everything used inside the debian scope - * - */ + * == Debian scoped settings == + * Everything used inside the debian scope + * + */ private def debianSettings: Seq[Setting[_]] = inConfig(Debian)( Seq( packageArchitecture := "all", @@ -145,14 +182,14 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { packageDescription in Debian := "My package Description"""" ) } - val cfile = dir / Names.Debian / Names.Control + val cfile = dir / Names.DebianMaintainerScripts / 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 cfile = dir / Names.DebianMaintainerScripts / Names.Conffiles val conffiles = for { LinuxPackageMapping(files, meta, _) <- mappings if meta.config != "false" @@ -165,11 +202,11 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { }, debianMD5sumsFile <<= (debianExplodedPackage, target) map { (mappings, dir) => - val md5file = dir / Names.Debian / "md5sums" + val md5file = dir / Names.DebianMaintainerScripts / "md5sums" val md5sums = for { (file, name) <- (dir.*** --- dir pair relativeTo(dir)) if file.isFile - if !(name startsWith Names.Debian) + if !(name startsWith Names.DebianMaintainerScripts) if !(name contains "debian-binary") // TODO - detect symlinks with Java7 (when we can) rather than hackery... if file.getCanonicalPath == file.getAbsolutePath @@ -180,9 +217,9 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { md5file }, debianMakeChownReplacements <<= (linuxPackageMappings, streams) map makeChownReplacements, - debianExplodedPackage <<= (linuxPackageMappings, debianControlFile, debianMaintainerScripts, debianConffilesFile, debianChangelog, daemonShell in Linux, + debianExplodedPackage <<= (linuxPackageMappings, debianControlFile, debianMaintainerScripts, debianConffilesFile, debianChangelog, linuxScriptReplacements, debianMakeChownReplacements, linuxPackageSymlinks, target, streams) - map { (mappings, _, maintScripts, _, changelog, shell, replacements, chown, symlinks, t, streams) => + map { (mappings, _, maintScripts, _, changelog, replacements, chown, symlinks, t, streams) => // Create files and directories mappings foreach { @@ -207,7 +244,7 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { // 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 + val targetFile = t / Names.DebianMaintainerScripts / name copyAndFixPerms(file, targetFile, LinuxFileMetaData()) filterAndFixPerms(targetFile, chown +: replacements, LinuxFileMetaData()) } @@ -223,20 +260,39 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { } /** - * == 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. - * - */ + * == 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 generateDebianMaintainerScripts( + scripts: Map[String, Seq[String]], + replacements: Seq[(String, String)], + tmpDir: File): Seq[(File, String)] = { + + scripts.map { + case (scriptName, content) => + val scriptBits = TemplateWriter.generateScriptFromLines(content, replacements) + val script = tmpDir / "tmp" / "debian" / scriptName + IO.write(script, scriptBits mkString "\n") + script -> scriptName + }.toList + } + + private[debian] final def defaultMaintainerScript(name: String): Option[List[String]] = { + val url = Option(getClass getResource s"$name-template") + url.map(source => IO.readLinesURL(source)) + } + private[debian] final def copyAndFixPerms(from: File, to: File, perms: LinuxFileMetaData, zipped: Boolean = false): Unit = { if (zipped) { IO.withTemporaryDirectory { dir => @@ -289,28 +345,29 @@ trait DebianPluginLike { } } - private[debian] def scriptMapping(scriptName: String)(script: Option[File], controlDir: File): Seq[(File, String)] = { + @deprecated("Will be removed", "1.0.3") + private[debian] def scriptMapping(scriptName: String, script: Option[File], controlDir: File): Option[(File, String)] = { (script, controlDir) match { // check if user defined script exists case (_, dir) if (dir / scriptName).exists => - Seq(file((dir / scriptName).getAbsolutePath) -> scriptName) + Some(file((dir / scriptName).getAbsolutePath) -> scriptName) // create mappings for generated script - case (scr, _) => scr.toSeq.map(_ -> scriptName) + case (scr, _) => scr.map(_ -> scriptName) } } /** - * Debian assumes the application chowns the necessary files and directories in the - * control scripts (Pre/Postinst). - * - * This method generates a replacement which can be inserted in bash script to chown - * all files which are not root. While adding the chown commands it checks if the users - * and groups have valid names. - * - * @param mappings - all mapped files - * @param streams - logging - * @return (CHOWN_REPLACEMENT -> ".. list of chown commands") - */ + * Debian assumes the application chowns the necessary files and directories in the + * control scripts (Pre/Postinst). + * + * This method generates a replacement which can be inserted in bash script to chown + * all files which are not root. While adding the chown commands it checks if the users + * and groups have valid names. + * + * @param mappings - all mapped files + * @param streams - logging + * @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? def chownCmd(user: String, group: String)(path: String): String = s"chown $user:$group $path" 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 9608f2298..6a16436f3 100644 --- a/src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala +++ b/src/main/scala/com/typesafe/sbt/packager/debian/JDebPackaging.scala @@ -39,7 +39,7 @@ object JDebPackaging extends AutoPlugin with DebianPluginLike { // FIXME do nothing. Java7 posix needed debianConffilesFile := { - target.value / Names.Debian / Names.Conffiles + target.value / Names.DebianMaintainerScripts / Names.Conffiles }, // FIXME copied from the debian plugin. Java7 posix needed @@ -51,7 +51,7 @@ object JDebPackaging extends AutoPlugin with DebianPluginLike { packageDescription in Debian := "My package Description"""" ) } - val cfile = dir / Names.Debian / Names.Control + val cfile = dir / Names.DebianMaintainerScripts / Names.Control IO.write(cfile, data.makeContent(size), java.nio.charset.Charset.defaultCharset) cfile }, @@ -67,7 +67,7 @@ object JDebPackaging extends AutoPlugin with DebianPluginLike { val symlinks = linuxPackageSymlinks.value // unused, but needed as dependency - val controlDir = targetDir / Names.Debian + val controlDir = targetDir / Names.DebianMaintainerScripts val control = debianControlFile.value val conffile = debianConffilesFile.value val replacements = debianMakeChownReplacements.value +: linuxScriptReplacements.value @@ -90,7 +90,7 @@ object JDebPackaging extends AutoPlugin with DebianPluginLike { ) debMaker setDepends "" debMaker setDeb debianFile - debMaker setControl (targetDir / Names.Debian) + debMaker setControl (targetDir / Names.DebianMaintainerScripts) // TODO set compression, gzip is default // TODO add signing with setKeyring, setKey, setPassphrase, setSignPackage, setSignMethod, setSignRole 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 99f1cb168..7f1a2db67 100644 --- a/src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala @@ -18,6 +18,8 @@ trait DebianKeys { // Package building val debianControlFile = TaskKey[File]("debian-control-file", "Makes the debian package control file.") + + @deprecated("Use generic maintainerScript task instead", "1.0.3") val debianMaintainerScripts = TaskKey[Seq[(File, String)]]("debian-maintainer-scripts", "Makes the debian maintainer scripts.") val debianConffilesFile = TaskKey[File]("debian-conffiles-file", "Makes the debian package conffiles file.") val debianUpstartFile = TaskKey[File]("debian-upstart-file", "Makes the upstart file for this debian package.") @@ -36,9 +38,13 @@ trait DebianKeys { "debian-control-scripts-directory", "Directory where all debian control scripts reside. Default is 'src/debian/DEBIAN'" ) + @deprecated("Use generic maintainerScript task instead", "1.0.3") val debianMakePreinstScript = TaskKey[Option[File]]("makePreinstScript", "Creates or discovers the preinst script used by this project") + @deprecated("Use generic maintainerScript task instead", "1.0.3") val debianMakePrermScript = TaskKey[Option[File]]("makePrermScript", "Creates or discovers the prerm script used by this project") + @deprecated("Use generic maintainerScript task instead", "1.0.3") val debianMakePostinstScript = TaskKey[Option[File]]("makePostInstScript", "Creates or discovers the postinst script used by this project") + @deprecated("Use generic maintainerScript task instead", "1.0.3") 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") 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 bee0d70fb..ade0f8e4f 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala @@ -91,7 +91,9 @@ object LinuxPlugin extends AutoPlugin { termTimeout = (termTimeout in Linux).value, killTimeout = (killTimeout in Linux).value ), - linuxScriptReplacements += controlScriptFunctionsReplacement( /* Add key for control-functions */ ) + linuxScriptReplacements += controlScriptFunctionsReplacement( /* Add key for control-functions */ ), + + maintainerScripts in Linux := Map.empty ) 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 1528429a8..fdefafacb 100644 --- a/src/main/scala/com/typesafe/sbt/packager/rpm/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/rpm/Keys.scala @@ -37,23 +37,32 @@ trait RpmKeys { val rpmConflicts = SettingKey[Seq[String]]("rpm-conflicts", "Packages this RPM conflicts with.") val rpmDependencies = SettingKey[RpmDependencies]("rpm-dependencies", "Configuration of dependency info for this RPM.") + // MAINTAINER SCRIPTS + @deprecated("Use maintainerScripts in RPM and RpmConstants.Pretrans instead.", "1.1.x") + val rpmPretrans = SettingKey[Option[String]]("rpm-pretrans", "%pretrans scriptlet") + @deprecated("Use maintainerScripts in RPM and RpmConstants.Pre instead.", "1.1.x") + val rpmPre = SettingKey[Option[String]]("rpm-pre", "%pre scriptlet") + @deprecated("Use maintainerScripts in RPM and RpmConstants.Verifyscript instead.", "1.1.x") + val rpmVerifyscript = SettingKey[Option[String]]("rpm-verifyscript", "%verifyscript scriptlet") + @deprecated("Use maintainerScripts in RPM and RpmConstants.Post instead.", "1.1.x") + val rpmPost = SettingKey[Option[String]]("rpm-post", "%post scriptlet") + @deprecated("Use maintainerScripts in RPM and RpmConstants.Posttrans instead.", "1.1.x") + val rpmPosttrans = SettingKey[Option[String]]("rpm-posttrans", "%posttrans scriptlet") + @deprecated("Use maintainerScripts in RPM and RpmConstants.Preun instead.", "1.1.x") + val rpmPreun = SettingKey[Option[String]]("rpm-preun", "%preun scriptlet") + @deprecated("Use maintainerScripts in RPM and RpmConstants.Postun instead.", "1.1.x") + val rpmPostun = SettingKey[Option[String]]("rpm-postun", "%postun scriptlet") + // SPEC val rpmSpecConfig = TaskKey[RpmSpec]("rpm-spec-config", "All the configuration for an RPM .spec file.") // SCRIPTS - val rpmScripts = SettingKey[RpmScripts]("rpm-scripts", "Configuration of pre- and post-integration scripts.") + val rpmScripts = TaskKey[RpmScripts]("rpm-scripts", "Configuration of pre- and post-integration scripts.") val rpmScriptsDirectory = SettingKey[File]( "rpm-scriptlets-directory", "Directory where all debian control scripts reside. Default is 'src/rpm/scriptlets'" ) - val rpmPretrans = SettingKey[Option[String]]("rpm-pretrans", "%pretrans scriptlet") - val rpmPre = SettingKey[Option[String]]("rpm-pre", "%pre scriptlet") - val rpmVerifyscript = SettingKey[Option[String]]("rpm-verifyscript", "%verifyscript scriptlet") - val rpmPost = SettingKey[Option[String]]("rpm-post", "%post scriptlet") - val rpmPosttrans = SettingKey[Option[String]]("rpm-posttrans", "%posttrans scriptlet") - val rpmPreun = SettingKey[Option[String]]("rpm-preun", "%preun scriptlet") - val rpmPostun = SettingKey[Option[String]]("rpm-postun", "%postun scriptlet") val rpmBrpJavaRepackJars = SettingKey[Boolean]("brp-java-repack-jars", """Overrides the __os_post_install scriptlet http://swaeku.github.io/blog/2013/08/05/how-to-disable-brp-java-repack-jars-during-rpm-build/ for details""") diff --git a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala index c6c5159b5..158e13fd4 100644 --- a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala +++ b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala @@ -4,6 +4,8 @@ package rpm import com.typesafe.sbt.packager.linux.{ LinuxPlugin, LinuxPackageMapping, LinuxFileMetaData, LinuxSymlink } import sbt._ +import com.typesafe.sbt.packager.linux.LinuxSymlink +import com.typesafe.sbt.packager.rpm.RpmPlugin.Names._ import java.io.File case class RpmMetadata( @@ -50,6 +52,9 @@ case class RpmDependencies( } } +/** + * Parameters stay because of binary compatibility. + */ case class RpmScripts( pretrans: Option[String] = None, pre: Option[String] = None, @@ -93,6 +98,7 @@ case class RpmScripts( @deprecated( "Call individual scriptlet content method instead, e.g. pretransContent(). This is to allow managing symlink during %post and %postun so it can be relocated", since = "1.0.5-M4") + @deprecated("Use contents(maintainerScripts) until next major release", "1.1.x") def contents(): String = { val labelledScripts = Seq("%pretrans", "%pre", "%post", "%verifyscript", "%posttrans", "%preun", "%postun") .zip(Seq(pretrans, pre, post, verifyscript, posttrans, preun, postun)) @@ -101,6 +107,22 @@ case class RpmScripts( } +object RpmScripts { + + import RpmPlugin.Names._ + + def fromMaintainerScripts(maintainerScripts: Map[String, Seq[String]] = Map()): RpmScripts = RpmScripts( + pretrans = maintainerScripts.get(Pretrans).map(_.mkString("\n")), + pre = maintainerScripts.get(Pre).map(_.mkString("\n")), + post = maintainerScripts.get(Post).map(_.mkString("\n")), + verifyscript = maintainerScripts.get(Verifyscript).map(_.mkString("\n")), + posttrans = maintainerScripts.get(Posttrans).map(_.mkString("\n")), + preun = maintainerScripts.get(Preun).map(_.mkString("\n")), + postun = maintainerScripts.get(Postun).map(_.mkString("\n")) + ) + +} + case class RpmSpec( meta: RpmMetadata, desc: RpmDescription = RpmDescription(), @@ -134,8 +156,7 @@ case class RpmSpec( ensureOr(meta.vendor, "`rpmVendor in Rpm` is empty. Please provide a valid vendor for the rpm SPEC.", isNonEmpty), ensureOr(meta.os, "`rpmOs in Rpm` is empty. Please provide a valid os vaue for the rpm SPEC.", isNonEmpty), ensureOr(meta.summary, "`packageSummary in Rpm` is empty. Please provide a valid summary for the rpm SPEC.", isNonEmpty), - ensureOr(meta.description, "`packageDescription in Rpm` is empty. Please provide a valid description for the rpm SPEC.", isNonEmpty) - ) + ensureOr(meta.description, "`packageDescription in Rpm` is empty. Please provide a valid description for the rpm SPEC.", isNonEmpty)) // TODO - Continue validating after this point? if (!emptyValidators.forall(identity)) sys.error("There are issues with the rpm spec data.") } 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 f4d8cacf0..4b9ce9a92 100644 --- a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala @@ -25,28 +25,36 @@ object RpmPlugin extends AutoPlugin { object autoImport extends RpmKeys { val Rpm = config("rpm") extend Linux + val RpmConstants = Names } import autoImport._ - def osPostInstallMacro: java.net.URL = getClass getResource "brpJavaRepackJar" + private final def osPostInstallMacro: java.net.URL = getClass getResource "brpJavaRepackJar" /** RPM specific names */ object Names { val Scriptlets = "scriptlets" //maintainer script names + /** `pretrans` */ + val Pretrans = "pretrans" /** `postinst` */ - val Post = "postinst" + val Post = "post" /** `preinst` */ - val Pre = "preinst" + val Pre = "pre" /** `postun` */ val Postun = "postun" /** `preun` */ val Preun = "preun" + /** `verifyscript` */ + val Verifyscript = "verifyscript" + /** `posttrans` */ + val Posttrans = "posttrans" // replacements val RpmDaemonLogFileReplacement = "rpm_daemon_log_file" + } override lazy val projectSettings = Seq( @@ -67,6 +75,9 @@ object RpmPlugin extends AutoPlugin { rpmPrerequisites := Seq.empty, rpmObsoletes := Seq.empty, rpmConflicts := Seq.empty, + rpmChangelogFile := None, + rpmBrpJavaRepackJars := false, + rpmPretrans := None, rpmPre := None, rpmPost := None, @@ -74,10 +85,10 @@ object RpmPlugin extends AutoPlugin { rpmPosttrans := None, rpmPreun := None, rpmPostun := None, - rpmChangelogFile := None, - rpmBrpJavaRepackJars := false, + rpmScriptsDirectory <<= sourceDirectory apply (_ / "rpm" / Names.Scriptlets), // Explicitly defer default settings to generic Linux Settings. + maintainerScripts in Rpm <<= maintainerScripts in Linux, packageSummary in Rpm <<= packageSummary in Linux, packageDescription in Rpm <<= packageDescription in Linux, target in Rpm <<= target(_ / "rpm"), @@ -93,14 +104,17 @@ object RpmPlugin extends AutoPlugin { (rpmLicense, rpmDistribution, rpmUrl, rpmGroup, rpmPackager, rpmIcon, rpmChangelogFile) apply RpmDescription, rpmDependencies <<= (rpmProvides, rpmRequirements, rpmPrerequisites, rpmObsoletes, rpmConflicts) apply RpmDependencies, - rpmPre <<= (rpmPre, rpmBrpJavaRepackJars) apply { - case (pre, true) => pre - case (pre, false) => + maintainerScripts := { + val scripts = maintainerScripts.value + if (rpmBrpJavaRepackJars.value) { + val pre = scripts.getOrElse(Names.Pre, Nil) val scriptBits = IO.readStream(RpmPlugin.osPostInstallMacro.openStream, Charset forName "UTF-8") - Some(pre.map(_ + "\n").getOrElse("") + scriptBits) + scripts + (Names.Pre -> (pre :+ scriptBits)) + } else { + scripts + } }, - rpmScripts <<= - (rpmPretrans, rpmPre, rpmPost, rpmVerifyscript, rpmPosttrans, rpmPreun, rpmPostun) apply RpmScripts, + rpmScripts := RpmScripts.fromMaintainerScripts(maintainerScripts.value), rpmSpecConfig <<= (rpmMetadata, rpmDescription, rpmDependencies, rpmScripts, linuxPackageMappings, linuxPackageSymlinks, defaultLinuxInstallLocation) map RpmSpec, packageBin <<= (rpmSpecConfig, target, streams) map { (spec, dir, s) => diff --git a/src/sbt-test/debian/daemon-group-gid-deb/build.sbt b/src/sbt-test/debian/daemon-group-gid-deb/build.sbt index 77c341539..cea79f827 100644 --- a/src/sbt-test/debian/daemon-group-gid-deb/build.sbt +++ b/src/sbt-test/debian/daemon-group-gid-deb/build.sbt @@ -28,7 +28,7 @@ TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) = val postinst = IO.read(debian / "postinst") val postrm = IO.read(debian / "postrm") assert(postinst contains """addGroup daemongroup "25000"""", "postinst misses addgroup for daemongroup: " + postinst) - assert(postinst contains """addUser daemonuser "" daemongroup "debian-test user-daemon" "/bin/false"""", "postinst misses useradd for daemonuser: " + postinst) + assert(postinst contains """addUser daemonuser "" daemongroup "debian-test daemon-user" "/bin/false"""", "postinst misses useradd for daemonuser: " + postinst) assert(postinst contains "chown daemonuser:daemongroup /var/log/debian-test", "postinst misses chown daemonuser /var/log/debian-test: " + postinst) assert(!(postinst contains "addgroup --system daemonuser"), "postinst has addgroup for daemonuser: " + postinst) assert(!(postinst contains "useradd --system --no-create-home --gid daemonuser --shell /bin/false daemonuser"), "postinst has useradd for daemongroup: " + postinst) diff --git a/src/sbt-test/debian/daemon-user-deb/build.sbt b/src/sbt-test/debian/daemon-user-deb/build.sbt index 52c9beb21..57f6b3ddb 100644 --- a/src/sbt-test/debian/daemon-user-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-deb/build.sbt @@ -26,7 +26,7 @@ TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) = val postinst = IO.read(debian / "postinst") val postrm = IO.read(debian / "postrm") assert(postinst contains """addGroup daemongroup """"", "postinst misses addgroup for daemongroup: " + postinst) - assert(postinst contains """addUser daemonuser "" daemongroup "debian-test user-daemon" "/bin/false"""", "postinst misses useradd for daemonuser: " + postinst) + assert(postinst contains """addUser daemonuser "" daemongroup "debian-test daemon-user" "/bin/false"""", "postinst misses useradd for daemonuser: " + postinst) assert(postinst contains "chown daemonuser:daemongroup /var/log/debian-test", "postinst misses chown daemonuser /var/log/debian-test: " + postinst) assert(!(postinst contains "addgroup --system daemonuser"), "postinst has addgroup for daemonuser: " + postinst) assert(!(postinst contains "useradd --system --no-create-home --gid daemonuser --shell /bin/false daemonuser"), "postinst has useradd for daemongroup: " + postinst) 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 bd21c1d18..4678554ca 100644 --- a/src/sbt-test/debian/daemon-user-shell-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-shell-deb/build.sbt @@ -27,7 +27,7 @@ TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) = val debian = target / "debian-test-0.1.0" / "DEBIAN" val postinst = IO.read(debian / "postinst") val postrm = IO.read(debian / "postrm") - assert(postinst contains """addUser daemonuser "" daemongroup "debian-test user-daemon" "/bin/bash"""", "postinst misses useradd for daemonuser: " + postinst) + assert(postinst contains """addUser daemonuser "" daemongroup "debian-test daemon-user" "/bin/bash"""", "postinst misses useradd for daemonuser: " + postinst) () } diff --git a/src/sbt-test/debian/daemon-user-uid-deb/build.sbt b/src/sbt-test/debian/daemon-user-uid-deb/build.sbt index 5bd9a138d..b3fa52df9 100644 --- a/src/sbt-test/debian/daemon-user-uid-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-uid-deb/build.sbt @@ -28,7 +28,7 @@ TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) = val postinst = IO.read(debian / "postinst") val postrm = IO.read(debian / "postrm") assert(postinst contains """addGroup daemongroup """"", "postinst misses addgroup for daemongroup: " + postinst) - assert(postinst contains """addUser daemonuser "20000" daemongroup "debian-test user-daemon" "/bin/false"""", "postinst misses useradd for daemonuser: " + postinst) + assert(postinst contains """addUser daemonuser "20000" daemongroup "debian-test daemon-user" "/bin/false"""", "postinst misses useradd for daemonuser: " + postinst) assert(postinst contains "chown daemonuser:daemongroup /var/log/debian-test", "postinst misses chown daemonuser /var/log/debian-test: " + postinst) assert(!(postinst contains "addgroup --system daemonuser"), "postinst has addgroup for daemonuser: " + postinst) assert(!(postinst contains "useradd --system --no-create-home --gid daemonuser --shell /bin/false daemonuser"), "postinst has useradd for daemongroup: " + postinst) diff --git a/src/sbt-test/debian/jdeb-script-replacements/build.sbt b/src/sbt-test/debian/jdeb-script-replacements/build.sbt index 9da2be99d..e6284cbd4 100644 --- a/src/sbt-test/debian/jdeb-script-replacements/build.sbt +++ b/src/sbt-test/debian/jdeb-script-replacements/build.sbt @@ -26,8 +26,8 @@ TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) = val postrm = extracted / "DEBIAN/postrm" Seq(preinst, postinst, prerm, postrm) foreach { script => val content = IO.read(script) - assert(content.startsWith(header), "script doesn't start with #!/bin/sh header:\n" + script) - assert(header.r.findAllIn(content).length == 1, "script contains more than one header line:\n" + script) + assert(content.startsWith(header), "script doesn't start with #!/bin/sh header:\n" + script + "\n" + content) + assert(header.r.findAllIn(content).length == 1, "script contains more than one header line:\n" + script + "\n" + content) } out.log.success("Successfully tested systemV control files") () diff --git a/src/sbt-test/debian/override-control-files/build.sbt b/src/sbt-test/debian/override-control-files/build.sbt index 7a31729dd..db535c08c 100644 --- a/src/sbt-test/debian/override-control-files/build.sbt +++ b/src/sbt-test/debian/override-control-files/build.sbt @@ -19,6 +19,13 @@ daemonGroup in Linux := "root" packageDescription := """A fun package description of our software, with multiple lines.""" +// add this to override all preexisting settings +import DebianConstants._ +maintainerScripts in Debian := maintainerScriptsFromDirectory( + sourceDirectory.value / DebianSource / DebianMaintainerScripts, + Seq(Preinst, Postinst, Prerm, Postrm) +) + TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) => val debian = target / "debian-test-0.1.0" / "DEBIAN" val postinst = IO.read(debian / "postinst") 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 149cb9903..27dbb96e8 100644 --- a/src/sbt-test/rpm/scriptlets-override-build-rpm/build.sbt +++ b/src/sbt-test/rpm/scriptlets-override-build-rpm/build.sbt @@ -1,3 +1,4 @@ +import RpmConstants._ enablePlugins(JavaServerAppPackaging) name := "rpm-test" @@ -19,17 +20,14 @@ rpmUrl := Some("http://github.com/sbt/sbt-native-packager") rpmLicense := Some("BSD") -rpmPre := Some("""echo "pre-install"""") - -rpmPost := Some("""echo "post-install"""") - -rpmPretrans := Some("""echo "pretrans"""") - -rpmPosttrans := Some("""echo "posttrans"""") - -rpmPreun := Some("""echo "pre-uninstall"""") - -rpmPostun := Some("""echo "post-uninstall"""") +maintainerScripts in Rpm := Map( + Pre -> Seq("""echo "pre-install""""), + Post -> Seq("""echo "post-install""""), + Pretrans -> Seq("""echo "pretrans""""), + Posttrans -> Seq("""echo "posttrans""""), + Preun -> Seq("""echo "pre-uninstall""""), + Postun -> Seq("""echo "post-uninstall"""") +) TaskKey[Unit]("check-spec-file") <<= (target, streams) map { (target, out) => val spec = IO.read(target / "rpm" / "SPECS" / "rpm-test.spec") diff --git a/src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/postinst b/src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/post similarity index 100% rename from src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/postinst rename to src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/post diff --git a/src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/preinst b/src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/pre similarity index 100% rename from src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/preinst rename to src/sbt-test/rpm/scriptlets-override-rpm/src/rpm/scriptlets/pre diff --git a/src/sbt-test/rpm/scriptlets-rpm/build.sbt b/src/sbt-test/rpm/scriptlets-rpm/build.sbt index ed8e43a94..b4310d53f 100644 --- a/src/sbt-test/rpm/scriptlets-rpm/build.sbt +++ b/src/sbt-test/rpm/scriptlets-rpm/build.sbt @@ -1,3 +1,5 @@ +import RpmConstants._ + enablePlugins(RpmPlugin) name := "rpm-test" @@ -19,17 +21,14 @@ rpmUrl := Some("http://github.com/sbt/sbt-native-packager") rpmLicense := Some("BSD") -rpmPre := Some("""echo "pre-install"""") - -rpmPost := Some("""echo "post-install"""") - -rpmPretrans := Some("""echo "pretrans"""") - -rpmPosttrans := Some("""echo "posttrans"""") - -rpmPreun := Some("""echo "pre-uninstall"""") - -rpmPostun := Some("""echo "post-uninstall"""") +maintainerScripts in Rpm := Map( + Pre -> Seq("""echo "pre-install""""), + Post -> Seq("""echo "post-install""""), + Pretrans -> Seq("""echo "pretrans""""), + Posttrans -> Seq("""echo "posttrans""""), + Preun -> Seq("""echo "pre-uninstall""""), + Postun -> Seq("""echo "post-uninstall"""") +) TaskKey[Unit]("check-spec-file") <<= (target, streams) map { (target, out) => val spec = IO.read(target / "rpm" / "SPECS" / "rpm-test.spec") diff --git a/src/sphinx/formats/debian.rst b/src/sphinx/formats/debian.rst index 2f3ab1146..aaa8d8f58 100644 --- a/src/sphinx/formats/debian.rst +++ b/src/sphinx/formats/debian.rst @@ -8,15 +8,15 @@ SBT Native Packager provides two ways to build debian packages. A native one, wh or a java, platform independent approach with `jdeb `_. By default the *native* implementation is activated. -.. contents:: +.. contents:: :depth: 2 - - + + .. raw:: html @@ -84,7 +84,7 @@ If you want to enable `jdeb` packaging add the following to your `build.sbt` .. code-block:: scala packageBin in Debian <<= debianJDebPackaging in Debian - + Configurations -------------- @@ -117,7 +117,8 @@ Debian requires the following specific settings: Debian requires a ``/usr/share/doc/{package name}/changelog.gz`` file that describes the version changes in this package. These should be appended to the base linux versions. - ``debianMaintainerScripts`` + ``maintainerScripts in Debian`` (``debianMaintainerScripts``) + *DEPRECATED* use ``maintainerScripts in Debian`` instead. These are the packaging scripts themselves used by ``dpkg-deb`` to build your debian. These scripts are used when installing/uninstalling a debian, like prerm, postinstall, etc. These scripts are placed in the ``DEBIAN`` file when building. Some of these files can be autogenerated, @@ -142,8 +143,8 @@ The Debian support grants the following commands: ``debian:gen-changes`` Generates the ``.changes``, and therefore the ``.deb`` package for this project. - - + + Customize --------------- @@ -160,12 +161,22 @@ A basic example to depend on java and recommend a git installation. debianPackageDependencies in Debian ++= Seq("java2-runtime", "bash (>= 2.05a-11)") debianPackageRecommends in Debian += "git" - + To hook into the debian package lifecycle (https://wiki.debian.org/MaintainerScripts) you can add ``preinst`` , ``postinst`` , ``prerm`` and/or ``postrm`` scripts. Just place them into -``src/debian/DEBIAN``. +``src/debian/DEBIAN``. Or you can do it programmatically in your ``build.sbt`` -If you use the ``packageArchetype.java_server`` there are predefined ``postinst`` and +.. code-block:: scala + + import DebianConstants._ + maintainerScripts in Debian := maintainerScriptsAppend((maintainerScripts in Debian).value)( + Preinst -> "echo 'hello, world'", + Postinst -> s"echo 'installed ${(packageName in Debian).value}'" + ) + +The helper methods can be found in `MaintainerScriptHelper Scaladocs`_. + +If you use the ``JavaServerAppPackaging`` there are predefined ``postinst`` and ``preinst`` files, which start/stop the application on install/remove calls. Existing maintainer scripts will be extended not overridden. @@ -175,3 +186,5 @@ Your control scripts are in a different castle.. directory? No problem. debianControlScriptsDirectory <<= (sourceDirectory) apply (_ / "deb" / "control") + +.. _MaintainerScriptHelper Scaladocs: http://www.scala-sbt.org/sbt-native-packager/latest/api/#com.typesafe.sbt.packager.MaintainerScriptHelper$ diff --git a/src/sphinx/formats/rpm.rst b/src/sphinx/formats/rpm.rst index 51de91890..450c5f0e3 100644 --- a/src/sphinx/formats/rpm.rst +++ b/src/sphinx/formats/rpm.rst @@ -7,19 +7,19 @@ http://fedoraproject.org/wiki/How_to_create_an_RPM_package is a good tutorial, b packages from source. The sbt-native-packager takes the approach that SBT has built your source and generated 'binary' packages. -.. contents:: +.. contents:: :depth: 2 - - + + .. raw:: html - - + + Requirements ------------ @@ -149,13 +149,13 @@ Dependency Settings ``rpmProvides`` The RPM package names that this RPM provides. - + ``rpmPrerequisites`` The RPM packages this RPM needs before installation - + ``rpmObsoletes`` The packages this RPM allows you to remove - + ``rpmConflcits`` The packages this RPM conflicts with and cannot be installed with. @@ -171,28 +171,12 @@ Meta Settings Scriptlet Settings ~~~~~~~~~~~~~~~~~~ - - ``rpmPretrans`` - The ``%pretrans`` scriptlet to run. - - ``rpmPre`` - The ``%pre`` scriptlet to run. - - ``rpmVerifyScript`` - The ``%verifyscript%`` scriptlet to run - - ``rpmPost`` - The ``%post`` scriptlet to run - - ``rpmPosttrans`` - The ``%posttrans`` scriptlet to run - - ``rpmPreun`` - The ``%preun`` scriptlet to run. - - ``rpmPostun`` - The ``%postun`` scriptlet to run. - + + ``maintainerScripts in Rpm`` + Contains the scriptles being injected into the specs file. Currently supports all + previous scriptlets: ``%pretrans``, ``%pre``, ``%verifyscript%``, ``%post``, ``%posttrans``, + ``%preun`` and ``%postun`` + ``rpmBrpJavaRepackJars`` appends ``__os_install_post`` scriptlet to ``rpmPre`` avoiding jar repackaging @@ -224,7 +208,7 @@ Rpm Prefix The rpm prefix allows you to create a relocatable package as defined by http://www.rpm.org/max-rpm/s1-rpm-reloc-prefix-tag.html. This optional setting with a handful of overrides to scriptlets and templates will allow you to create a working java_server -archetype that can be relocated in the file system. +archetype that can be relocated in the file system. Example Settings: @@ -235,7 +219,7 @@ Example Settings: rpmPrefix := Some(defaultLinuxInstallLocation), linuxPackageSymlinks := Seq.empty, defaultLinuxLogsLocation := defaultLinuxInstallLocation + "/" + name - + rpmChangelogFile ~~~~~~~~~~~~~~~~ @@ -249,7 +233,7 @@ Example Settings: .. code-block:: scala changelog := "changelog.txt" - + rpmChangelogFile := Some(changelog) @@ -272,10 +256,10 @@ Apply the following changes to the default init start script. You can find this ``src/templates/start`` .. code-block:: bash - + ... [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog - + # smb could define some additional options in $RUN_OPTS RUN_CMD="${PACKAGE_PREFIX}/${{app_name}}/bin/${{app_name}}" ... @@ -285,35 +269,39 @@ Apply the following changes to the default init start script. You can find this Scriptlet Changes ~~~~~~~~~~~~~~~~~ -Changing the scripts can be done in two ways. Override the ``rpmPre``, ``rpmPostun`` etc. scripts. +Changing the scripts can be done in two ways. Override the ``maintainerScripts in Rpm``. For example: .. code-block:: scala // overriding - rpmPre := Some("""## override all other enhancements - echo "I take care of everything myself" - """) - - // appending different stuff depending if previous content is there - rpmPostun := rpmPost.value.map { content => - s"""|$content - |echo "I append this to the current content - |""".stripMargin - }.orElse { - Option("""echo "There wasn't any previous content" - """.stripMargin) - } - - // just appending - rpmPostun := { - val prev = rpmPostun.value.getOrElse("") - Some(s"""|$prev - | echo "Hello you" - |""".stripMargin) - } - -or place your new scripts in the ``src/rpm/scriptlets`` folder. For example: + import RpmConstants._ + maintainerScripts in Rpm := Map( + Pre -> Seq("""echo "pre-install""""), + Post -> Seq("""echo "post-install""""), + Pretrans -> Seq("""echo "pretrans""""), + Posttrans -> Seq("""echo "posttrans""""), + Preun -> Seq("""echo "pre-uninstall""""), + Postun -> Seq("""echo "post-uninstall"""") + ) + + // appending with strings and replacements + import RpmConstants._ + maintainerScripts in Rpm := maintainerScriptsAppend((maintainerScripts in Rpm).value)( + Pretrans -> "echo 'hello, world'", + Post -> s"echo 'installing ${(packageName in Rpm).value}'" + ) + + // appending from a different file + import RpmConstants._ + maintainerScripts in Rpm := maintainerScriptsAppendFromFile((maintainerScripts in Rpm).value)( + Pretrans -> (sourceDirectory.value / "rpm" / "pretrans"), + Post -> (sourceDirectory.value / "rpm" / "posttrans") + ) + +The helper methods can be found in `MaintainerScriptHelper Scaladocs`_. + +You also can place new scripts in the ``src/rpm/scriptlets`` folder. For example: ``src/rpm/scriptlets/preinst`` @@ -333,9 +321,37 @@ or place your new scripts in the ``src/rpm/scriptlets`` folder. For example: ... Using files will override all previous contents. The names used can be found in -the `Scaladocs`_. +the `RPM Scaladocs`_. + +Scriptlet Migration from 1.0.x +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Before + +.. code-block:: scala + + rpmPostun := rpmPost.value.map { content => + s"""|$content + |echo "I append this to the current content + |""".stripMargin + }.orElse { + Option("""echo "There wasn't any previous content" + """.stripMargin) + } + +After + +.. code-block:: scala + + // this gives you easy access to the correct keys + import RpmConstants._ + // in order to append you have to pass the initial maintainerScripts map + maintainerScripts in Rpm := maintainerScriptsAppend((maintainerScripts in Rpm).value)( + Pretrans -> "echo 'hello, world'", + Post -> s"echo 'installing ${(packageName in Rpm).value}'" + ) + - Jar Repackaging ~~~~~~~~~~~~~~~ @@ -345,8 +361,8 @@ This behaviour is turned off by default with this setting. .. code-block:: scala rpmBrpJavaRepackJars := false - -Note that this appends content to your ``rpmPre`` definition, so make sure not to override it. + +Note that this appends content to your ``Pre`` definition, so make sure not to override it. For more information on this topic follow these links: * `issue #195`_ @@ -357,5 +373,5 @@ For more information on this topic follow these links: .. _issue #195: https://github.com/sbt/sbt-native-packager/issues/195 .. _pullrequest #199: https://github.com/sbt/sbt-native-packager/pull/199 .. _OpenSuse issue: https://github.com/sbt/sbt-native-packager/issues/215 - .. _Scaladocs: http://www.scala-sbt.org/sbt-native-packager/latest/api/#com.typesafe.sbt.packager.rpm.RpmPlugin$$Names$ - + .. _RPM Scaladocs: http://www.scala-sbt.org/sbt-native-packager/latest/api/#com.typesafe.sbt.packager.rpm.RpmPlugin$$Names$ + .. _MaintainerScriptHelper Scaladocs: http://www.scala-sbt.org/sbt-native-packager/latest/api/#com.typesafe.sbt.packager.MaintainerScriptHelper$ diff --git a/test-project-simple/build.sbt b/test-project-simple/build.sbt index ec5909f25..dad5343b7 100644 --- a/test-project-simple/build.sbt +++ b/test-project-simple/build.sbt @@ -6,7 +6,7 @@ libraryDependencies ++= Seq( mainClass in Compile := Some("ExampleApp") -enablePlugins(JavaAppPackaging, JDebPackaging) +enablePlugins(JavaServerAppPackaging, JDebPackaging) maintainer := "Josh Suereth " packageSummary := "Minimal Native Packager"