diff --git a/tools/archive.py b/tools/archive.py
index b868296..84c0da3 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -11,10 +11,10 @@
 import gradle
 
 try:
-  import resource
+    import resource
 except ImportError:
-  # Not a Unix system. Do what Gandalf tells you not to.
-  pass
+    # Not a Unix system. Do what Gandalf tells you not to.
+    pass
 import shutil
 import subprocess
 import sys
@@ -23,319 +23,336 @@
 
 ARCHIVE_BUCKET = 'r8-releases'
 
+
 def ParseOptions():
-  result = optparse.OptionParser()
-  result.add_option('--dry-run', '--dry_run',
-      help='Build only, no upload.',
-      default=False, action='store_true')
-  result.add_option('--dry-run-output', '--dry_run_output',
-      help='Output directory for \'build only, no upload\'.',
-      type="string", action="store")
-  result.add_option('--skip-gradle-build', '--skip_gradle_build',
-      help='Skip Gradle build. Can only be used for local testing.',
-      default=False, action='store_true')
-  return result.parse_args()
+    result = optparse.OptionParser()
+    result.add_option('--dry-run',
+                      '--dry_run',
+                      help='Build only, no upload.',
+                      default=False,
+                      action='store_true')
+    result.add_option('--dry-run-output',
+                      '--dry_run_output',
+                      help='Output directory for \'build only, no upload\'.',
+                      type="string",
+                      action="store")
+    result.add_option(
+        '--skip-gradle-build',
+        '--skip_gradle_build',
+        help='Skip Gradle build. Can only be used for local testing.',
+        default=False,
+        action='store_true')
+    return result.parse_args()
+
 
 def GetVersion():
-  output = subprocess.check_output([
-      jdk.GetJavaExecutable(), '-cp', utils.R8_JAR, 'com.android.tools.r8.R8',
-      '--version'
-  ]).decode('utf-8')
-  r8_version = output.splitlines()[0].strip()
-  return r8_version.split()[1]
+    output = subprocess.check_output([
+        jdk.GetJavaExecutable(), '-cp', utils.R8_JAR, 'com.android.tools.r8.R8',
+        '--version'
+    ]).decode('utf-8')
+    r8_version = output.splitlines()[0].strip()
+    return r8_version.split()[1]
+
 
 def GetGitBranches():
-  return subprocess.check_output(['git', 'show', '-s', '--pretty=%d', 'HEAD'])
+    return subprocess.check_output(['git', 'show', '-s', '--pretty=%d', 'HEAD'])
+
 
 def GetGitHash():
-  return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('utf-8').strip()
+    return subprocess.check_output(['git', 'rev-parse',
+                                    'HEAD']).decode('utf-8').strip()
+
 
 def IsMain(version):
-  branches = subprocess.check_output(['git', 'branch', '-r', '--contains',
-                                      'HEAD']).decode('utf-8')
-  # CL runs from gerrit does not have a branch, we always treat them as main
-  # commits to archive these to the hash based location
-  if len(branches) == 0:
+    branches = subprocess.check_output(
+        ['git', 'branch', '-r', '--contains', 'HEAD']).decode('utf-8')
+    # CL runs from gerrit does not have a branch, we always treat them as main
+    # commits to archive these to the hash based location
+    if len(branches) == 0:
+        return True
+    if not version == 'main':
+        # Sanity check, we don't want to archive on top of release builds EVER
+        # Note that even though we branch, we never push the bots to build the same
+        # commit as main on a branch since we always change the version to
+        # not be just 'main' (or we crash here :-)).
+        if 'origin/main' in branches:
+            raise Exception('We are seeing origin/main in a commit that '
+                            'don\'t have \'main\' as version')
+        return False
+    if not 'origin/main' in branches:
+        raise Exception('We are not seeing origin/main '
+                        'in a commit that have \'main\' as version')
     return True
-  if not version == 'main':
-    # Sanity check, we don't want to archive on top of release builds EVER
-    # Note that even though we branch, we never push the bots to build the same
-    # commit as main on a branch since we always change the version to
-    # not be just 'main' (or we crash here :-)).
-    if 'origin/main' in branches:
-      raise Exception('We are seeing origin/main in a commit that '
-                      'don\'t have \'main\' as version')
-    return False
-  if not 'origin/main' in branches:
-      raise Exception('We are not seeing origin/main '
-                      'in a commit that have \'main\' as version')
-  return True
 
