Generate a Maven artefact with the desugar library configuration

This also add the version to the JSON configuration format.

Test: tools/archive.py --dry-run --dry-run-output ooo
Bug: 134732760
Change-Id: Ia5060f0c91afe0e904fdbf70742c6db5cc785727
diff --git a/tools/create_maven_release.py b/tools/create_maven_release.py
index 2a66424..b4343f3 100755
--- a/tools/create_maven_release.py
+++ b/tools/create_maven_release.py
@@ -6,9 +6,10 @@
 import argparse
 import gradle
 import hashlib
+import json
 from os import makedirs
 from os.path import join
-from shutil import copyfile, make_archive, rmtree
+from shutil import copyfile, make_archive, move, rmtree
 import subprocess
 import sys
 from string import Template
@@ -31,7 +32,7 @@
       <distribution>repo</distribution>
     </license>""")
 
-POMTEMPLATE = Template(
+R8_POMTEMPLATE = Template(
 """<project
     xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -71,11 +72,56 @@
 </project>
 """)
 
+DESUGAR_CONFIGUATION_POMTEMPLATE = Template(
+"""<project
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.android.tools</groupId>
+  <artifactId>desugar_jdk_libs_configuration</artifactId>
+  <version>$version</version>
+  <name>D8 configuration to desugar desugar_jdk_libs</name>
+  <description>
+  D8 configuration to desugar desugar_jdk_libs.
+  </description>
+  <url>http://r8.googlesource.com/r8</url>
+  <inceptionYear>2019</inceptionYear>
+  <licenses>
+    <license>
+      <name>BSD-3-Clause</name>
+      <url>https://opensource.org/licenses/BSD-3-Clause</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <dependencies>
+    <groupId>com.android.tools</groupId>
+    <artifactId>desugar_jdk_libs</artifactId>
+    <version>1.0.0</version>
+  </dependencies>
+  <developers>
+    <developer>
+      <name>The Android Open Source Project</name>
+    </developer>
+  </developers>
+  <scm>
+    <connection>
+      https://r8.googlesource.com/r8.git
+    </connection>
+    <url>
+      https://r8.googlesource.com/r8
+    </url>
+  </scm>
+</project>
+""")
+
 def parse_options(argv):
   result = argparse.ArgumentParser()
   result.add_argument('--out', help='The zip file to output')
   result.add_argument('--r8lib', action='store_true',
                       help='Build r8 with dependencies included shrunken')
+  result.add_argument('--desugar-configuration', action='store_true',
+                      help='Build r8 with dependencies included shrunken')
   return result.parse_args(argv)
 
 def determine_version():
@@ -211,10 +257,8 @@
         group=group, artifact=artifact, version=version)
   return result
 
-def write_pom_file(version, pom_file, exclude_dependencies):
-  dependencies = "" if exclude_dependencies else generate_dependencies()
-  library_licenses = generate_library_licenses() if exclude_dependencies else ""
-  version_pom = POMTEMPLATE.substitute(
+def write_pom_file(template, pom_file, version, dependencies='', library_licenses=''):
+  version_pom = template.substitute(
       version=version, dependencies=dependencies, library_licenses=library_licenses)
   with open(pom_file, 'w') as file:
     file.write(version_pom)
@@ -239,40 +283,91 @@
   with (open(file + '.sha1', 'w')) as file:
     file.write(hexdigest)
 
-def run(out, is_r8lib=False):
-  if out == None:
-    print 'Need to supply output zip with --out.'
-    exit(1)
-  # Build the R8 no deps artifact.
-  if not is_r8lib:
-    gradle.RunGradleExcludeDeps([utils.R8])
-  else:
-    gradle.RunGradle([utils.R8LIB, '-Pno_internal'])
-  # Create directory structure for this version.
-  version = determine_version()
+def generate_maven_zip(name, version, pom_file, jar_file, out):
   with utils.TempDir() as tmp_dir:
-    version_dir = join(tmp_dir, utils.get_maven_path('r8', version))
+    # Create the base maven version directory
+    version_dir = join(tmp_dir, utils.get_maven_path(name, version))
     makedirs(version_dir)
     # Write the pom file.
-    pom_file = join(version_dir, 'r8-' + version + '.pom')
-    write_pom_file(version, pom_file, is_r8lib)
-    # Copy the jar to the output.
-    target_jar = join(version_dir, 'r8-' + version + '.jar')
-    copyfile(utils.R8LIB_JAR if is_r8lib else utils.R8_JAR, target_jar)
+    pom_file_location = join(version_dir, name + '-' + version + '.pom')
+    copyfile(pom_file, pom_file_location)
+    # Write the jar file.
+    jar_file_location = join(version_dir, name + '-' + version + '.jar')
+    copyfile(jar_file, jar_file_location)
     # Create check sums.
-    write_md5_for(target_jar)
-    write_md5_for(pom_file)
-    write_sha1_for(target_jar)
-    write_sha1_for(pom_file)
+    write_md5_for(jar_file_location)
+    write_md5_for(pom_file_location)
+    write_sha1_for(jar_file_location)
+    write_sha1_for(pom_file_location)
     # Zip it up - make_archive will append zip to the file, so remove.
     assert out.endswith('.zip')
     base_no_zip = out[0:len(out)-4]
     make_archive(base_no_zip, 'zip', tmp_dir)
 
+def generate_r8_maven_zip(out, is_r8lib=False):
+  # Build the R8 no deps artifact.
+  if not is_r8lib:
+    gradle.RunGradleExcludeDeps([utils.R8])
+  else:
+    gradle.RunGradle([utils.R8LIB, '-Pno_internal'])
+
+  version = determine_version()
+  # Generate the pom file.
+  pom_file = 'r8.pom'
+  write_pom_file(
+      R8_POMTEMPLATE,
+      pom_file,
+      version,
+      "" if is_r8lib else generate_dependencies(),
+      generate_library_licenses() if is_r8lib else "")
+  # Write the maven zip file.
+  generate_maven_zip(
+      'r8',
+      version,
+      pom_file,
+      utils.R8LIB_JAR if is_r8lib else utils.R8_JAR,
+      out)
+
+# Write the desugaring configuration of a jar file with the following content:
+#  META-INF
+#    desugar
+#      d8
+#        desugar.json
+def generate_jar_with_desugar_configuration(configuration, destination):
+  with utils.TempDir() as tmp_dir:
+    configuration_dir = join(tmp_dir, 'META-INF', 'desugar', 'd8')
+    makedirs(configuration_dir)
+    copyfile(configuration, join(configuration_dir, 'desugar.json'))
+    make_archive(destination, 'zip', tmp_dir)
+    move(destination + '.zip', destination)
+
+# Generate the maven zip for the configuration to desugar desugar_jdk_libs.
+def generate_desugar_configuration_maven_zip(out):
+  version = utils.desugar_configuration_version()
+  # Generate the pom file.
+  pom_file = 'desugar_configuration.pom'
+  write_pom_file(DESUGAR_CONFIGUATION_POMTEMPLATE, pom_file, version)
+  # Generate the jar with the configuration file.
+  jar_file = 'desugar_configuration.jar'
+  generate_jar_with_desugar_configuration(
+      utils.DESUGAR_CONFIGURATION, jar_file)
+  # Write the maven zip file.
+  generate_maven_zip(
+      'desugar_jdk_libs_configuration', version, pom_file, jar_file, out)
+
+
 def main(argv):
   options = parse_options(argv)
-  out = options.out
-  run(out, options.r8lib)
+  if options.r8lib and options.desugar_configuration:
+    raise Exception(
+        'Cannot combine options --r8lib and --desugar-configuration')
+  if options.out == None:
+    raise Exception(
+        'Need to supply output zip with --out.')
+  if options.desugar_configuration:
+    generate_desugar_configuration_maven_zip(options.out)
+  else:
+    generate_r8_maven_zip(options.out, options.r8lib)
 
 if __name__ == "__main__":
   exit(main(sys.argv[1:]))