Skip to content

Commit d65ce7f

Browse files
committed
FIX #285 FIX #287 FIX #52 FIX #312 Improved docs for packageMappings in Universal and Linux
Conflicts: src/sphinx/DetailedTopics/index.rst
1 parent 56b1875 commit d65ce7f

File tree

6 files changed

+463
-4
lines changed

6 files changed

+463
-4
lines changed

src/sphinx/DetailedTopics/archetypes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,4 @@ You can use ``${{variable_name}}`` to reference variables when writing your scir
195195

196196
Creating a file here will override the ``/etc/default/<application>`` template
197197
used when SystemV is the server loader.
198+

src/sphinx/DetailedTopics/custom.rst

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
.. _Custom:
2+
3+
Custom Package Formats
4+
======================
5+
6+
This section provides an overview of different pacakging flavors.
7+
8+
SBT Assembly
9+
------------
10+
11+
**Main Goal**
12+
13+
| Create a fat-jar with sbt-assembly in order to deliever a single,
14+
| self-containing jar as a package instead of the default lib/ structure
15+
16+
First add the sbt-assembly plugin to your `plugins.sbt` file.
17+
18+
.. code-block:: scala
19+
20+
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
21+
22+
The next step is to remove all the jar mappings from the normal mappings and only add the
23+
assembly jar. In this example we'll set the assembly jar name ourself, so we know exactly
24+
what the output should look like. Finally we change the ``scriptClasspath`` so it only
25+
contains the assembled jar. This is what the final ``build.sbt`` should contain:
26+
27+
.. code-block:: scala
28+
29+
// the assembly settings
30+
assemblySettings
31+
32+
// we specify the name for our fat jar
33+
jarName in assembly := "assembly-project.jar"
34+
35+
// using the java server for this application. java_application is fine, too
36+
packageArchetype.java_server
37+
38+
// removes all jar mappings in universal and appends the fat jar
39+
mappings in Universal := {
40+
// universalMappings: Seq[(File,String)]
41+
val universalMappings = (mappings in Universal).value
42+
val fatJar = (assembly in Compile).value
43+
// removing means filtering
44+
val filtered = universalMappings filter {
45+
case (file, name) => ! name.endsWith(".jar")
46+
}
47+
// add the fat jar
48+
filtered :+ (fatJar -> ("lib/" + fatJar.getName))
49+
}
50+
51+
52+
// the bash scripts classpath only needs the fat jar
53+
scriptClasspath := Seq( (jarName in assembly).value )
54+
55+
Multi Module Builds
56+
-------------------
57+
58+
**Main Goal**
59+
60+
| Aggregate multiple projects into one native package
61+
62+
If you want to aggregate different projects in a multi module build to a single package,
63+
you can specify everthing in a single ``build.sbt``
64+
65+
.. code-block:: scala
66+
67+
import NativePackagerKeys._
68+
69+
name := "mukis-fullstack"
70+
71+
// used like the groupId in maven
72+
organization in ThisBuild := "de.mukis"
73+
74+
// all sub projects have the same version
75+
version in ThisBuild := "1.0"
76+
77+
scalaVersion in ThisBuild := "2.11.2"
78+
79+
// common dependencies
80+
libraryDependencies in ThisBuild ++= Seq(
81+
"com.typesafe" % "config" % "1.2.0"
82+
)
83+
84+
// this is the root project, aggregating all sub projects
85+
lazy val root = Project(
86+
id = "root",
87+
base = file("."),
88+
// configure your native packaging settings here
89+
settings = packageArchetype.java_server++ Seq(
90+
maintainer := "John Smith <[email protected]>",
91+
packageDescription := "Fullstack Application",
92+
packageSummary := "Fullstack Application",
93+
// entrypoint
94+
mainClass in Compile := Some("de.mukis.frontend.ProductionServer")
95+
),
96+
// always run all commands on each sub project
97+
aggregate = Seq(frontend, backend, api)
98+
) dependsOn(frontend, backend, api) // this does the actual aggregation
99+
100+
// --------- Project Frontend ------------------
101+
lazy val frontend = Project(
102+
id = "frontend",
103+
base = file("frontend")
104+
) dependsOn(api)
105+
106+
107+
// --------- Project Backend ----------------
108+
lazy val backend = Project(
109+
id = "backend",
110+
base = file("backend")
111+
) dependsOn(api)
112+
113+
// --------- Project API ------------------
114+
lazy val api = Project(
115+
id = "api",
116+
base = file("api")
117+
)
118+
119+
120+
Custom Packaging Format
121+
-----------------------
122+
123+
**Main Goal**
124+
125+
| Use native packager to define your own custom packaging format
126+
| and reuse stuff you already like
127+
128+
The very core principle of native packager are the ``mappings``. They are a sequence
129+
of ``File -> String`` tuples, that map a file on your system to a location on your install
130+
location.
131+
132+
Defining a custom mapping format is basically transforming these mappings into the format
133+
of you choice. To do so, we recommend the following steps
134+
135+
1. Create a new configuration ``scope`` for you packaging type
136+
2. Define a ``packageBin`` task in your new scope that transforms the mappings into a package
137+
138+
The following examples demonstrates how to create a simple *text format*, which lists all your
139+
mappings inside a package format. A minimal ``build.sbt`` would look like this
140+
141+
.. code-block:: scala
142+
143+
import NativePackagerKeys._
144+
145+
val TxtFormat = config("txtFormat")
146+
147+
val root = project.in(file("."))
148+
// adding your custom configuration scope
149+
.configs( TxtFormat )
150+
.settings(packageArchetype.java_server:_*)
151+
.settings(
152+
name := "mukis-custom-package",
153+
version := "1.0",
154+
mainClass in Compile := Some("de.mukis.ConfigApp"),
155+
maintainer in Linux := "Nepomuk Seiler <[email protected]>",
156+
packageSummary in Linux := "Custom application configuration",
157+
packageDescription := "Custom application configuration",
158+
// defining your custom configuration
159+
packageBin in TxtFormat := {
160+
val fileMappings = (mappings in Universal).value
161+
val output = target.value / s"${packageName.value}.txt"
162+
// create the is with the mappings. Note this is not the ISO format -.-
163+
IO.write(output, "# Filemappings\n")
164+
// append all mappings to the list
165+
fileMappings foreach {
166+
case (file, name) => IO.append(output, s"${file.getAbsolutePath}\t$name${IO.Newline}")
167+
}
168+
output
169+
}
170+
)
171+
172+
To create your new "packageFormat" just run
173+
174+
.. code-block:: bash
175+
176+
txtFormat:packageBin
177+
178+
If you want to read more about sbt configurations:
179+
180+
* `sbt tasks <http://www.scala-sbt.org/0.13/docs/Tasks.html>`_
181+
* `sbt configurations <http://www.scala-sbt.org/0.13.5/docs/Detailed-Topics/Testing.html#additional-test-configurations-with-shared-sources>`_
182+
* `custom configuration <http://stackoverflow.com/questions/18789477/define-custom-configuration-in-sbt>`_
183+

src/sphinx/DetailedTopics/index.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ Advanced Topics
1212
redhat.rst
1313
debian.rst
1414
windows.rst
15-
docker.rst
15+
docker.rst
16+
paths.rst
17+
custom.rst

0 commit comments

Comments
 (0)