Skip to content

Commit 699e24b

Browse files
committed
Fixes #118
* Add customizable sbt keys for all template sources * Make sure current template sources are used by default. * Start on documentation for archetypes.
1 parent d9b49e7 commit 699e24b

File tree

7 files changed

+90
-38
lines changed

7 files changed

+90
-38
lines changed

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala

+14-7
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package archetypes
55
import Keys._
66
import sbt._
77
import sbt.Project.Initialize
8-
import sbt.Keys.{ mappings, target, name, mainClass, normalizedName }
8+
import sbt.Keys.{ mappings, target, name, mainClass, normalizedName, sourceDirectory }
99
import linux.LinuxPackageMapping
1010
import SbtNativePackager._
1111

@@ -43,15 +43,16 @@ object JavaAppPackaging {
4343
} yield JavaAppBashScript.makeDefines(cn, appClasspath = cp, extras = extras)
4444
hasMain getOrElse Nil
4545
},
46-
makeBashScript <<= (bashScriptDefines, target in Universal, normalizedName) map makeUniversalBinScript,
46+
// TODO - Overridable bash template.
47+
makeBashScript <<= (bashScriptDefines, target in Universal, normalizedName, sourceDirectory in Compile) map makeUniversalBinScript,
4748
batScriptExtraDefines := Nil,
4849
batScriptReplacements <<= (normalizedName, Keys.mainClass in Compile, scriptClasspath, batScriptExtraDefines) map { (name, mainClass, cp, extras) =>
4950
mainClass map { mc =>
5051
JavaAppBatScript.makeReplacements(name = name, mainClass = mc, appClasspath = cp, extras = extras)
5152
} getOrElse Nil
5253

5354
},
54-
makeBatScript <<= (batScriptReplacements, target in Universal, normalizedName) map makeUniversalBatScript,
55+
makeBatScript <<= (batScriptReplacements, target in Universal, normalizedName, sourceDirectory in Compile) map makeUniversalBatScript,
5556
mappings in Universal <++= (makeBashScript, normalizedName) map { (script, name) =>
5657
for {
5758
s <- script.toSeq
@@ -73,21 +74,27 @@ object JavaAppPackaging {
7374
else "../" + name
7475
}
7576

76-
def makeUniversalBinScript(defines: Seq[String], tmpDir: File, name: String): Option[File] =
77+
def makeUniversalBinScript(defines: Seq[String], tmpDir: File, name: String, sourceDir: File): Option[File] =
7778
if (defines.isEmpty) None
7879
else {
79-
val scriptBits = JavaAppBashScript.generateScript(defines)
80+
val defaultTemplateLocation = sourceDir / "templates" / "bash-template"
81+
val scriptBits =
82+
if(defaultTemplateLocation.exists) JavaAppBashScript.generateScript(defines, defaultTemplateLocation.toURI.toURL)
83+
else JavaAppBashScript.generateScript(defines)
8084
val script = tmpDir / "tmp" / "bin" / name
8185
IO.write(script, scriptBits)
8286
// TODO - Better control over this!
8387
script.setExecutable(true)
8488
Some(script)
8589
}
8690

87-
def makeUniversalBatScript(replacements: Seq[(String, String)], tmpDir: File, name: String): Option[File] =
91+
def makeUniversalBatScript(replacements: Seq[(String, String)], tmpDir: File, name: String, sourceDir: File): Option[File] =
8892
if (replacements.isEmpty) None
8993
else {
90-
val scriptBits = JavaAppBatScript.generateScript(replacements)
94+
val defaultTemplateLocation = sourceDir / "templates" / "bat-template"
95+
val scriptBits =
96+
if(defaultTemplateLocation.exists) JavaAppBatScript.generateScript(replacements, defaultTemplateLocation.toURI.toURL)
97+
else JavaAppBatScript.generateScript(replacements)
9198
val script = tmpDir / "tmp" / "bin" / (name + ".bat")
9299
IO.write(script, scriptBits)
93100
Some(script)

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppBashScript.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.typesafe.sbt.packager.archetypes
22

3+
import java.net.URL
4+
35
/**
46
* Constructs a bash script for running a java application.
57
*
@@ -33,10 +35,10 @@ object JavaAppBashScript {
3335
val fullString = cp map (n => "$lib_dir/"+n) mkString ":"
3436
"declare -r app_classpath=\""+fullString+"\"\n"
3537
}
36-
def generateScript(defines: Seq[String]): String = {
38+
def generateScript(defines: Seq[String], template: URL = bashTemplateSource): String = {
3739
val defineString = defines mkString "\n"
3840
val replacements = Seq("template_declares" -> defineString)
39-
TemplateWriter.generateScript(bashTemplateSource, replacements)
41+
TemplateWriter.generateScript(template, replacements)
4042
}
4143

4244
def configFileDefine(configFile: String) =

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppBatScript.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ object JavaAppBatScript {
5050
}
5151

5252
def generateScript(
53-
replacements: Seq[(String,String)]): String =
54-
TemplateWriter.generateScript(bashTemplateSource, replacements, "\r\n", TemplateWriter.batFriendlyKeySurround)
53+
replacements: Seq[(String,String)], template: java.net.URL = bashTemplateSource): String =
54+
TemplateWriter.generateScript(template, replacements, "\r\n", TemplateWriter.batFriendlyKeySurround)
5555

5656
}

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppUpstartScript.scala

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.typesafe.sbt.packager.archetypes
22

3+
import java.io.File
4+
import java.net.URL
5+
36
/**
47
* Constructs an start script for running a java application.
58
*
@@ -8,31 +11,32 @@ object JavaAppStartScript {
811

912
import ServerLoader._
1013

11-
protected def upstartTemplateSource: java.net.URL = getClass.getResource("upstart-template")
12-
protected def sysvinitTemplateSource: java.net.URL = getClass.getResource("sysvinit-template")
13-
protected def postinstTemplateSource: java.net.URL = getClass.getResource("postinst-template")
14-
protected def postinstSysvinitTemplateSource: java.net.URL = getClass.getResource("postinst-sysvinit-template")
15-
protected def preremTemplateSource: java.net.URL = getClass.getResource("prerem-template")
16-
17-
18-
def generateScript(replacements: Seq[(String, String)], loader: ServerLoader): String =
19-
loader match {
20-
case Upstart =>
21-
TemplateWriter.generateScript(upstartTemplateSource, replacements)
22-
case SystemV =>
23-
TemplateWriter.generateScript(sysvinitTemplateSource, replacements)
14+
protected def upstartTemplateSource: URL = getClass.getResource("upstart-template")
15+
protected def sysvinitTemplateSource: URL = getClass.getResource("sysvinit-template")
16+
protected def postinstTemplateSource: URL = getClass.getResource("postinst-template")
17+
protected def postinstSysvinitTemplateSource: URL = getClass.getResource("postinst-sysvinit-template")
18+
protected def preremTemplateSource: URL = getClass.getResource("prerem-template")
19+
20+
21+
def defaultStartScriptTemplate(loader: ServerLoader, defaultLocation: File): URL =
22+
if(defaultLocation.exists) defaultLocation.toURI.toURL
23+
else loader match {
24+
case Upstart => upstartTemplateSource
25+
case SystemV => sysvinitTemplateSource
2426
}
2527

2628

27-
def generatePrerm(appName: String): String =
28-
TemplateWriter.generateScript(preremTemplateSource, Seq("app_name" -> appName))
29+
def generatePrerm(appName: String, template: java.net.URL = preremTemplateSource): String =
30+
TemplateWriter.generateScript(template, Seq("app_name" -> appName))
2931

3032

31-
def generatePostinst(appName: String, loader: ServerLoader): String =
32-
loader match {
33-
case Upstart =>
33+
def generatePostinst(appName: String, loader: ServerLoader, template: Option[java.net.URL] = None): String =
34+
(template, loader) match {
35+
// User has overriden the default.
36+
case (Some(template), _) => TemplateWriter.generateScript(template, Seq("app_name" -> appName))
37+
case (_, Upstart) =>
3438
TemplateWriter.generateScript(postinstTemplateSource, Seq("app_name" -> appName))
35-
case SystemV =>
39+
case (_, SystemV) =>
3640
TemplateWriter.generateScript(postinstSysvinitTemplateSource, Seq("app_name" -> appName))
3741
}
3842

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala

+17-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package archetypes
44

55
import Keys._
66
import sbt._
7-
import sbt.Keys.{ target, mainClass, normalizedName }
7+
import sbt.Keys.{ target, mainClass, normalizedName, sourceDirectory }
88
import SbtNativePackager._
99
import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink, LinuxPlugin }
1010

@@ -28,6 +28,7 @@ object JavaServerAppPackaging {
2828
Seq(
2929
serverLoading := Upstart,
3030
daemonUser := Users.Root,
31+
// This one is begging for sbt 0.13 syntax...
3132
debianStartScriptReplacements <<= (
3233
maintainer in Debian, packageSummary in Debian, serverLoading in Debian, daemonUser in Debian, normalizedName,
3334
sbt.Keys.version, defaultLinuxInstallLocation, mainClass in Compile, scriptClasspath)
@@ -45,9 +46,18 @@ object JavaServerAppPackaging {
4546
appMainClass = mainClass.get,
4647
daemonUser = daemonUser)
4748
},
48-
debianMakeStartScript <<= (debianStartScriptReplacements, normalizedName, target in Universal, serverLoading in Debian)
49+
// TODO - Default locations shouldn't be so hacky.
50+
linuxStartScriptTemplate in Debian <<= (serverLoading in Debian, sourceDirectory in Compile) map { (loader, dir) =>
51+
JavaAppStartScript.defaultStartScriptTemplate(loader, dir / "templates" / "start")
52+
},
53+
debianMakeStartScript <<= (debianStartScriptReplacements, normalizedName, target in Universal, linuxStartScriptTemplate in Debian)
4954
map makeDebianStartScript,
50-
debianMakeEtcDefault <<= (normalizedName, target in Universal, serverLoading in Debian)
55+
linuxEtcDefaultTemplate in Debian <<= sourceDirectory in Compile map { dir =>
56+
val overrideScript = dir / "templates" / "etc-default"
57+
if(overrideScript.exists) overrideScript.toURI.toURL
58+
else etcDefaultTemplateSource
59+
},
60+
debianMakeEtcDefault <<= (normalizedName, target in Universal, serverLoading in Debian, linuxEtcDefaultTemplate in Debian)
5161
map makeEtcDefaultScript,
5262
linuxPackageMappings in Debian <++= (debianMakeEtcDefault, normalizedName) map { (conf, name) =>
5363
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name))).withConfig()).toSeq
@@ -58,7 +68,6 @@ object JavaServerAppPackaging {
5868
case Upstart => ("/etc/init/" + name + ".conf", "0644")
5969
case SystemV => ("/etc/init.d/" + name, "0755")
6070
}
61-
6271
for {
6372
s <- script.toSeq
6473
} yield LinuxPackageMapping(Seq(s -> path)).withPerms(permissions)
@@ -79,10 +88,10 @@ object JavaServerAppPackaging {
7988
debianMakePostinstScript <<= (normalizedName, target in Universal, serverLoading in Debian) map makeDebianPostinstScript)
8089

8190
private def makeDebianStartScript(
82-
replacements: Seq[(String, String)], name: String, tmpDir: File, loader: ServerLoader): Option[File] =
91+
replacements: Seq[(String, String)], name: String, tmpDir: File, template: URL): Option[File] =
8392
if (replacements.isEmpty) None
8493
else {
85-
val scriptBits = JavaAppStartScript.generateScript(replacements, loader)
94+
val scriptBits = TemplateWriter.generateScript(template, replacements)
8695
val script = tmpDir / "tmp" / "init" / name
8796
IO.write(script, scriptBits)
8897
Some(script)
@@ -102,11 +111,11 @@ object JavaServerAppPackaging {
102111
Some(script)
103112
}
104113

105-
protected def makeEtcDefaultScript(name: String, tmpDir: File, loader: ServerLoader): Option[File] = {
114+
protected def makeEtcDefaultScript(name: String, tmpDir: File, loader: ServerLoader, source: java.net.URL): Option[File] = {
106115
loader match {
107116
case Upstart => None
108117
case SystemV => {
109-
val scriptBits = TemplateWriter.generateScript(etcDefaultTemplateSource, Seq.empty)
118+
val scriptBits = TemplateWriter.generateScript(source, Seq.empty)
110119
val script = tmpDir / "tmp" / "etc" / "default" / name
111120
IO.write(script, scriptBits)
112121
Some(script)

src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ trait Keys {
1616
val linuxPackageMappings = TaskKey[Seq[LinuxPackageMapping]]("linux-package-mappings", "File to install location mappings including owner and privileges.")
1717
val linuxPackageSymlinks = TaskKey[Seq[LinuxSymlink]]("linux-package-symlinks", "Symlinks we should produce in the underlying package.")
1818
val generateManPages = TaskKey[Unit]("generate-man-pages", "Shows all the man files in the current project")
19+
20+
val linuxStartScriptTemplate = TaskKey[URL]("linuxStartScriptTemplate", "The location of the template start script file we use for debian (upstart or init.d")
21+
val linuxEtcDefaultTemplate = TaskKey[URL]("linuxEtcDefaultTemplate", "The location of the /etc/default/<pkg> template script.")
1922
}
2023

2124
object Keys extends Keys {

src/sphinx/archetypes.rst

+27
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,30 @@ produces a universal layout that looks like the following:
5656

5757

5858
You can add additional files to the project by placing things in ``src/windows``, ``src/universal`` or ``src/linux`` as needed.
59+
60+
61+
Java Server
62+
-----------
63+
64+
This archetype is designed for Java applications that are intended to run as
65+
servers or services. This archetype includes wiring such that the application
66+
is started immediately upon startup.
67+
68+
Currently supported operating systems:
69+
70+
* Ubuntu 12.04 LTS - Upstart
71+
* Ubuntu 12.04 LTS - init.d
72+
73+
74+
The Java Server archetype has a similar installation layout as the java
75+
application. The primary differneces are:
76+
77+
* Linux
78+
79+
* ``/var/log/<pkg>`` is symlinked from ``<install>/log``
80+
81+
* Creates a start script in ``/etc/init.d`` or ``/etc/init/``
82+
83+
* Creates a startup config file in ``/etc/default/<pkg>``
84+
85+

0 commit comments

Comments
 (0)