Allow the output directory of the base to be set for DexSplitter

Change-Id: I720b0369813c1654b283a3ce7adeb9283b22c90c
diff --git a/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java b/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java
index 5e8d54d..b2fe1bc 100644
--- a/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java
+++ b/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java
@@ -25,6 +25,7 @@
 public class DexSplitter {
 
   private static final String DEFAULT_OUTPUT_DIR = "output";
+  private static final String DEFAULT_BASE_NAME = "base";
 
   private static final boolean PRINT_ARGS = false;
 
@@ -63,6 +64,7 @@
   public static class Options {
     private List<String> inputArchives = new ArrayList<>();
     private List<FeatureJar> featureJars = new ArrayList<>();
+    private String baseOutputName = DEFAULT_BASE_NAME;
     private String output = DEFAULT_OUTPUT_DIR;
     private String featureSplitMapping;
     private String proguardMap;
@@ -91,6 +93,14 @@
       this.proguardMap = proguardMap;
     }
 
+    public String getBaseOutputName() {
+      return baseOutputName;
+    }
+
+    public void setBaseOutputName(String baseOutputName) {
+      this.baseOutputName = baseOutputName;
+    }
+
     public void addInputArchive(String inputArchive) {
       inputArchives.add(inputArchive);
     }
@@ -159,6 +169,11 @@
         options.setProguardMap(proguardMap);
         continue;
       }
+      String baseOutputName = OptionsParsing.tryParseSingle(context, "--base-output-name", null);
+      if (baseOutputName != null) {
+        options.setBaseOutputName(baseOutputName);
+        continue;
+      }
       String featureSplit = OptionsParsing.tryParseSingle(context, "--feature-splits", null);
       if (featureSplit != null) {
         options.setFeatureSplitMapping(featureSplit);
@@ -175,7 +190,7 @@
       return FeatureClassMapping.fromSpecification(Paths.get(options.getFeatureSplitMapping()));
     }
     assert !options.getFeatureJars().isEmpty();
-    return FeatureClassMapping.fromJarFiles(options.getFeatureJars());
+    return FeatureClassMapping.fromJarFiles(options.getFeatureJars(), options.getBaseOutputName());
   }
 
   private static void run(String[] args)
diff --git a/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java b/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java
index 6893eb1..5281eac 100644
--- a/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java
+++ b/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java
@@ -43,14 +43,18 @@
   HashSet<FeaturePredicate> mappings = new HashSet<>();
 
   Path mappingFile;
+  String baseName;
+
+  static final String DEFAULT_BASE_NAME = "base";
 
   static final String COMMENT = "#";
   static final String SEPARATOR = ":";
-  static final String BASE_NAME = "base";
+
 
   public static FeatureClassMapping fromSpecification(Path file)
       throws FeatureMappingException, IOException {
     FeatureClassMapping mapping = new FeatureClassMapping();
+    mapping.baseName = DEFAULT_BASE_NAME;
     List<String> lines = FileUtils.readAllLines(file);
     for (int i = 0; i < lines.size(); i++) {
       String line = lines.get(i);
@@ -59,9 +63,10 @@
     return mapping;
   }
 
-  public static FeatureClassMapping fromJarFiles(List<FeatureJar> featureJars)
+  public static FeatureClassMapping fromJarFiles(List<FeatureJar> featureJars, String baseName)
       throws FeatureMappingException, IOException {
     FeatureClassMapping mapping = new FeatureClassMapping();
+    mapping.baseName = baseName != null ? baseName : DEFAULT_BASE_NAME;
     for (FeatureJar featureJar : featureJars) {
       Path jarPath = Paths.get(featureJar.getJar());
       ArchiveClassFileProvider provider = new ArchiveClassFileProvider(jarPath);
@@ -97,7 +102,7 @@
       }
     }
     if (bestMatch == null) {
-      return BASE_NAME;
+      return baseName;
     }
     return bestMatch.feature;
   }
diff --git a/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java b/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
index ed293f6..5bbb9d5 100644
--- a/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
+++ b/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
@@ -280,6 +280,9 @@
       options.setOutput(output.toString());
       if (explicitBase) {
         options.addFeatureJar(baseJar.toString());
+      } else {
+        // Ensure that we can rename base (if people called a feature base)
+        options.setBaseOutputName("base_renamed");
       }
       options.addFeatureJar(featureJar.toString(), specificOutputName);
       DexSplitter.run(options);
@@ -294,11 +297,15 @@
       if (explicitBase) {
         args.add("--feature-jar");
         args.add(baseJar.toString());
+      } else {
+        args.add("--base-output-name");
+        args.add("base_renamed");
       }
 
       DexSplitter.main(args.toArray(new String[0]));
     }
-    Path base = output.resolve("base").resolve("classes.dex");
+    String baseOutputName = explicitBase ? "base" : "base_renamed";
+    Path base = output.resolve(baseOutputName).resolve("classes.dex");
     Path feature = output.resolve(specificOutputName).resolve("classes.dex");;
     validateUnobfuscatedOutput(base, feature);
   }