Skip to content

Commit 3ebd08e

Browse files
committed
Assembly - Run the keep rule on Uber jar...
Instead of running them jar by jar, this makes the keep rule much more usable.
1 parent b074c40 commit 3ebd08e

File tree

1 file changed

+55
-15
lines changed

1 file changed

+55
-15
lines changed

src/main/scala/sbtassembly/Assembly.scala

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,30 @@ package sbtassembly
33
import com.eed3si9n.jarjarabrams._
44
import sbt.Def.Initialize
55
import sbt.Keys._
6-
import sbt.Package.{ manifestFormat, JarManifest, MainClass, ManifestAttributes }
6+
import sbt.Package.{JarManifest, MainClass, ManifestAttributes, manifestFormat}
77
import sbt.internal.util.HListFormats._
88
import sbt.internal.util.HNil
99
import sbt.internal.util.Types.:+:
10-
import sbt.io.{ DirectoryFilter => _, IO => _, Path => _, Using }
10+
import sbt.io.{Using, DirectoryFilter => _, IO => _, Path => _}
1111
import sbt.util.FileInfo.lastModified
12-
import sbt.util.Tracked.{ inputChanged, lastOutput }
13-
import sbt.util.{ FilesInfo, Level, ModifiedFileInfo }
14-
import sbt.{ File, Logger, _ }
12+
import sbt.util.Tracked.{inputChanged, lastOutput}
13+
import sbt.util.{FilesInfo, Level, ModifiedFileInfo}
14+
import sbt.{File, Logger, _}
1515
import sbt.Tags.Tag
1616
import CacheImplicits._
17-
import sbtassembly.AssemblyPlugin.autoImport.{ Assembly => _, _ }
17+
import com.eed3si9n.jarjar.util.{EntryStruct, IoUtil}
18+
import com.eed3si9n.jarjar.{JJProcessor, Keep}
19+
import org.apache.logging.log4j.core.util.IOUtils
20+
import sbtassembly.AssemblyPlugin.autoImport.{Assembly => _, _}
1821
import sbtassembly.PluginCompat.ClasspathUtilities
1922

2023
import java.io._
2124
import java.net.URI
22-
import java.nio.file.attribute.{ BasicFileAttributeView, FileTime, PosixFilePermission }
23-
import java.nio.file.{ Path, _ }
25+
import java.nio.file.attribute.{BasicFileAttributeView, FileTime, PosixFilePermission}
26+
import java.nio.file.{Path, _}
2427
import java.security.MessageDigest
2528
import java.time.Instant
26-
import java.util.jar.{ Attributes => JAttributes, JarFile, Manifest => JManifest }
29+
import java.util.jar.{JarFile, Attributes => JAttributes, Manifest => JManifest}
2730
import scala.annotation.tailrec
2831
import scala.collection.GenSeq
2932
import scala.collection.JavaConverters._
@@ -260,7 +263,12 @@ object Assembly {
260263
}
261264
}
262265

263-
val classShader = shader(ao.shadeRules.filter(_.isApplicableToCompiling), log)
266+
val classShader = shader(ao.shadeRules.filter(_.isApplicableToCompiling).filter(x => x.shadePattern match {
267+
case ShadePattern.Rename(_) => true
268+
case ShadePattern.Zap(_) => true
269+
case ShadePattern.Keep(_) => false
270+
}), log)
271+
264272
val classByParentDir =
265273
if (!ao.includeBin) Vector.empty[(File, File)]
266274
else dirs.flatMap(dir => (dir.data ** (-DirectoryFilter)).get.map(dir.data -> _))
@@ -336,12 +344,22 @@ object Assembly {
336344
timed(Level.Debug, "Finding remaining conflicts that were not merged") {
337345
reportConflictsMissedByTheMerge(mergedEntries, log)
338346
}
339-
val jarEntriesToWrite = timed(Level.Debug, "Sort/Parallelize merged entries") {
340-
if (ao.repeatableBuild) // we need the jars in a specific order to have a consistent hash
341-
mergedEntries.flatMap(_.entries).seq.sortBy(_.target)
342-
else // we actually gain performance when creating the jar in parallel, but we won't have a consistent hash
343-
mergedEntries.flatMap(_.entries).par
347+
348+
val jarEntriesToWrite = {
349+
val temp = mergedEntries.flatMap(_.entries)
350+
351+
val withKeepRule = timed(Level.Debug, "Keep") {
352+
keepShader(ao.shadeRules, log, temp)
353+
}
354+
355+
timed(Level.Debug, "Sort/Parallelize merged entries") {
356+
if (ao.repeatableBuild) // we need the jars in a specific order to have a consistent hash
357+
withKeepRule.sortBy(_.target)
358+
else // we actually gain performance when creating the jar in parallel, but we won't have a consistent hash
359+
withKeepRule.par
360+
}
344361
}
362+
345363
val localTime = timestamp
346364
.map(t => t - java.util.TimeZone.getDefault.getOffset(t))
347365
.getOrElse(System.currentTimeMillis())
@@ -481,6 +499,28 @@ object Assembly {
481499
def isScalaLibraryFile(scalaLibraries: Vector[String], file: File): Boolean =
482500
scalaLibraries exists { x => file.getName startsWith x }
483501

502+
private[sbtassembly] def keepShader(shadeRules: SeqShadeRules, log: Logger, entries: Seq[JarEntry]): Seq[JarEntry] = {
503+
val jjRules = shadeRules.map(_.shadePattern).collect({
504+
case ShadePattern.Keep(patterns) =>
505+
patterns.map(pattern => {
506+
val jrule = new Keep()
507+
jrule.setPattern(pattern)
508+
jrule
509+
})
510+
}).flatten
511+
512+
val proc = new JJProcessor(jjRules, false, true, null)
513+
entries.foreach({ entry =>
514+
val entryStruct = new EntryStruct()
515+
entryStruct.name = entry.target
516+
entryStruct.data = Streamable.bytes(entry.stream())
517+
proc.process(entryStruct)
518+
})
519+
520+
val itemsToExclude = proc.getExcludes
521+
entries.filterNot(entry => itemsToExclude.contains(entry.target))
522+
}
523+
484524
private[sbtassembly] def shader(
485525
shadeRules: SeqShadeRules,
486526
log: Logger

0 commit comments

Comments
 (0)