diff --git a/main-actions/src/main/scala/sbt/Package.scala b/main-actions/src/main/scala/sbt/Package.scala index 9ce8735b4..e9735ce10 100644 --- a/main-actions/src/main/scala/sbt/Package.scala +++ b/main-actions/src/main/scala/sbt/Package.scala @@ -25,6 +25,14 @@ import sbt.util.CacheImplicits._ import sbt.util.Tracked.{ inputChanged, outputChanged } sealed trait PackageOption + +/** + * == Package == + * + * This module provides an API to package jar files. + * + * @see [[https://docs.oracle.com/javase/tutorial/deployment/jar/index.html]] + */ object Package { final case class JarManifest(m: Manifest) extends PackageOption { assert(m != null) @@ -49,11 +57,25 @@ object Package { } } + /** + * The jar package configuration. Contains all relevant information to create a jar file. + * + * @param sources the jar contents + * @param jar the destination jar file + * @param options additional package information, e.g. jar manifest, main class or manifest attributes + */ final class Configuration( val sources: Seq[(File, String)], val jar: File, val options: Seq[PackageOption] ) + + /** + * + * @param conf the package configuration that should be build + * @param cacheStoreFactory used for jar caching. We try to avoid rebuilds as much as possible + * @param log feedback for the user + */ def apply(conf: Configuration, cacheStoreFactory: CacheStoreFactory, log: Logger): Unit = { val manifest = new Manifest val main = manifest.getMainAttributes @@ -67,24 +89,30 @@ object Package { } setVersion(main) - type Inputs = Map[File, String] :+: FilesInfo[ModifiedFileInfo] :+: Manifest :+: HNil + type Inputs = Seq[(File, String)] :+: FilesInfo[ModifiedFileInfo] :+: Manifest :+: HNil val cachedMakeJar = inputChanged(cacheStoreFactory make "inputs") { (inChanged, inputs: Inputs) => import exists.format val sources :+: _ :+: manifest :+: HNil = inputs outputChanged(cacheStoreFactory make "output") { (outChanged, jar: PlainFileInfo) => if (inChanged || outChanged) { - makeJar(sources.toSeq, jar.file, manifest, log) + makeJar(sources, jar.file, manifest, log) jar.file } else log.debug("Jar uptodate: " + jar.file) } } - val map = conf.sources.toMap - val inputs = map :+: lastModified(map.keySet) :+: manifest :+: HNil + val inputFiles = conf.sources.map(_._1).toSet + val inputs = conf.sources :+: lastModified(inputFiles) :+: manifest :+: HNil cachedMakeJar(inputs)(() => exists(conf.jar)) } + + /** + * updates the manifest version is there is none present. + * + * @param main the current jar attributes + */ def setVersion(main: Attributes): Unit = { val version = Attributes.Name.MANIFEST_VERSION if (main.getValue(version) eq null) { diff --git a/notes/1.3.0/enable-multiple-source-file-in-mappings.md b/notes/1.3.0/enable-multiple-source-file-in-mappings.md new file mode 100644 index 000000000..8a085472b --- /dev/null +++ b/notes/1.3.0/enable-multiple-source-file-in-mappings.md @@ -0,0 +1,9 @@ +[@muuki88]: https://github.com/muuki88 +[@gutefrageIT]: https://twitter.com/gutefrageIT + +[#1972]: https://github.com/sbt/sbt/issues/1972 +[#4329]: https://github.com/sbt/sbt/pull/4329 + +### Bug Fixes + +- Enable packaging of the same file more than once [#1972][]/[#4329][] by [@muuki88][] (sponsored by [@gutefrageIT][]) diff --git a/sbt/src/sbt-test/package/mappings/build.sbt b/sbt/src/sbt-test/package/mappings/build.sbt new file mode 100644 index 000000000..f135d3067 --- /dev/null +++ b/sbt/src/sbt-test/package/mappings/build.sbt @@ -0,0 +1,16 @@ +name := "Mappings Test" + +version := "0.2" + +mappings in (Compile, packageBin) ++= { + val test = file("test") + Seq( + test -> "test1", + test -> "test2" + ) +} + +lazy val unzipPackage = taskKey[Unit]("extract jar file") +unzipPackage := { + IO.unzip((packageBin in Compile).value, target.value / "extracted") +} \ No newline at end of file diff --git a/sbt/src/sbt-test/package/mappings/test b/sbt/src/sbt-test/package/mappings/test new file mode 100644 index 000000000..f95f9bb76 --- /dev/null +++ b/sbt/src/sbt-test/package/mappings/test @@ -0,0 +1,3 @@ +> unzipPackage +$ exists target/extracted/test2 +$ exists target/extracted/test1