From 46971c03e87b0af1df2ae737ce432730b1ce4eb5 Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Fri, 25 Sep 2020 15:41:36 -0400 Subject: [PATCH 1/9] WIP: Initial proguard implementation --- build.sc | 6 +++ contrib/proguard/src/Proguard.scala | 67 +++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 contrib/proguard/src/Proguard.scala diff --git a/build.sc b/build.sc index f3b74228f75..9960e6a531d 100755 --- a/build.sc +++ b/build.sc @@ -75,6 +75,7 @@ object Deps { val zinc = ivy"org.scala-sbt::zinc:1.4.0-M1" val bsp = ivy"ch.epfl.scala:bsp4j:2.0.0-M4" val jarjarabrams = ivy"com.eed3si9n.jarjarabrams::jarjar-abrams-core:0.3.0" + val proguard = ivy"com.guardsquare:proguard-core:7.0.0" } trait MillPublishModule extends PublishModule{ @@ -454,6 +455,11 @@ object contrib extends MillModule { } } + object proguard extends MillModule { + override def moduleDeps = Seq(scalalib) + def ivyDeps = Agg(Deps.proguard, Deps.osLib) + } + object tut extends MillModule { override def compileModuleDeps = Seq(scalalib) def testArgs = T{ diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala new file mode 100644 index 00000000000..44abfde57d4 --- /dev/null +++ b/contrib/proguard/src/Proguard.scala @@ -0,0 +1,67 @@ +package mill.contrib.proguard + +import coursier.Repositories +import mill.T +import mill.Agg +import mill.api.{Logger, Loose, PathRef, Result} +import mill.define.{Sources, Target} +import mill.scalalib.Lib.resolveDependencies +import mill.scalalib.{Dep, DepSyntax, Lib, ScalaModule} +import os.proc +import os.Path +import os.PathChunk + +trait Proguard extends ScalaModule { + def proguardVersion: T[String] = T { "4.4" } + + def shrink: T[Boolean] = T { true } + + def optimize: T[Boolean] = T { true } + + def obfuscate: T[Boolean] = T { true } + + def preverify: T[Boolean] = T { true } + + // maybe this should be the assembly() target instead? + def inJars: T[Seq[PathRef]] = T { localClasspath() } + + def outJar: T[PathRef] = T { PathRef(T.dest / "out.jar") } + + def libraryJars: T[Seq[PathRef]] = T { upstreamAssemblyClasspath().iterator.to(Seq) } + + def proguard: T[PathRef] = T { + os + .proc( + "java -jar", + proguardClasspath().indexed.head.path, + "-injars", + inJars().map(_.path), + "-outjars", + outJar().path, + "-libraryjars", + libraryJars().map(_.path), + steps(), + additionalOptions() + ) + .call(stdout = T.dest / "stdout.txt", stderr = T.dest / "stderr.txt") + + // the call above already throws an exception on a non-zero exit code + outJar() + } + + def proguardClasspath: T[Loose.Agg[PathRef]] = T { + resolveDependencies( + Seq(Repositories.central), + Lib.depToDependencyJava(_), + Seq(ivy"net.sf.proguard:proguard:${proguardVersion()}")) + } + + 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")) + } + + def additionalOptions: T[Seq[String]] = T { Seq[String]() } +} From 7302ee55bcc55efa4f59250970d53efeb1642cb6 Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Fri, 25 Sep 2020 19:30:05 -0400 Subject: [PATCH 2/9] More progress: get proguard actually running --- contrib/proguard/src/Proguard.scala | 35 ++++++++++++++--------------- scratch/build.sc | 6 ++++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index 44abfde57d4..f30ed5fad1e 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -12,30 +12,27 @@ import os.Path import os.PathChunk trait Proguard extends ScalaModule { - def proguardVersion: T[String] = T { "4.4" } + def proguardVersion: T[String] = T { "7.0.0" } def shrink: T[Boolean] = T { true } - def optimize: T[Boolean] = T { true } - def obfuscate: T[Boolean] = T { true } - def preverify: T[Boolean] = T { true } - // maybe this should be the assembly() target instead? - def inJars: T[Seq[PathRef]] = T { localClasspath() } - + def inJar: T[PathRef] = T { assembly() } def outJar: T[PathRef] = T { PathRef(T.dest / "out.jar") } - - def libraryJars: T[Seq[PathRef]] = T { upstreamAssemblyClasspath().iterator.to(Seq) } + def libraryJars: T[Seq[PathRef]] = T { + upstreamAssemblyClasspath().toSeq + } def proguard: T[PathRef] = T { - os - .proc( - "java -jar", - proguardClasspath().indexed.head.path, + val cmd = os.proc( + "java", + "-cp", + proguardClasspath().map(_.path).mkString(":"), + "proguard.ProGuard", "-injars", - inJars().map(_.path), + inJar().path, "-outjars", outJar().path, "-libraryjars", @@ -43,17 +40,19 @@ trait Proguard extends ScalaModule { steps(), additionalOptions() ) - .call(stdout = T.dest / "stdout.txt", stderr = T.dest / "stderr.txt") + System.out.println("Running command: " + cmd.command.flatMap(_.value).mkString(" ")) + cmd.call(stdout = T.dest / "stdout.txt", stderr = T.dest / "stderr.txt") - // the call above already throws an exception on a non-zero exit code + // the call above already throws an exception on a non-zero exit code, + // so if we reached this point we've succeeded! outJar() } def proguardClasspath: T[Loose.Agg[PathRef]] = T { resolveDependencies( - Seq(Repositories.central), + Seq(Repositories.jcenter), Lib.depToDependencyJava(_), - Seq(ivy"net.sf.proguard:proguard:${proguardVersion()}")) + Seq(ivy"com.guardsquare:proguard-base:${proguardVersion()}")) } def steps: T[Seq[String]] = T { diff --git a/scratch/build.sc b/scratch/build.sc index e0219632467..057fdf2d5be 100644 --- a/scratch/build.sc +++ b/scratch/build.sc @@ -1,6 +1,10 @@ import mill._ import mill.scalalib._ +//import mill.contrib.Proguard -object foo extends ScalaModule{ +import $ivy.`com.lihaoyi::mill-contrib-proguard:$MILL_VERSION` +import contrib.proguard._ + +object foo extends ScalaModule with Proguard { def scalaVersion = "2.13.2" } \ No newline at end of file From 81a8b16088830fb695681bf5b15d6630dce29e5d Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Mon, 5 Oct 2020 12:23:28 -0400 Subject: [PATCH 3/9] Finish proguard plugin --- contrib/proguard/src/Proguard.scala | 46 +++++++++++++++++++---------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index f30ed5fad1e..6ccc91886fb 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -12,6 +12,9 @@ import os.Path import os.PathChunk 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. def proguardVersion: T[String] = T { "7.0.0" } def shrink: T[Boolean] = T { true } @@ -19,28 +22,34 @@ trait Proguard extends ScalaModule { def obfuscate: T[Boolean] = T { true } def preverify: T[Boolean] = T { true } + def javaHome: T[PathRef] = T { + PathRef(Path(System.getProperty("java.home"))) + } + def inJar: T[PathRef] = T { assembly() } def outJar: T[PathRef] = T { PathRef(T.dest / "out.jar") } def libraryJars: T[Seq[PathRef]] = T { - upstreamAssemblyClasspath().toSeq + val javaJars = os.list(javaHome().path / "lib", sort = false).filter(_.ext == "jar") + javaJars.toSeq.map(PathRef(_)) } def proguard: T[PathRef] = T { val cmd = os.proc( - "java", - "-cp", - proguardClasspath().map(_.path).mkString(":"), - "proguard.ProGuard", - "-injars", - inJar().path, - "-outjars", - outJar().path, - "-libraryjars", - libraryJars().map(_.path), - steps(), - additionalOptions() - ) - System.out.println("Running command: " + cmd.command.flatMap(_.value).mkString(" ")) + "java", + "-cp", + proguardClasspath().map(_.path).mkString(":"), + "proguard.ProGuard", + steps(), + "-injars", + inJar().path, + "-outjars", + outJar().path, + "-libraryjars", + libraryJars().map(_.path).mkString(":"), + entryPoint(), + additionalOptions() + ) + System.out.println(cmd.command.flatMap(_.value).mkString(" ")) cmd.call(stdout = T.dest / "stdout.txt", stderr = T.dest / "stderr.txt") // the call above already throws an exception on a non-zero exit code, @@ -62,5 +71,12 @@ trait Proguard extends ScalaModule { (if (preverify()) Seq() else Seq("-dontpreverify")) } + def entryPoint: T[String] = T { + s"""|-keep public class ${finalMainClass()} { + | public static void main(java.lang.String[]); + |} + |""".stripMargin + } + def additionalOptions: T[Seq[String]] = T { Seq[String]() } } From 5bf236bf255a2014fe79ea3d7270c17bded421fb Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Mon, 5 Oct 2020 12:26:40 -0400 Subject: [PATCH 4/9] Reset file --- scratch/build.sc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scratch/build.sc b/scratch/build.sc index 057fdf2d5be..e0219632467 100644 --- a/scratch/build.sc +++ b/scratch/build.sc @@ -1,10 +1,6 @@ import mill._ import mill.scalalib._ -//import mill.contrib.Proguard -import $ivy.`com.lihaoyi::mill-contrib-proguard:$MILL_VERSION` -import contrib.proguard._ - -object foo extends ScalaModule with Proguard { +object foo extends ScalaModule{ def scalaVersion = "2.13.2" } \ No newline at end of file From 562c3c44e1f0892a1c29cb1286533c3d2f5ef5e2 Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Tue, 6 Oct 2020 12:55:14 -0400 Subject: [PATCH 5/9] PR feedback --- build.sc | 4 +--- contrib/proguard/src/Proguard.scala | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.sc b/build.sc index 9960e6a531d..377579c7b91 100755 --- a/build.sc +++ b/build.sc @@ -75,7 +75,6 @@ object Deps { val zinc = ivy"org.scala-sbt::zinc:1.4.0-M1" val bsp = ivy"ch.epfl.scala:bsp4j:2.0.0-M4" val jarjarabrams = ivy"com.eed3si9n.jarjarabrams::jarjar-abrams-core:0.3.0" - val proguard = ivy"com.guardsquare:proguard-core:7.0.0" } trait MillPublishModule extends PublishModule{ @@ -456,8 +455,7 @@ object contrib extends MillModule { } object proguard extends MillModule { - override def moduleDeps = Seq(scalalib) - def ivyDeps = Agg(Deps.proguard, Deps.osLib) + override def compileModuleDeps = Seq(scalalib) } object tut extends MillModule { diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index 6ccc91886fb..bfecb330c0e 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -27,13 +27,15 @@ trait Proguard extends ScalaModule { } def inJar: T[PathRef] = T { assembly() } - def outJar: T[PathRef] = T { PathRef(T.dest / "out.jar") } + def libraryJars: T[Seq[PathRef]] = T { val javaJars = os.list(javaHome().path / "lib", sort = false).filter(_.ext == "jar") javaJars.toSeq.map(PathRef(_)) } def proguard: T[PathRef] = T { + val outJar = PathRef(T.dest / "out.jar") + val cmd = os.proc( "java", "-cp", @@ -54,7 +56,7 @@ trait Proguard extends ScalaModule { // the call above already throws an exception on a non-zero exit code, // so if we reached this point we've succeeded! - outJar() + outJar } def proguardClasspath: T[Loose.Agg[PathRef]] = T { From 6d0804a431fa4098b6e8def88f8b7e1656fe9347 Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Wed, 7 Oct 2020 12:25:23 -0400 Subject: [PATCH 6/9] Add documentation; use Java home binary --- contrib/proguard/src/Proguard.scala | 5 +++-- docs/pages/9 - Contrib Modules.md | 32 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index bfecb330c0e..5513c32a2c4 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -35,9 +35,10 @@ trait Proguard extends ScalaModule { def proguard: T[PathRef] = T { val outJar = PathRef(T.dest / "out.jar") + val java = javaHome().path / "bin" / "java" val cmd = os.proc( - "java", + java, "-cp", proguardClasspath().map(_.path).mkString(":"), "proguard.ProGuard", @@ -45,7 +46,7 @@ trait Proguard extends ScalaModule { "-injars", inJar().path, "-outjars", - outJar().path, + outJar.path, "-libraryjars", libraryJars().map(_.path).mkString(":"), entryPoint(), diff --git a/docs/pages/9 - Contrib Modules.md b/docs/pages/9 - Contrib Modules.md index 80fea16e8c9..74c1e2e045b 100644 --- a/docs/pages/9 - Contrib Modules.md +++ b/docs/pages/9 - Contrib Modules.md @@ -622,6 +622,38 @@ object app extends ScalaModule with RouterModule { } ``` +## Proguard + +This module allows [Proguard](https://www.guardsquare.com/en/products/proguard/manual/introduction) to be used in Mill builds. +ProGuard is a Java class file shrinker, optimizer, obfuscator, and preverifier. + +By default, all four steps - shrink, optimize, obfuscate, verify - are run, but this can be configured through task options. +Any additional options can be specified as a list of strings with `additionalOptions`. The full list of proguard options +can be found [here](https://www.guardsquare.com/en/products/proguard/manual/usage). + +The output of `assembly` is used as the input jar and the output is written to `out.jar` in the `dest` folder. + +The `stdout` and `stderr` from the proguard command can be found under the `dest` folder. + +The only default entrypoint is the main class (i.e. `finalMainClass` task). Additional entrypoints can be configured using `additionalOptions` as well. + +Here is a simple example: + +``` +import $ivy.`com.lihaoyi::mill-contrib-proguard:$MILL_VERSION` +import contrib.proguard._ + +object foo extends ScalaModule with Proguard { + def scalaVersion = "2.12.0" + + override def shrink: T[Boolean] = T { true } + override def optimize: T[Boolean] = T { false } + override def obfuscate: T[Boolean] = T { false } +} +``` + +Also, please note that Proguard doesn't seem to work with scala 2.13 yet. + ## ScalaPB This module allows [ScalaPB](https://scalapb.github.io) to be used in Mill builds. ScalaPB is a [Protocol Buffers](https://developers.google.com/protocol-buffers/) compiler plugin that generates Scala case classes, encoders and decoders for protobuf messages. From 22accede0408ffaa3c04123b86d92553f01ab62e Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Thu, 8 Oct 2020 14:09:59 -0400 Subject: [PATCH 7/9] Add ScalaDoc --- contrib/proguard/src/Proguard.scala | 50 +++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index 5513c32a2c4..6db579af3b3 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -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"))) } + /** 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") val java = javaHome().path / "bin" / "java" @@ -60,6 +92,9 @@ trait Proguard extends ScalaModule { outJar } + /** 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), @@ -67,13 +102,18 @@ trait Proguard extends ScalaModule { 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[]); @@ -81,5 +121,9 @@ trait Proguard extends ScalaModule { |""".stripMargin } + /** Specify any additional options to proguard. + * + * These are fed as-is to the proguard command. + * */ def additionalOptions: T[Seq[String]] = T { Seq[String]() } } From a901fbd852ea73a6b85a26bcec47892502d4eade Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Fri, 9 Oct 2020 10:24:54 -0400 Subject: [PATCH 8/9] PR feedback --- contrib/proguard/src/Proguard.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index 6db579af3b3..8f02f8d6fea 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -46,7 +46,7 @@ trait Proguard extends ScalaModule { * 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 { + def javaHome: T[PathRef] = T.input { PathRef(Path(System.getProperty("java.home"))) } @@ -66,7 +66,7 @@ trait Proguard extends ScalaModule { * 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") + val outJar = T.dest / "out.jar" val java = javaHome().path / "bin" / "java" val cmd = os.proc( @@ -78,7 +78,7 @@ trait Proguard extends ScalaModule { "-injars", inJar().path, "-outjars", - outJar.path, + outJar, "-libraryjars", libraryJars().map(_.path).mkString(":"), entryPoint(), @@ -89,7 +89,7 @@ trait Proguard extends ScalaModule { // the call above already throws an exception on a non-zero exit code, // so if we reached this point we've succeeded! - outJar + PathRef(outJar) } /** The location of the proguard jar files. From 04ceab75c4176d57db78537932e7b61fccca823d Mon Sep 17 00:00:00 2001 From: Stephen Bly Date: Fri, 30 Oct 2020 16:34:35 -0400 Subject: [PATCH 9/9] Add some basic tests --- contrib/proguard/src/Proguard.scala | 2 +- .../test/resources/proguard/src/Main.scala | 5 ++ contrib/proguard/test/src/ProguardTests.scala | 50 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 contrib/proguard/test/resources/proguard/src/Main.scala create mode 100644 contrib/proguard/test/src/ProguardTests.scala diff --git a/contrib/proguard/src/Proguard.scala b/contrib/proguard/src/Proguard.scala index 8f02f8d6fea..4ad1ff34399 100644 --- a/contrib/proguard/src/Proguard.scala +++ b/contrib/proguard/src/Proguard.scala @@ -50,7 +50,7 @@ trait Proguard extends ScalaModule { PathRef(Path(System.getProperty("java.home"))) } - /** Specifies the input jar to proguard. Defaults to the output of the `assembly` task. */ */ + /** 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 diff --git a/contrib/proguard/test/resources/proguard/src/Main.scala b/contrib/proguard/test/resources/proguard/src/Main.scala new file mode 100644 index 00000000000..d435838289d --- /dev/null +++ b/contrib/proguard/test/resources/proguard/src/Main.scala @@ -0,0 +1,5 @@ +import java.nio.file.{Files, Paths} + +object Main extends App { + +} diff --git a/contrib/proguard/test/src/ProguardTests.scala b/contrib/proguard/test/src/ProguardTests.scala new file mode 100644 index 00000000000..2cac1096dcd --- /dev/null +++ b/contrib/proguard/test/src/ProguardTests.scala @@ -0,0 +1,50 @@ +package mill.contrib.proguard + +import mill._ +import mill.define.Sources +import mill.define.Target +import mill.scalalib.ScalaModule +import mill.util.TestEvaluator +import mill.util.TestUtil +import os.Path +import utest._ +import utest.framework.TestPath + +object ProguardTests extends TestSuite { + + object Proguard + extends TestUtil.BaseModule + with scalalib.ScalaModule + with Proguard { + // override build root to test custom builds/modules + override def millSourcePath: Path = TestUtil.getSrcPathStatic() + override def scalaVersion = "2.12.0" + } + + val testModuleSourcesPath: Path = os.pwd / 'contrib / 'proguard / 'test / 'resources / "proguard" + + def workspaceTest[T](m: TestUtil.BaseModule)(t: TestEvaluator => T)( + implicit tp: TestPath): T = { + val eval = new TestEvaluator(m) + os.remove.all(m.millSourcePath) + os.remove.all(eval.outPath) + os.makeDir.all(m.millSourcePath / os.up) + os.copy(testModuleSourcesPath, m.millSourcePath) + t(eval) + } + + def tests: Tests = Tests { + 'proguard - { + "should download proguard jars" - workspaceTest(Proguard) { eval => + val Right((agg, _)) = eval.apply(Proguard.proguardClasspath) + assert(!agg.isEmpty) + } + + "create proguarded jar" - workspaceTest(Proguard) { eval => + val Right((path, _)) = eval.apply(Proguard.proguard) + assert(os.exists(path.path)) + } + + } + } +}