Proguard config as files in L8

Change-Id: Icff1b0db5aacf36490f4cbd73d1a2d041887275b
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index d1a8e6a..1373928 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.StringDiagnostic;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -150,7 +151,8 @@
   @Keep
   public static class Builder extends BaseCompilerCommand.Builder<L8Command, Builder> {
 
-    private final List<Pair<List<String>, Origin>> proguardConfigs = new ArrayList<>();
+    private final List<Pair<List<String>, Origin>> proguardConfigStrings = new ArrayList<>();
+    private final List<Path> proguardConfigFiles = new ArrayList<>();
 
     private Builder() {
       this(new DefaultL8DiagnosticsHandler());
@@ -162,7 +164,7 @@
 
     public boolean isShrinking() {
       // Answers true if keep rules, even empty, are provided.
-      return !proguardConfigs.isEmpty();
+      return !proguardConfigStrings.isEmpty() || !proguardConfigFiles.isEmpty();
     }
 
     @Override
@@ -175,10 +177,22 @@
       return CompilationMode.DEBUG;
     }
 
+    /** Add proguard configuration-file resources. */
+    public Builder addProguardConfigurationFiles(Path... paths) {
+      Collections.addAll(proguardConfigFiles, paths);
+      return self();
+    }
+
+    /** Add proguard configuration-file resources. */
+    public Builder addProguardConfigurationFiles(List<Path> paths) {
+      proguardConfigFiles.addAll(paths);
+      return self();
+    }
+
     /** Add proguard configuration. */
     public Builder addProguardConfiguration(List<String> lines, Origin origin) {
-      proguardConfigs.add(new Pair<>(lines, origin));
-      return this;
+      proguardConfigStrings.add(new Pair<>(lines, origin));
+      return self();
     }
 
     @Override
@@ -238,9 +252,10 @@
             inputs.getLibraryResourceProviders()) {
           r8Builder.addLibraryResourceProvider(libraryResourceProvider);
         }
-        for (Pair<List<String>, Origin> proguardConfig : proguardConfigs) {
+        for (Pair<List<String>, Origin> proguardConfig : proguardConfigStrings) {
           r8Builder.addProguardConfiguration(proguardConfig.getFirst(), proguardConfig.getSecond());
         }
+        r8Builder.addProguardConfigurationFiles(proguardConfigFiles);
         r8Command = r8Builder.makeCommand();
       } else {
         D8Command.Builder d8Builder =
diff --git a/src/test/java/com/android/tools/r8/L8CommandTest.java b/src/test/java/com/android/tools/r8/L8CommandTest.java
index 525a9ec..d13ef12 100644
--- a/src/test/java/com/android/tools/r8/L8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/L8CommandTest.java
@@ -8,9 +8,15 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -117,4 +123,46 @@
                     StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
                 .build());
   }
+
+  @Test
+  public void addProguardConfigurationString() throws Throwable {
+    String keepRule = "-keep class java.time.*";
+    List<String> keepRules = new ArrayList<>();
+    keepRules.add(keepRule);
+    L8Command.Builder builder =
+        prepareBuilder(new TestDiagnosticMessagesImpl())
+            .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+            .addDesugaredLibraryConfiguration(
+                StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+            .addProguardConfiguration(keepRules, Origin.unknown());
+    assertTrue(builder.isShrinking());
+    assertNotNull(builder.build().getR8Command());
+  }
+
+  @Test
+  public void addProguardConfigurationFile() throws Throwable {
+    String keepRule = "-keep class java.time.*";
+    Path keepRuleFile = temp.newFile("keepRuleFile.txt").toPath();
+    Files.write(keepRuleFile, Collections.singletonList(keepRule), StandardCharsets.UTF_8);
+
+    L8Command.Builder builder1 =
+        prepareBuilder(new TestDiagnosticMessagesImpl())
+            .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+            .addDesugaredLibraryConfiguration(
+                StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+            .addProguardConfigurationFiles(keepRuleFile);
+    assertTrue(builder1.isShrinking());
+    assertNotNull(builder1.build().getR8Command());
+
+    List<Path> keepRuleFiles = new ArrayList<>();
+    keepRuleFiles.add(keepRuleFile);
+    L8Command.Builder builder2 =
+        prepareBuilder(new TestDiagnosticMessagesImpl())
+            .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+            .addDesugaredLibraryConfiguration(
+                StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+            .addProguardConfigurationFiles(keepRuleFiles);
+    assertTrue(builder2.isShrinking());
+    assertNotNull(builder2.build().getR8Command());
+  }
 }