Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proguard contrib module #972

Merged
merged 9 commits into from
Nov 2, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions contrib/proguard/src/Proguard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,60 @@ import os.proc
import os.Path
import os.PathChunk

/** Adds proguard capabilities when mixed-in to a module
*
* The target name is `proguard`. This runs proguard on the output jar of `asssembly`
* and outputs a shrunk/obfuscated/optimized jar under `out.jar` in the `dest/` folder.
*
* Sensible defaults are provided, so no members require overriding..
*
*/
trait Proguard extends ScalaModule {

// This is actually the only available version on Maven currently.
// But we should keep it as a configuration in case a new version is released.
/** The version of proguard to download from Maven.
*
* Note that currently this is the only available version. */
def proguardVersion: T[String] = T { "7.0.0" }

/** Run the "shrink" step in the proguard pipeline. Defaults to true. */
def shrink: T[Boolean] = T { true }

/** Run the "optimize" step in the proguard pipeline. Defaults to true. */
def optimize: T[Boolean] = T { true }

/** Run the "obfuscate" step in the proguard pipeline. Defaults to true. */
def obfuscate: T[Boolean] = T { true }

/** Run the "optimize" step in the proguard pipeline. Defaults to true.
*
* Note that this is required for Java 7 and above.
*/
def preverify: T[Boolean] = T { true }

/** The path to JAVA_HOME.
*
* This is used for both the `java` command binary,
* as well as the standard library jars.
* Defaults to the `java.home` system property. */
def javaHome: T[PathRef] = T {
PathRef(Path(System.getProperty("java.home")))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to mark this target as input, otherwise mills caching would hide potential changes of the system property.

Suggested change
def javaHome: T[PathRef] = T {
PathRef(Path(System.getProperty("java.home")))
}
def javaHome: T[PathRef] = T.input {
PathRef(Path(System.getProperty("java.home")))
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll make the change. But I'm wondering now if this should actually be Sources? What's the difference?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sources and also Source are specializations of Input. Also Source(s) support the watch mode (mill -w), whereas Input is not able to trigger a re-build on it's own.


/** Specifies the input jar to proguard. Defaults to the output of the `assembly` task. */ */
def inJar: T[PathRef] = T { assembly() }

/** The library jars proguard requires
* Defaults the jars under `javaHome`. */
def libraryJars: T[Seq[PathRef]] = T {
val javaJars = os.list(javaHome().path / "lib", sort = false).filter(_.ext == "jar")
javaJars.toSeq.map(PathRef(_))
}

/** Run the proguard task.
*
* The full command will be printed when run.
* The stdout and stderr of the command are written to the `dest/` folder.
* The output jar is written to `dest/our.jar`. */
def proguard: T[PathRef] = T {
val outJar = PathRef(T.dest / "out.jar")
lefou marked this conversation as resolved.
Show resolved Hide resolved
val java = javaHome().path / "bin" / "java"
Expand Down Expand Up @@ -60,26 +92,38 @@ trait Proguard extends ScalaModule {
outJar
lefou marked this conversation as resolved.
Show resolved Hide resolved
}

/** The location of the proguard jar files.
* These are downloaded from JCenter and fed to `java -cp`
*/
def proguardClasspath: T[Loose.Agg[PathRef]] = T {
resolveDependencies(
Seq(Repositories.jcenter),
Lib.depToDependencyJava(_),
Seq(ivy"com.guardsquare:proguard-base:${proguardVersion()}"))
}

def steps: T[Seq[String]] = T {
private def steps: T[Seq[String]] = T {
(if (optimize()) Seq() else Seq("-dontoptimize")) ++
(if (obfuscate()) Seq() else Seq("-dontobfuscate")) ++
(if (shrink()) Seq() else Seq("-dontshrink")) ++
(if (preverify()) Seq() else Seq("-dontpreverify"))
}

/** The default `entrypoint` to proguard.
*
* Defaults to the `main` method of `finalMainClass`.
* Can be overriden to specify a different entrypoint,
* or additional entrypoints can be specified with `additionalOptions`. */
def entryPoint: T[String] = T {
s"""|-keep public class ${finalMainClass()} {
| public static void main(java.lang.String[]);
|}
|""".stripMargin
}

/** Specify any additional options to proguard.
*
* These are fed as-is to the proguard command.
* */
def additionalOptions: T[Seq[String]] = T { Seq[String]() }
}