Revert "Revert "Enable running tests on r8lib with dependencies""

This reverts commit 98478dceff1b57e15148eea7a7603d2f41606858.

Change-Id: I18ea656d32c162164025618b072b0f2d600b2141
diff --git a/build.gradle b/build.gradle
index 977ebd7..d2df8f8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -257,6 +257,7 @@
 def r8LibPath = "$buildDir/libs/r8lib.jar"
 def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt"
 def r8LibTestPath = "$buildDir/classes/r8libtest"
+def r8TestsJarPath = "$buildDir/libs/r8tests.jar"
 
 def osString = OperatingSystem.current().isLinux() ? "linux" :
         OperatingSystem.current().isMacOsX() ? "mac" : "windows"
@@ -565,9 +566,7 @@
     }
     from repackageSources.outputs.files
     from repackageDeps.outputs.files
-    doLast {
-        configureRelocations(it)
-    }
+    configureRelocations(it)
 }
 
 task r8WithoutDeps(type: ShadowJar) {
@@ -599,6 +598,14 @@
     }
 }
 
+task R8NoManifestNoDeps(type: ShadowJar) {
+    from consolidatedLicense.outputs.files
+    baseName 'r8nomanifest-exclude-deps'
+    classifier = null
+    version = null
+    from sourceSets.main.output
+}
+
 task R8NoManifest(type: ShadowJar) {
     from consolidatedLicense.outputs.files
     baseName 'r8nomanifest'
@@ -639,7 +646,8 @@
 }
 
 def baseR8CommandLine(args = []) {
-    return ["java", "-ea", "-jar", R8.outputs.files[0]] + args
+    // Execute r8 commands against a stable r8 with relocated dependencies.
+    return ["java", "-ea", "-jar", r8WithRelocatedDeps.outputs.files[0]] + args
 }
 
 def r8CfCommandLine(input, output, pgconf, args = [], libs = []) {
@@ -655,34 +663,42 @@
 
 def r8LibCreateTask(name, pgConf, r8Task, output, args = [], libs = []) {
     return tasks.create("r8Lib${name}", Exec) {
-        inputs.files ([pgConf, R8.outputs, r8Task.outputs])
+        inputs.files ([pgConf, r8WithRelocatedDeps.outputs, r8Task.outputs])
         outputs.file output
         dependsOn downloadOpenJDKrt
+        dependsOn r8WithRelocatedDeps
+        dependsOn r8Task
         commandLine r8CfCommandLine(r8Task.outputs.files[0], output, pgConf, args, libs)
         workingDir = projectDir
     }
 }
 
-task testJar(type: Jar, dependsOn: testClasses) {
+task testJar(type: ShadowJar, dependsOn: testClasses) {
+    outputs.upToDateWhen { false }
     baseName = "r8tests"
     from sourceSets.test.output
+    if (!project.hasProperty('exclude_deps')) {
+        relocate('com.google.common', 'com.android.tools.r8.com.google.common')
+        relocate('org.objectweb.asm', 'com.android.tools.r8.org.objectweb.asm')
+    }
 }
 
 task generateR8LibKeepRules(type: Exec) {
     doFirst {
         standardOutput new FileOutputStream(r8LibGeneratedKeepRulesPath)
     }
-    dependsOn R8
-    dependsOn r8WithoutDeps
+    def libSourceTask = project.hasProperty('exclude_deps') ? R8NoManifestNoDeps : R8NoManifest
+    dependsOn r8WithRelocatedDeps
+    dependsOn libSourceTask
     dependsOn testJar
     dependsOn downloadOpenJDKrt
-    inputs.files ([R8.outputs, r8WithoutDeps.outputs, testJar.outputs])
+    inputs.files ([r8WithRelocatedDeps.outputs, libSourceTask.outputs, testJar.outputs])
     outputs.file r8LibGeneratedKeepRulesPath
     commandLine baseR8CommandLine([
             "printuses",
             "--keeprules",
             "third_party/openjdk/openjdk-rt-1.8/rt.jar",
-            r8WithoutDeps.outputs.files[0],
+            libSourceTask.outputs.files[0],
             testJar.outputs.files[0]])
     workingDir = projectDir
 }
@@ -691,15 +707,22 @@
     dependsOn r8LibCreateTask(
             "NoDeps",
             "src/main/keep.txt",
-            r8WithoutDeps,
+            R8NoManifestNoDeps,
             r8LibPath,
             ["--pg-conf", generateR8LibKeepRules.outputs.files[0]],
             repackageDepsNoRelocate.outputs.files
-    ).dependsOn(repackageDepsNoRelocate, r8WithoutDeps, generateR8LibKeepRules)
+    ).dependsOn(repackageDepsNoRelocate, generateR8LibKeepRules)
+    outputs.file r8LibPath
 }
 
 task R8Lib {
-    dependsOn r8LibCreateTask("Main", "src/main/keep.txt", R8NoManifest, r8LibPath)
+    dependsOn r8LibCreateTask(
+            "Main",
+            "src/main/keep.txt",
+            R8NoManifest,
+            r8LibPath,
+            ["--pg-conf", generateR8LibKeepRules.outputs.files[0]]
+    ).dependsOn(generateR8LibKeepRules)
     outputs.file r8LibPath
 }
 
