Skip to content

Commit

Permalink
Merge pull request #6 from joan38/iterable
Browse files Browse the repository at this point in the history
Ability to create Bytes shader function
  • Loading branch information
eed3si9n authored Aug 21, 2020
2 parents 9e3dc32 + 20f65cd commit cf68c46
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 67 deletions.
119 changes: 61 additions & 58 deletions core/src/main/scala/com/eed3si9n/jarjarabrams/Shader.scala
Original file line number Diff line number Diff line change
@@ -1,79 +1,82 @@
package com.eed3si9n.jarjarabrams

import java.io.{ByteArrayInputStream, InputStream}
import java.nio.file.{ Files, Path, StandardOpenOption }
import org.pantsbuild.jarjar.{ JJProcessor, _ }
import org.pantsbuild.jarjar.util.EntryStruct
import com.eed3si9n.jarjarabrams.Utils.readAllBytes

object Shader {
def shadeDirectory(
rules: Seq[ShadeRule],
dir: Path,
mappings: Seq[(Path, String)],
verbose: Boolean
): Unit = {
val inputStreams = mappings.filter(x => !Files.isDirectory(x._1)).map(x => Files.newInputStream(x._1) -> x._2)
val newMappings = shadeInputStreams(rules, inputStreams, verbose)
mappings.filterNot(_._1.toFile.isDirectory).foreach(f => Files.delete(f._1))
newMappings.foreach { case (inputStream, mapping) =>
val out = dir.resolve(mapping)
if (!Files.exists(out.getParent)) Files.createDirectories(out.getParent)
Files.write(out, readAllBytes(inputStream), StandardOpenOption.CREATE)
): Unit =
if (rules.isEmpty) {}
else {
val shader = bytecodeShader(rules, verbose)
for {
(path, name) <- mappings
if !Files.isDirectory(path)
bytes = Files.readAllBytes(path)
_ = Files.delete(path)
(shadedBytes, shadedName) <- shader(bytes, name)
out = dir.resolve(shadedName)
_ = Files.createDirectories(out.getParent)
_ = Files.write(out, shadedBytes, StandardOpenOption.CREATE)
} yield ()
}
}

def shadeInputStreams(
rules: Seq[ShadeRule],
mappings: Seq[(InputStream, String)],
verbose: Boolean
): Seq[(InputStream, String)] = {
val jjrules = rules.flatMap { r =>
r.shadePattern match {
case ShadePattern.Rename(patterns) =>
patterns.map { case (from, to) =>
val jrule = new Rule()
jrule.setPattern(from)
jrule.setResult(to)
jrule
}
case ShadePattern.Zap(patterns) =>
patterns.map { pattern =>
val jrule = new Zap()
jrule.setPattern(pattern)
jrule
}
case ShadePattern.Keep(patterns) =>
patterns.map { pattern =>
val jrule = new Keep()
jrule.setPattern(pattern)
jrule
}
case _ => Nil
def bytecodeShader(
rules: Seq[ShadeRule],
verbose: Boolean
): (Array[Byte], String) => Option[(Array[Byte], String)] =
if (rules.isEmpty) (bytes, mapping) => Some(bytes -> mapping)
else {
val jjrules = rules.flatMap { r =>
r.shadePattern match {
case ShadePattern.Rename(patterns) =>
patterns.map { case (from, to) =>
val jrule = new Rule()
jrule.setPattern(from)
jrule.setResult(to)
jrule
}
case ShadePattern.Zap(patterns) =>
patterns.map { pattern =>
val jrule = new Zap()
jrule.setPattern(pattern)
jrule
}
case ShadePattern.Keep(patterns) =>
patterns.map { pattern =>
val jrule = new Keep()
jrule.setPattern(pattern)
jrule
}
case _ => Nil
}
}
}

val proc = new JJProcessor(jjrules, verbose, true, null)
val proc = new JJProcessor(jjrules, verbose, true, null)
val excludes = proc.getExcludes

/*
jarjar MisplacedClassProcessor class transforms byte[] to a class using org.objectweb.asm.ClassReader.getClassName
which always translates class names containing '.' into '/', regardless of OS platform.
We need to transform any windows file paths in order for jarjar to match them properly and not omit them.
*/
val sanitizedMappings =
mappings.map(f => if (f._2.contains('\\')) (f._1, f._2.replace('\\', '/')) else f)
val shadedInputStreams = sanitizedMappings.flatMap { f =>
val entry = new EntryStruct
entry.data = readAllBytes(f._1)
entry.name = f._2
entry.time = -1
entry.skipTransform = false
if (proc.process(entry)) Some(new ByteArrayInputStream(entry.data) -> entry.name)
else None
(bytes, mapping) =>
/*
jarjar MisplacedClassProcessor class transforms byte[] to a class using org.objectweb.asm.ClassReader.getClassName
which always translates class names containing '.' into '/', regardless of OS platform.
We need to transform any windows file paths in order for jarjar to match them properly and not omit them.
*/
val sanitizedMapping = if (mapping.contains('\\')) mapping.replace('\\', '/') else mapping
val entry = new EntryStruct
entry.data = bytes
entry.name = sanitizedMapping
entry.time = -1
entry.skipTransform = false
if (!excludes.contains(entry.name) && proc.process(entry))
Some(entry.data -> entry.name)
else
None
}
val excludes = proc.getExcludes
shadedInputStreams.filterNot(mapping => excludes.contains(mapping._2))
}
}

sealed trait ShadePattern {
Expand Down
9 changes: 0 additions & 9 deletions core/src/main/scala/com/eed3si9n/jarjarabrams/Utils.scala

This file was deleted.

0 comments on commit cf68c46

Please sign in to comment.