# 概述

sbt-native-packager 的初衷是：

“Code once, deploy anywhere”

# 介绍

SBT native packager允许您以原始格式构建应用程序包，并为常见配置(如简单Java应用程序或服务器应用程序)提供不同的模型（archetypes）。

## Goals 目标

1. Native formats should build on their respective platform
This allows native packager to support a wide range of formats as the packaging plugin serves as a wrapper around the actual packaging tool. However, alternative packaging plugins maybe provided if a java/scala implementation exists. As an example debian packages should always build on debian systems, however native packager provides an additional plugin that integrates JDeb for a platform independent packaging strategy.

1. Provide archetypes for zero configuration builds
While packaging plugins provide the how a package is created, archetypes provide the configuration for what gets packaged. Archetypes configure your build to create a package for a certain purpose. While an archetype may not support all packaging formats, it should work without configuration for the supported formats.

1. Enforce best-practices
There is no single way to create a package. Native packager tries to create packages following best practices, e.g. for file names, installation paths or script layouts.

## Scope 范围

While native packager provides a wide range of formats and archetype configurations, its scope is relatively narrow. Native packager only takes care of packaging, the act of putting a list of mappings (source file to install target path) into a distinct package format (zip, rpm, etc.).

1. 程序生命周期管理
2. 部署配置

## 核心概念

### 职责分离

1. format plugins： 如何创建 package （how）
2. archetype plugins：将哪些内容放入 package 中 （what）

### mappings 映射

Mappings are a Seq[(File, String)], which translates to “a list of tuples, where each tuple defines a source file that gets mapped to a path on the target system”.

The file part of the tuple must be available during the packaging phase. The String part represents the path inside the installation directory.

1. 其中 file 部分是只需要被打包的文件，需要在打包阶段已经生成完毕
2. 其中 String 部分表示安装目录的路径

# Universal Plugin

The Universal Plugin creates a generic, or “universal” distribution package. This is called “universal packaging.” Universal packaging just takes a plain mappings configuration and generates various package files in the output format specified. Because it creates a distribution that is not tied to any particular platform it may require manual labor (more work from your users) to correctly install and set up.

## 原理

By default, all files found in the src/universal directory are included in the distribution. So, the first step in creating a distribution is to place files in this directory and organize them as you’d like in them to be in the distributed package. If your output format is a zip file, for example, although the distribution will consist of just one zip file, the files and directories within that zip file will reflect the same organization and structure as src/universal.

To add files generated by the build task to a distribution, simply add a mapping to the mappings in Universal setting. Let’s look at an example where we add the packaged jar of a project to the lib folder of a distribution:

1. 依赖于 Compile 中的 packageBin，因为这个 task 会在 target 目录下生成 jar，这些 jar 是打包必备的核心内容。
2. 创建一个 mapping 是一个（Tuple2[File, String]），表示添加的文件和目标路径的字符串。

# 关于 Mapping 的各种方法总结

## 关于 setting 的操作符

You cannot find documentation, because as @JacekLaskowski correctly pointed out all operators except for +=, ++= and := are deprecated.

You can however find the Documentation if you switch to older version of sbt.

If you however are stuck to older version, this is their meaning (via documentation):

+= and ++= append to previous value, where first appends single element and next appends a Seq
~= transforms value, e.g. you want to use value stored in a setting to get a new setting.
<<= depends on another key, for example if you call organization <<= name, then organization value is equal to name value. You can depend on multiple values, e.g. organization <<= (name, version) { (n, v) => / do something with values / }
<+= and <++= are appending with dependencies, like the append, but you can use another’s setting value to compute new value
Said that, @JacekLaskowski is right, and if you are using sbt 13.x or greater you should not have to use those operators in favours of macros.

:= will replace the previous value
+= will append a single element to the sequence.
++= will concatenate another sequence.

~= applies a function to the setting’s previous value, producing a new value of the same type. 也就是将之前的值经过一些处理得到新的值，再赋值。

Unlike <<= of course, <+= and <++= will append to the previous value of the key on the left, rather than replacing it.

For example, say you have a coverage report named after the project, and you want to add it to the files removed by clean:

## 关于路径的获取方法

SBT provides the IO and Path APIs, which help make defining custom mappings easy. The files will appear in the generate universal zip, but also in your debian/rpm/msi/dmg builds as described above in the conventions.

https://www.scala-sbt.org/0.13.1/docs/Detailed-Topics/Paths.html

The packageBin in Compile dependency is only needed if your files get generated during the packageBin command or before. For static files you can remove it.