@@ -1385,19 +1408,15 @@
 }
 
 task configureTestForR8Lib(type: Copy) {
-    dependsOn testClasses
-    // Setting classpath triggers a scan for test files in $buildDir/classes/test that finds all
-    // tests and not just the ones under $test/com/android/tools/r8. That is generally not
-    // something we want so we just copy the desired test files to $r8LibTestPath.
-    // Note, we cannot use sourceSets.test.output here since it will copy all tests.
-    def sourcePath = "$buildDir/classes/test/com/android/tools/r8"
-    inputs.file sourcePath
+    dependsOn testJar
+    inputs.file r8TestsJarPath
     if (getR8LibTask() != null) {
         dependsOn getR8LibTask()
-        def destPath = r8LibTestPath + "/com/android/tools/r8"
-        delete destPath
-        from(sourcePath)
-        into(destPath)
+        delete r8LibTestPath
+        from zipTree(testJar.outputs.files[0])
+        into r8LibTestPath
+        include "com/android/tools/r8/**"
+        include "dalvik/**"
     }
     outputs.dir r8LibTestPath
 }
@@ -1499,7 +1518,12 @@
     }
     if (project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')) {
         dependsOn configureTestForR8Lib
-        classpath = files([r8LibPath]) + (sourceSets.test.runtimeClasspath - sourceSets.main.output)
+        // We remove build/classes/test from classpath and rely on configureTestForR8Lib to provide
+        // all needed tests in r8LibTestPath.
+        classpath = files([r8LibPath, r8LibTestPath]) +
+                sourceSets.test.runtimeClasspath -
+                sourceSets.main.output -
+                files(['build/classes/test'])
         testClassesDir = new File(r8LibTestPath)
     }
     if (OperatingSystem.current().isLinux()
diff --git a/tools/archive.py b/tools/archive.py
index 78a8189..ce04494 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -92,9 +92,10 @@
     raise Exception('You are not a bot, don\'t archive builds')
 
   # Generate an r8-ed build without dependencies.
-  # Note: build_r8lib does a gradle-clean, this must be the first command.
-  build_r8lib('r8nomanifest', True, True, utils.R8LIB_KEEP_RULES,
-    utils.R8LIB_EXCLUDE_DEPS_JAR)
+  # The '-Pno_internal' flag is important because we generate the lib based on uses in tests.
+  gradle.RunGradleExcludeDeps([utils.R8LIB_NO_DEPS, '-Pno_internal'])
+  shutil.copyfile(utils.R8LIB_JAR, utils.R8LIB_EXCLUDE_DEPS_JAR)
+  shutil.copyfile(utils.R8LIB_JAR + '.map', utils.R8LIB_EXCLUDE_DEPS_JAR + '.map')
 
   # Create maven release which uses a build that exclude dependencies.
   create_maven_release.main(["--out", utils.LIBS])
@@ -106,6 +107,7 @@
   # 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.
   gradle.RunGradle([
     utils.R8,
     utils.D8,
@@ -114,6 +116,7 @@
     utils.R8LIB,
     utils.COMPATDXLIB,
     utils.COMPATPROGUARDLIB,
+    '-Pno_internal'
   ])
   version = GetVersion()
   is_master = IsMaster(version)
diff --git a/tools/test.py b/tools/test.py
index 043487c..6b24433 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -185,6 +185,7 @@
     gradle_args.append('-Pr8lib')
   if options.r8lib_no_deps:
     gradle_args.append('-Pr8lib_no_deps')
+    gradle_args.append('-Pexclude_deps')
 
   # Add Gradle tasks
   gradle_args.append('cleanTest')
diff --git a/tools/utils.py b/tools/utils.py
index 9278459..e0ffa5c 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -30,6 +30,7 @@
 D8 = 'd8'
 R8 = 'r8'
 R8LIB = 'r8lib'
+R8LIB_NO_DEPS = 'r8LibNoDeps'
 R8_SRC = 'sourceJar'
 COMPATDX = 'compatdx'
 COMPATDXLIB = 'compatdxlib'