aboutsummaryrefslogtreecommitdiff
path: root/plugins/proguard/build
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/proguard/build')
-rw-r--r--plugins/proguard/build/build.scala129
-rw-r--r--plugins/proguard/build/build/build.scala13
2 files changed, 142 insertions, 0 deletions
diff --git a/plugins/proguard/build/build.scala b/plugins/proguard/build/build.scala
new file mode 100644
index 0000000..5edd7a8
--- /dev/null
+++ b/plugins/proguard/build/build.scala
@@ -0,0 +1,129 @@
+package cbt_build.proguard
+import cbt._
+import java.nio.file.Files._
+import java.net._
+import java.io._
+import scala.xml._
+class Build(val context: Context) extends Plugin with Scalafmt{
+ override def dependencies = (
+ super.dependencies ++ // don't forget super.dependencies here for scala-library, etc.
+ Resolver( mavenCentral ).bind(
+ MavenDependency("net.sf.proguard","proguard-base","5.3.2")
+ ) :+ libraries.captureArgs
+ )
+
+ def refcard = projectDirectory / "spec/refcard.html"
+
+ /** downloads html proguard parameter specification */
+ def updateSpec = {
+ System.err.println(lib.blue("downloading ")+refcard)
+ lib.download(
+ new URL("https://www.guardsquare.com/en/proguard/manual/refcard"),
+ refcard,
+ None,
+ replace = true
+ )
+ System.err.println("simplifying html")
+ val tables = (
+ loadSloppyHtml( new String( readAllBytes( refcard.toPath ) ) ) \ "body" \\ "table"
+ )
+ val s = (
+ "<html><body>\n" ++ tables.map( table =>
+ " <table>\n" ++ (table \\ "tr").map( tr =>
+ " <tr>\n" ++ (tr \\ "td").map( td =>
+ " <td>" ++ td.text ++ "</td>\n"
+ ).mkString ++ " </tr>\n"
+ ).mkString ++ " </table>\n"
+ ).mkString ++ "</body></html>\n"
+ )
+ System.err.println("writing file")
+ write( refcard.toPath, s.getBytes)
+ }
+
+ private def loadSloppyHtml(html: String): scala.xml.Elem = {
+ object XmlNotDownloadingDTD extends scala.xml.factory.XMLLoader[scala.xml.Elem] {
+ override def parser: javax.xml.parsers.SAXParser = {
+ val f = javax.xml.parsers.SAXParserFactory.newInstance()
+ f.setNamespaceAware(false)
+ f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ f.newSAXParser()
+ }
+ }
+
+ val p = new org.ccil.cowan.tagsoup.Parser
+ val w = new StringWriter
+ p.setContentHandler(new org.ccil.cowan.tagsoup.XMLWriter(w))
+ p.parse(
+ new org.xml.sax.InputSource(
+ new ByteArrayInputStream( "<!DOCTYPE[^<]*>".r.replaceFirstIn( html, "" ).getBytes )
+ )
+ )
+ XmlNotDownloadingDTD.loadString( w.toString )
+ }
+
+ /** generates Scala code from parameter specification html */
+ def generate = {
+ val tables = XML.loadFile(refcard) \\ "table"
+ def cellsToSeq( node: Node ) = (node \\ "tr").map(
+ tr => (tr \\ "td").map( td => td.text ) match {
+ case Seq( k, v ) => k -> v
+ }
+ )
+ val options = cellsToSeq( tables(0) ).collect{
+ case (k, v) if k.startsWith("-") => k.drop(1).split(" ").toList -> v
+ }.map{
+ case (k,description) =>
+ val name = k(0)
+ val tpe = k.drop(1).mkString(" ") match {
+ case "" => "Boolean"
+ case "n" => "Int"
+ case "class_specification" | "version" | "optimization_filter" => "String"
+ case "filename" | "directoryname" => "File"
+ case "class_path" if name === "outjars" => "Seq[File]"
+ case "class_path" => "ClassPath"
+ case "[filename]" => "Option[File]"
+ case "[directory_filter]" | "[package_filter]" | "[package_name]"
+ | "[attribute_filter]" | "[string]" | "[class_filter]" | "[file_filter]"
+ => "Option[String]"
+ case "[,modifier,...] class_specification" => "(Seq[KeepOptionModifier], String)"
+ }
+ (name, tpe, description.split("\n").mkString(" "))
+ }.sortBy(_._1)
+
+ val docs = options.map{
+ case (name, tpe, description) => s" @param $name $description"
+ }.mkString("\n")
+
+ val args = options.map{
+ case v@(_, "Boolean", _) => v -> Some("false")
+ case v@("injars" | "libraryjars" | "keep" | "outjars", _, _) => v -> None
+ case (n, t, d) => (n, s"Option[$t]", d) -> Some("None")
+ }.map{
+ case ((name, tpe, description), default) => s" $name: $tpe" ++ default.map(" = "++_).getOrElse("")
+ }.mkString(",\n")
+
+ val keepModifiers = cellsToSeq( tables(2) ).map{
+ case (k, v) => s""" /** $v */\n object $k extends KeepOptionModifier("$k")"""
+ }.mkString("\n")
+
+ val template = new String(
+ readAllBytes(
+ (projectDirectory / "templates/Proguard.scala").toPath
+ )
+ )
+ val code = (
+ "/* automatically generated by build/build.scala from templates/Proguard.scala */\n" ++
+ template
+ .replace ("/* ${generated-top-level} */", keepModifiers )
+ .replace( "${generated-docs}", docs )
+ .replace( "/* ${generated-args} */", args )
+ )
+
+ val targetFile = projectDirectory / "src/generated/Proguard.scala"
+ targetFile.getParentFile.mkdirs
+ write( targetFile.toPath, code.getBytes )
+
+ scalafmt
+ compile
+ }
+}
diff --git a/plugins/proguard/build/build/build.scala b/plugins/proguard/build/build/build.scala
new file mode 100644
index 0000000..7928cfa
--- /dev/null
+++ b/plugins/proguard/build/build/build.scala
@@ -0,0 +1,13 @@
+package cbt_build.proguard.build
+import cbt._
+class Build(val context: Context) extends BuildBuild{
+ override def dependencies = (
+ super.dependencies ++ // don't forget super.dependencies here for scala-library, etc.
+ Resolver( mavenCentral, sonatypeReleases ).bind(
+ ScalaDependency("org.scala-lang.modules","scala-xml","1.0.5"),
+ "org.ccil.cowan.tagsoup" % "tagsoup" % "1.2.1"
+ ) ++ Seq(
+ plugins.scalafmt
+ )
+ )
+}