-def GetStorageDestination(storage_prefix,
-                          version_or_path,
-                          file_name,
-                          is_main):
-  # We archive main commits under raw/main instead of directly under raw
-  version_dir = GetVersionDestination(storage_prefix,
-                                      version_or_path,
-                                      is_main)
-  return '%s/%s' % (version_dir, file_name)
+
+def GetStorageDestination(storage_prefix, version_or_path, file_name, is_main):
+    # We archive main commits under raw/main instead of directly under raw
+    version_dir = GetVersionDestination(storage_prefix, version_or_path,
+                                        is_main)
+    return '%s/%s' % (version_dir, file_name)
+
 
 def GetVersionDestination(storage_prefix, version_or_path, is_main):
-  archive_dir = 'raw/main' if is_main else 'raw'
-  return '%s%s/%s/%s' % (storage_prefix, ARCHIVE_BUCKET,
-                         archive_dir, version_or_path)
+    archive_dir = 'raw/main' if is_main else 'raw'
+    return '%s%s/%s/%s' % (storage_prefix, ARCHIVE_BUCKET, archive_dir,
+                           version_or_path)
+
 
 def GetUploadDestination(version_or_path, file_name, is_main):
-  return GetStorageDestination('gs://', version_or_path, file_name, is_main)
+    return GetStorageDestination('gs://', version_or_path, file_name, is_main)
+
 
 def GetUrl(version_or_path, file_name, is_main):
-  return GetStorageDestination('https://storage.googleapis.com/',
-                               version_or_path, file_name, is_main)
+    return GetStorageDestination('https://storage.googleapis.com/',
+                                 version_or_path, file_name, is_main)
+
 
 def GetMavenUrl(is_main):
-  return GetVersionDestination('https://storage.googleapis.com/', '', is_main)
+    return GetVersionDestination('https://storage.googleapis.com/', '', is_main)
+
 
 def SetRLimitToMax():
-  (soft, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
-  resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard))
+    (soft, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
+    resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard))
+
 
 def PrintResourceInfo():
-  (soft, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
-  print('INFO: Open files soft limit: %s' % soft)
-  print('INFO: Open files hard limit: %s' % hard)
+    (soft, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
+    print('INFO: Open files soft limit: %s' % soft)
+    print('INFO: Open files hard limit: %s' % hard)
 
 
 def Main():
-  (options, args) = ParseOptions()
-  Run(options)
+    (options, args) = ParseOptions()
+    Run(options)
+
 
 def Run(options):
-  if not utils.is_bot() and not options.dry_run:
-    raise Exception('You are not a bot, don\'t archive builds. '
-      + 'Use --dry-run to test locally')
-  if (options.dry_run_output and
-      (not os.path.exists(options.dry_run_output) or
-       not os.path.isdir(options.dry_run_output))):
-    raise Exception(options.dry_run_output
-        + ' does not exist or is not a directory')
-  if (options.skip_gradle_build and not options.dry_run):
-    raise Exception('Using --skip-gradle-build only supported with --dry-run')
+    if not utils.is_bot() and not options.dry_run:
+        raise Exception('You are not a bot, don\'t archive builds. ' +
+                        'Use --dry-run to test locally')
+    if (options.dry_run_output and
+        (not os.path.exists(options.dry_run_output) or
+         not os.path.isdir(options.dry_run_output))):
+        raise Exception(options.dry_run_output +
+                        ' does not exist or is not a directory')
+    if (options.skip_gradle_build and not options.dry_run):
+        raise Exception(
+            'Using --skip-gradle-build only supported with --dry-run')
 
-  if utils.is_bot() and not utils.IsWindows():
-    SetRLimitToMax()
-  if not utils.IsWindows():
-    PrintResourceInfo()
+    if utils.is_bot() and not utils.IsWindows():
+        SetRLimitToMax()
+    if not utils.IsWindows():
+        PrintResourceInfo()
 
-  with utils.TempDir() as temp:
-    version_file = os.path.join(temp, 'r8-version.properties')
-    with open(version_file,'w') as version_writer:
-      version_writer.write('version.sha=' + GetGitHash() + '\n')
-      if not os.environ.get('SWARMING_BOT_ID') and not options.dry_run:
-        raise Exception('Environment variable SWARMING_BOT_ID not set')
+    with utils.TempDir() as temp:
+        version_file = os.path.join(temp, 'r8-version.properties')
+        with open(version_file, 'w') as version_writer:
+            version_writer.write('version.sha=' + GetGitHash() + '\n')
+            if not os.environ.get('SWARMING_BOT_ID') and not options.dry_run:
+                raise Exception('Environment variable SWARMING_BOT_ID not set')
 
-      releaser = \
-          ("<local developer build>" if options.dry_run
-            else 'releaser=go/r8bot ('
-                + (os.environ.get('SWARMING_BOT_ID') or 'foo') + ')\n')
-      version_writer.write(releaser)
-      version_writer.write('version-file.version.code=1\n')
+            releaser = \
+                ("<local developer build>" if options.dry_run
+                  else 'releaser=go/r8bot ('
+                      + (os.environ.get('SWARMING_BOT_ID') or 'foo') + ')\n')
+            version_writer.write(releaser)
+            version_writer.write('version-file.version.code=1\n')
 
-    create_maven_release.generate_r8_maven_zip(
-        utils.MAVEN_ZIP_LIB,
-        version_file=version_file,
-        skip_gradle_build=options.skip_gradle_build)
+        create_maven_release.generate_r8_maven_zip(
+            utils.MAVEN_ZIP_LIB,
+            version_file=version_file,
+            skip_gradle_build=options.skip_gradle_build)
 
-    # Ensure all archived artifacts has been built before archiving.
-    # The target tasks postfixed by 'lib' depend on the actual target task so
-    # building it invokes the original task first.
-    # The '-Pno_internal' flag is important because we generate the lib based on uses in tests.
-    if (not options.skip_gradle_build):
-      gradle.RunGradle([
-          utils.GRADLE_TASK_CONSOLIDATED_LICENSE,
-          utils.GRADLE_TASK_KEEP_ANNO_JAR,
-          utils.GRADLE_TASK_R8,
-          utils.GRADLE_TASK_R8LIB,
-          utils.GRADLE_TASK_R8LIB_NO_DEPS,
-          utils.GRADLE_TASK_RETRACE,
-          utils.GRADLE_TASK_RETRACE_NO_DEPS,
-          utils.GRADLE_TASK_SOURCE_JAR,
-          utils.GRADLE_TASK_SWISS_ARMY_KNIFE,
-          '-Pno_internal'
-      ])
+        # Ensure all archived artifacts has been built before archiving.
+        # The target tasks postfixed by 'lib' depend on the actual target task so
+        # building it invokes the original task first.
+        # The '-Pno_internal' flag is important because we generate the lib based on uses in tests.
+        if (not options.skip_gradle_build):
+            gradle.RunGradle([
+                utils.GRADLE_TASK_CONSOLIDATED_LICENSE,
+                utils.GRADLE_TASK_KEEP_ANNO_JAR, utils.GRADLE_TASK_R8,
+                utils.GRADLE_TASK_R8LIB, utils.GRADLE_TASK_R8LIB_NO_DEPS,
+                utils.GRADLE_TASK_RETRACE, utils.GRADLE_TASK_RETRACE_NO_DEPS,
+                utils.GRADLE_TASK_SOURCE_JAR,
+                utils.GRADLE_TASK_SWISS_ARMY_KNIFE, '-Pno_internal'
+            ])
 
-    # Create maven release of the desuage_jdk_libs configuration. This require
-    # an r8.jar with dependencies to have been built.
-    create_maven_release.generate_desugar_configuration_maven_zip(
-        utils.DESUGAR_CONFIGURATION_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION,
-        utils.DESUGAR_IMPLEMENTATION,
-        utils.LIBRARY_DESUGAR_CONVERSIONS_LEGACY_ZIP)
-    create_maven_release.generate_desugar_configuration_maven_zip(
-        utils.DESUGAR_CONFIGURATION_JDK11_LEGACY_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
-        utils.DESUGAR_IMPLEMENTATION_JDK11,
-        utils.LIBRARY_DESUGAR_CONVERSIONS_LEGACY_ZIP)
+        # Create maven release of the desuage_jdk_libs configuration. This require
+        # an r8.jar with dependencies to have been built.
+        create_maven_release.generate_desugar_configuration_maven_zip(
+            utils.DESUGAR_CONFIGURATION_MAVEN_ZIP, utils.DESUGAR_CONFIGURATION,
+            utils.DESUGAR_IMPLEMENTATION,
+            utils.LIBRARY_DESUGAR_CONVERSIONS_LEGACY_ZIP)
+        create_maven_release.generate_desugar_configuration_maven_zip(
+            utils.DESUGAR_CONFIGURATION_JDK11_LEGACY_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
+            utils.DESUGAR_IMPLEMENTATION_JDK11,
+            utils.LIBRARY_DESUGAR_CONVERSIONS_LEGACY_ZIP)
 
-    create_maven_release.generate_desugar_configuration_maven_zip(
-        utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL,
-        utils.DESUGAR_IMPLEMENTATION_JDK11,
-        utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
-    create_maven_release.generate_desugar_configuration_maven_zip(
-        utils.DESUGAR_CONFIGURATION_JDK11_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11,
-        utils.DESUGAR_IMPLEMENTATION_JDK11,
-        utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
-    create_maven_release.generate_desugar_configuration_maven_zip(
-        utils.DESUGAR_CONFIGURATION_JDK11_NIO_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_NIO,
-        utils.DESUGAR_IMPLEMENTATION_JDK11,
-        utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
+        create_maven_release.generate_desugar_configuration_maven_zip(
+            utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL,
+            utils.DESUGAR_IMPLEMENTATION_JDK11,
+            utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
+        create_maven_release.generate_desugar_configuration_maven_zip(
+            utils.DESUGAR_CONFIGURATION_JDK11_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11,
+            utils.DESUGAR_IMPLEMENTATION_JDK11,
+            utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
+        create_maven_release.generate_desugar_configuration_maven_zip(
+            utils.DESUGAR_CONFIGURATION_JDK11_NIO_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_NIO,
+            utils.DESUGAR_IMPLEMENTATION_JDK11,
+            utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
 
-    version = GetVersion()
-    is_main = IsMain(version)
-    if is_main:
-      # On main we use the git hash to archive with
-      print('On main, using git hash for archiving')
-      version = GetGitHash()
+        version = GetVersion()
+        is_main = IsMain(version)
+        if is_main:
+            # On main we use the git hash to archive with
+            print('On main, using git hash for archiving')
+            version = GetGitHash()
 
-    destination = GetVersionDestination('gs://', version, is_main)
-    if utils.cloud_storage_exists(destination) and not options.dry_run:
-      raise Exception('Target archive directory %s already exists' % destination)
+        destination = GetVersionDestination('gs://', version, is_main)
+        if utils.cloud_storage_exists(destination) and not options.dry_run:
+            raise Exception('Target archive directory %s already exists' %
+                            destination)
 
-    # Create pom file for our maven repository that we build for testing.
-    default_pom_file = os.path.join(temp, 'r8.pom')
-    create_maven_release.write_default_r8_pom_file(default_pom_file, version)
-    for_archiving = [
-        utils.R8_JAR,
-        utils.R8LIB_JAR,
-        utils.R8LIB_JAR + '.map',
-        utils.R8LIB_JAR + '_map.zip',
-        utils.R8_FULL_EXCLUDE_DEPS_JAR,
-        utils.R8LIB_EXCLUDE_DEPS_JAR,
-        utils.R8LIB_EXCLUDE_DEPS_JAR + '.map',
-        utils.R8LIB_EXCLUDE_DEPS_JAR + '_map.zip',
-        utils.MAVEN_ZIP_LIB,
-        utils.DESUGAR_CONFIGURATION,
-        utils.DESUGAR_CONFIGURATION_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
-        utils.DESUGAR_CONFIGURATION_JDK11_LEGACY_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_MAVEN_ZIP,
-        utils.DESUGAR_CONFIGURATION_JDK11_NIO_MAVEN_ZIP,
-        utils.R8_SRC_JAR,
-        utils.R8RETRACE_JAR,
-        utils.R8RETRACE_JAR + '.map',
-        utils.R8RETRACE_JAR + '_map.zip',
-        utils.R8RETRACE_EXCLUDE_DEPS_JAR,
-        utils.R8RETRACE_EXCLUDE_DEPS_JAR + '.map',
-        utils.R8RETRACE_EXCLUDE_DEPS_JAR + '_map.zip',
-        utils.KEEPANNO_ANNOTATIONS_JAR,
-        utils.GENERATED_LICENSE]
-    for file in for_archiving:
-      file_name = os.path.basename(file)
-      tagged_jar = os.path.join(temp, file_name)
-      shutil.copyfile(file, tagged_jar)
-      if file_name.endswith('.jar') and not file_name.endswith('-src.jar'):
-        with zipfile.ZipFile(tagged_jar, 'a') as zip:
-          zip.write(version_file, os.path.basename(version_file))
-      destination = GetUploadDestination(version, file_name, is_main)
-      print('Uploading %s to %s' % (tagged_jar, destination))
-      if options.dry_run:
-        if options.dry_run_output:
-          dry_run_destination = os.path.join(options.dry_run_output, file_name)
-          print('Dry run, not actually uploading. Copying to '
-              + dry_run_destination)
-          shutil.copyfile(tagged_jar, dry_run_destination)
-        else:
-          print('Dry run, not actually uploading')
-      else:
-        utils.upload_file_to_cloud_storage(tagged_jar, destination)
-        print('File available at: %s' % GetUrl(version, file_name, is_main))
+        # Create pom file for our maven repository that we build for testing.
+        default_pom_file = os.path.join(temp, 'r8.pom')
+        create_maven_release.write_default_r8_pom_file(default_pom_file,
+                                                       version)
+        for_archiving = [
+            utils.R8_JAR, utils.R8LIB_JAR, utils.R8LIB_JAR + '.map',
+            utils.R8LIB_JAR + '_map.zip', utils.R8_FULL_EXCLUDE_DEPS_JAR,
+            utils.R8LIB_EXCLUDE_DEPS_JAR, utils.R8LIB_EXCLUDE_DEPS_JAR + '.map',
+            utils.R8LIB_EXCLUDE_DEPS_JAR + '_map.zip', utils.MAVEN_ZIP_LIB,
+            utils.DESUGAR_CONFIGURATION, utils.DESUGAR_CONFIGURATION_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
+            utils.DESUGAR_CONFIGURATION_JDK11_LEGACY_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_MAVEN_ZIP,
+            utils.DESUGAR_CONFIGURATION_JDK11_NIO_MAVEN_ZIP, utils.R8_SRC_JAR,
+            utils.R8RETRACE_JAR, utils.R8RETRACE_JAR + '.map',
+            utils.R8RETRACE_JAR + '_map.zip', utils.R8RETRACE_EXCLUDE_DEPS_JAR,
+            utils.R8RETRACE_EXCLUDE_DEPS_JAR + '.map',
+            utils.R8RETRACE_EXCLUDE_DEPS_JAR + '_map.zip',
+            utils.KEEPANNO_ANNOTATIONS_JAR, utils.GENERATED_LICENSE
+        ]
+        for file in for_archiving:
+            file_name = os.path.basename(file)
+            tagged_jar = os.path.join(temp, file_name)
+            shutil.copyfile(file, tagged_jar)
+            if file_name.endswith(
+                    '.jar') and not file_name.endswith('-src.jar'):
+                with zipfile.ZipFile(tagged_jar, 'a') as zip:
+                    zip.write(version_file, os.path.basename(version_file))
+            destination = GetUploadDestination(version, file_name, is_main)
+            print('Uploading %s to %s' % (tagged_jar, destination))
+            if options.dry_run:
+                if options.dry_run_output:
+                    dry_run_destination = os.path.join(options.dry_run_output,
+                                                       file_name)
+                    print('Dry run, not actually uploading. Copying to ' +
+                          dry_run_destination)
+                    shutil.copyfile(tagged_jar, dry_run_destination)
+                else:
+                    print('Dry run, not actually uploading')
+            else:
+                utils.upload_file_to_cloud_storage(tagged_jar, destination)
+                print('File available at: %s' %
+                      GetUrl(version, file_name, is_main))
 
-      # Upload R8 to a maven compatible location.
-      if file == utils.R8_JAR:
-        maven_dst = GetUploadDestination(utils.get_maven_path('r8', version),
-                                         'r8-%s.jar' % version, is_main)
-        maven_pom_dst = GetUploadDestination(
-            utils.get_maven_path('r8', version),
-            'r8-%s.pom' % version, is_main)
-        if options.dry_run:
-          print('Dry run, not actually creating maven repo for R8')
-        else:
-          utils.upload_file_to_cloud_storage(tagged_jar, maven_dst)
-          utils.upload_file_to_cloud_storage(default_pom_file, maven_pom_dst)
-          print('Maven repo root available at: %s' % GetMavenUrl(is_main))
+            # Upload R8 to a maven compatible location.
+            if file == utils.R8_JAR:
+                maven_dst = GetUploadDestination(
+                    utils.get_maven_path('r8', version), 'r8-%s.jar' % version,
+                    is_main)
+                maven_pom_dst = GetUploadDestination(
+                    utils.get_maven_path('r8', version), 'r8-%s.pom' % version,
+                    is_main)
+                if options.dry_run:
+                    print('Dry run, not actually creating maven repo for R8')
+                else:
+                    utils.upload_file_to_cloud_storage(tagged_jar, maven_dst)
+                    utils.upload_file_to_cloud_storage(default_pom_file,
+                                                       maven_pom_dst)
+                    print('Maven repo root available at: %s' %
+                          GetMavenUrl(is_main))
 
-      # Upload desugar_jdk_libs configuration to a maven compatible location.
-      if file == utils.DESUGAR_CONFIGURATION:
-        jar_basename = 'desugar_jdk_libs_configuration.jar'
-        jar_version_name = 'desugar_jdk_libs_configuration-%s.jar' % version
-        maven_dst = GetUploadDestination(
-            utils.get_maven_path('desugar_jdk_libs_configuration', version),
-                                 jar_version_name, is_main)
+            # Upload desugar_jdk_libs configuration to a maven compatible location.
+            if file == utils.DESUGAR_CONFIGURATION:
+                jar_basename = 'desugar_jdk_libs_configuration.jar'
+                jar_version_name = 'desugar_jdk_libs_configuration-%s.jar' % version
+                maven_dst = GetUploadDestination(
+                    utils.get_maven_path('desugar_jdk_libs_configuration',
+                                         version), jar_version_name, is_main)
 
-        with utils.TempDir() as tmp_dir:
-          desugar_jdk_libs_configuration_jar = os.path.join(tmp_dir,
-                                                            jar_version_name)
-          create_maven_release.generate_jar_with_desugar_configuration(
-              utils.DESUGAR_CONFIGURATION,
-              utils.DESUGAR_IMPLEMENTATION,
-              utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP,
-              desugar_jdk_libs_configuration_jar)
+                with utils.TempDir() as tmp_dir:
+                    desugar_jdk_libs_configuration_jar = os.path.join(
+                        tmp_dir, jar_version_name)
+                    create_maven_release.generate_jar_with_desugar_configuration(
+                        utils.DESUGAR_CONFIGURATION,
+                        utils.DESUGAR_IMPLEMENTATION,
+                        utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP,
+                        desugar_jdk_libs_configuration_jar)
 
-          if options.dry_run:
-            print('Dry run, not actually creating maven repo for '
-                + 'desugar configuration.')
-            if options.dry_run_output:
-              shutil.copyfile(
-                  desugar_jdk_libs_configuration_jar,
-                  os.path.join(options.dry_run_output, jar_version_name))
-          else:
-            utils.upload_file_to_cloud_storage(
-                desugar_jdk_libs_configuration_jar, maven_dst)
-            print('Maven repo root available at: %s' % GetMavenUrl(is_main))
-            # Also archive the jar as non maven destination for Google3
-            jar_destination = GetUploadDestination(
-                version, jar_basename, is_main)
-            utils.upload_file_to_cloud_storage(
-                desugar_jdk_libs_configuration_jar, jar_destination)
+                    if options.dry_run:
+                        print('Dry run, not actually creating maven repo for ' +
+                              'desugar configuration.')
+                        if options.dry_run_output:
+                            shutil.copyfile(
+                                desugar_jdk_libs_configuration_jar,
+                                os.path.join(options.dry_run_output,
+                                             jar_version_name))
+                    else:
+                        utils.upload_file_to_cloud_storage(
+                            desugar_jdk_libs_configuration_jar, maven_dst)
+                        print('Maven repo root available at: %s' %
+                              GetMavenUrl(is_main))
+                        # Also archive the jar as non maven destination for Google3
+                        jar_destination = GetUploadDestination(
+                            version, jar_basename, is_main)
+                        utils.upload_file_to_cloud_storage(
+                            desugar_jdk_libs_configuration_jar, jar_destination)
 
-      # TODO(b/237636871): Refactor this to avoid the duplication of what is above.
-      # Upload desugar_jdk_libs JDK-11 legacyconfiguration to a maven compatible location.
-      if file == utils.DESUGAR_CONFIGURATION_JDK11_LEGACY:
-        jar_basename = 'desugar_jdk_libs_configuration.jar'
-        jar_version_name = 'desugar_jdk_libs_configuration-%s-jdk11-legacy.jar' % version
-        maven_dst = GetUploadDestination(
-            utils.get_maven_path('desugar_jdk_libs_configuration', version),
-            jar_version_name, is_main)
+            # TODO(b/237636871): Refactor this to avoid the duplication of what is above.
+            # Upload desugar_jdk_libs JDK-11 legacyconfiguration to a maven compatible location.
+            if file == utils.DESUGAR_CONFIGURATION_JDK11_LEGACY:
+                jar_basename = 'desugar_jdk_libs_configuration.jar'
+                jar_version_name = 'desugar_jdk_libs_configuration-%s-jdk11-legacy.jar' % version
+                maven_dst = GetUploadDestination(
+                    utils.get_maven_path('desugar_jdk_libs_configuration',
+                                         version), jar_version_name, is_main)
 
-        with utils.TempDir() as tmp_dir:
-          desugar_jdk_libs_configuration_jar = os.path.join(tmp_dir,
-                                                            jar_version_name)
-          create_maven_release.generate_jar_with_desugar_configuration(
-              utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
-              utils.DESUGAR_IMPLEMENTATION_JDK11,
-              utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP,
-              desugar_jdk_libs_configuration_jar)
+                with utils.TempDir() as tmp_dir:
+                    desugar_jdk_libs_configuration_jar = os.path.join(
+                        tmp_dir, jar_version_name)
+                    create_maven_release.generate_jar_with_desugar_configuration(
+                        utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
+                        utils.DESUGAR_IMPLEMENTATION_JDK11,
+                        utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP,
+                        desugar_jdk_libs_configuration_jar)
 
-          if options.dry_run:
-            print('Dry run, not actually creating maven repo for '
-                + 'desugar configuration.')
-            if options.dry_run_output:
-              shutil.copyfile(
-                  desugar_jdk_libs_configuration_jar,
-                  os.path.join(options.dry_run_output, jar_version_name))
-          else:
-            utils.upload_file_to_cloud_storage(
-                desugar_jdk_libs_configuration_jar, maven_dst)
-            print('Maven repo root available at: %s' % GetMavenUrl(is_main))
-            # Also archive the jar as non maven destination for Google3
-            jar_destination = GetUploadDestination(
-                version, jar_basename, is_main)
-            utils.upload_file_to_cloud_storage(
-                desugar_jdk_libs_configuration_jar, jar_destination)
+                    if options.dry_run:
+                        print('Dry run, not actually creating maven repo for ' +
+                              'desugar configuration.')
+                        if options.dry_run_output:
+                            shutil.copyfile(
+                                desugar_jdk_libs_configuration_jar,
+                                os.path.join(options.dry_run_output,
+                                             jar_version_name))
+                    else:
+                        utils.upload_file_to_cloud_storage(
+                            desugar_jdk_libs_configuration_jar, maven_dst)
+                        print('Maven repo root available at: %s' %
+                              GetMavenUrl(is_main))
+                        # Also archive the jar as non maven destination for Google3
+                        jar_destination = GetUploadDestination(
+                            version, jar_basename, is_main)
+                        utils.upload_file_to_cloud_storage(
+                            desugar_jdk_libs_configuration_jar, jar_destination)
+
 
 if __name__ == '__main__':
-  sys.exit(Main())
+    sys.exit(Main())
