aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Roussel <yroussel@google.com>2017-07-05 12:10:21 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-07-05 12:10:21 +0000
commit37059f3f14f3920359dc0c7a5133a338988c966e (patch)
treeb8b67bc9ea12cc9d69735b59730a6386641cf1b5
parentac25c3d3e8f287fe118e5b98d9ca012881df67ef (diff)
parent78be58456a12d4a51ad5fb0c19c292c01746f97b (diff)
downloadr8-37059f3f14f3920359dc0c7a5133a338988c966e.tar.gz
Merge "Allow overwriting zip output file in D8 and R8"
-rw-r--r--src/main/java/com/android/tools/r8/BaseCommand.java28
-rw-r--r--src/main/java/com/android/tools/r8/D8Command.java10
-rw-r--r--src/main/java/com/android/tools/r8/DexSegments.java9
-rw-r--r--src/main/java/com/android/tools/r8/Disassemble.java9
-rw-r--r--src/main/java/com/android/tools/r8/R8Command.java9
-rw-r--r--src/main/java/com/android/tools/r8/utils/FileUtils.java4
-rw-r--r--src/test/java/com/android/tools/r8/ToolHelper.java6
-rw-r--r--src/test/java/com/android/tools/r8/utils/D8CommandTest.java11
-rw-r--r--src/test/java/com/android/tools/r8/utils/R8CommandTest.java9
9 files changed, 71 insertions, 24 deletions
diff --git a/src/main/java/com/android/tools/r8/BaseCommand.java b/src/main/java/com/android/tools/r8/BaseCommand.java
index 85c430a44..aa0e39659 100644
--- a/src/main/java/com/android/tools/r8/BaseCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCommand.java
@@ -22,6 +22,7 @@ abstract class BaseCommand {
private final OutputMode outputMode;
private final CompilationMode mode;
private final int minApiLevel;
+ private final boolean overwriteOutputs;
BaseCommand(boolean printHelp, boolean printVersion) {
this.printHelp = printHelp;
@@ -32,10 +33,11 @@ abstract class BaseCommand {
this.outputMode = OutputMode.Indexed;
this.mode = null;
this.minApiLevel = 0;
+ this.overwriteOutputs = true;
}
BaseCommand(AndroidApp app, Path outputPath,
- OutputMode outputMode, CompilationMode mode, int minApiLevel) {
+ OutputMode outputMode, CompilationMode mode, int minApiLevel, boolean overwriteOutputs) {
assert app != null;
assert mode != null;
assert minApiLevel > 0;
@@ -44,6 +46,7 @@ abstract class BaseCommand {
this.outputMode = outputMode;
this.mode = mode;
this.minApiLevel = minApiLevel;
+ this.overwriteOutputs = overwriteOutputs;
// Print options are not set.
printHelp = false;
printVersion = false;
@@ -81,6 +84,10 @@ abstract class BaseCommand {
return outputMode;
}
+ public boolean isOverwriteOutputs() {
+ return overwriteOutputs;
+ }
+
abstract static class Builder<C extends BaseCommand, B extends Builder<C, B>> {
private boolean printHelp = false;
@@ -90,6 +97,7 @@ abstract class BaseCommand {
private OutputMode outputMode = OutputMode.Indexed;
private CompilationMode mode;
private int minApiLevel = Constants.DEFAULT_ANDROID_API;
+ private boolean overwriteOutputs = true;
protected Builder(CompilationMode mode) {
this(AndroidApp.builder(), mode);
@@ -197,9 +205,9 @@ abstract class BaseCommand {
return outputMode;
}
- /** Set an output path. Must be an existing directory or a non-existent zip file. */
- public B setOutputPath(Path outputPath) throws CompilationException {
- this.outputPath = FileUtils.validateOutputFile(outputPath);
+ /** Set an output path. Must be an existing directory or a zip file. */
+ public B setOutputPath(Path outputPath) {
+ this.outputPath = outputPath;
return self();
}
@@ -248,5 +256,17 @@ abstract class BaseCommand {
this.printVersion = printVersion;
return self();
}
+
+ protected boolean isOverwriteOutputs() {
+ return overwriteOutputs;
+ }
+
+ protected void setOverwriteOutputs(boolean overwriteOutputs) {
+ this.overwriteOutputs = overwriteOutputs;
+ }
+
+ protected void validate() throws CompilationException {
+ FileUtils.validateOutputFile(outputPath, overwriteOutputs);
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 62cb5a57d..0ef972889 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -101,8 +101,10 @@ public class D8Command extends BaseCommand {
if (isPrintHelp() || isPrintVersion()) {
return new D8Command(isPrintHelp(), isPrintVersion());
}
+
+ validate();
return new D8Command(getAppBuilder().build(),
- getOutputPath(), getOutputMode(), getMode(), getMinApiLevel());
+ getOutputPath(), getOutputMode(), getMode(), getMinApiLevel(), isOverwriteOutputs());
}
}
@@ -180,8 +182,8 @@ public class D8Command extends BaseCommand {
}
private D8Command(AndroidApp inputApp, Path outputPath,
- OutputMode outputMode, CompilationMode mode, int minApiLevel) {
- super(inputApp, outputPath, outputMode, mode, minApiLevel);
+ OutputMode outputMode, CompilationMode mode, int minApiLevel, boolean overwriteOutputs) {
+ super(inputApp, outputPath, outputMode, mode, minApiLevel, overwriteOutputs);
}
private D8Command(boolean printHelp, boolean printVersion) {
@@ -194,7 +196,7 @@ public class D8Command extends BaseCommand {
assert !internal.debug;
internal.debug = getMode() == CompilationMode.DEBUG;
internal.minApiLevel = getMinApiLevel();
- internal.overwriteOutputs = true;
+ internal.overwriteOutputs = isOverwriteOutputs();
// Assert and fixup defaults.
assert !internal.skipMinification;
internal.skipMinification = true;
diff --git a/src/main/java/com/android/tools/r8/DexSegments.java b/src/main/java/com/android/tools/r8/DexSegments.java
index 501fecc16..09eb21e50 100644
--- a/src/main/java/com/android/tools/r8/DexSegments.java
+++ b/src/main/java/com/android/tools/r8/DexSegments.java
@@ -41,12 +41,14 @@ public class DexSegments {
if (isPrintHelp()) {
return new Command(isPrintHelp());
}
+ validate();
return new Command(
getAppBuilder().build(),
getOutputPath(),
getOutputMode(),
getMode(),
- getMinApiLevel());
+ getMinApiLevel(),
+ isOverwriteOutputs());
}
}
@@ -89,8 +91,9 @@ public class DexSegments {
Path outputPath,
OutputMode outputMode,
CompilationMode mode,
- int minApiLevel) {
- super(inputApp, outputPath, outputMode, mode, minApiLevel);
+ int minApiLevel,
+ boolean isOverwrite) {
+ super(inputApp, outputPath, outputMode, mode, minApiLevel, isOverwrite);
}
private Command(boolean printHelp) {
diff --git a/src/main/java/com/android/tools/r8/Disassemble.java b/src/main/java/com/android/tools/r8/Disassemble.java
index b183ecc17..7d7389533 100644
--- a/src/main/java/com/android/tools/r8/Disassemble.java
+++ b/src/main/java/com/android/tools/r8/Disassemble.java
@@ -46,13 +46,15 @@ public class Disassemble {
return new DisassembleCommand(isPrintHelp(), isPrintVersion());
}
+ validate();
return new DisassembleCommand(
getAppBuilder().build(),
getOutputPath(),
getOutputMode(),
getMode(),
getMinApiLevel(),
- useSmali);
+ useSmali,
+ isOverwriteOutputs());
}
}
@@ -108,8 +110,9 @@ public class Disassemble {
OutputMode outputMode,
CompilationMode mode,
int minApiLevel,
- boolean useSmali) {
- super(inputApp, outputPath, outputMode, mode, minApiLevel);
+ boolean useSmali,
+ boolean isOverwrite) {
+ super(inputApp, outputPath, outputMode, mode, minApiLevel, isOverwrite);
//assert getOutputMode() == OutputMode.Indexed : "Only regular mode is supported in R8";
this.useSmali = useSmali;
}
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 7d0146290..7fd1c6f72 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -136,6 +136,7 @@ public class R8Command extends BaseCommand {
return new R8Command(isPrintHelp(), isPrintVersion());
}
+ validate();
DexItemFactory factory = new DexItemFactory();
ImmutableList<ProguardConfigurationRule> mainDexKeepRules;
if (this.mainDexRules.isEmpty()) {
@@ -178,7 +179,8 @@ public class R8Command extends BaseCommand {
getMinApiLevel(),
useTreeShaking,
useMinification,
- ignoreMissingClasses);
+ ignoreMissingClasses,
+ isOverwriteOutputs());
}
}
@@ -321,8 +323,9 @@ public class R8Command extends BaseCommand {
int minApiLevel,
boolean useTreeShaking,
boolean useMinification,
- boolean ignoreMissingClasses) {
- super(inputApp, outputPath, outputMode, mode, minApiLevel);
+ boolean ignoreMissingClasses,
+ boolean overwriteOutputs) {
+ super(inputApp, outputPath, outputMode, mode, minApiLevel, overwriteOutputs);
assert proguardConfiguration != null;
assert mainDexKeepRules != null;
assert getOutputMode() == OutputMode.Indexed : "Only regular mode is supported in R8";
diff --git a/src/main/java/com/android/tools/r8/utils/FileUtils.java b/src/main/java/com/android/tools/r8/utils/FileUtils.java
index 3f69c2e88..6a708455d 100644
--- a/src/main/java/com/android/tools/r8/utils/FileUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/FileUtils.java
@@ -73,10 +73,10 @@ public class FileUtils {
Files.write(file, Arrays.asList(lines));
}
- public static Path validateOutputFile(Path path) throws CompilationException {
+ public static Path validateOutputFile(Path path, boolean allowOverwrite) throws CompilationException {
if (path != null) {
if (isZipFile(path)) {
- if (Files.exists(path)) {
+ if ((!allowOverwrite) && Files.exists(path)) {
throw new CompilationException("Cannot write to existing output file: " + path);
}
} else if (!(Files.exists(path) && Files.isDirectory(path))) {
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index e74eb2c15..e039e9e2f 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -725,4 +725,10 @@ public class ToolHelper {
public static AndroidApp getApp(BaseCommand command) {
return command.getInputApp();
}
+
+ public static <T extends BaseCommand, U extends BaseCommand.Builder<T, U>>
+ U setOverwrite(U commandBuilder, boolean overwrite) {
+ commandBuilder.setOverwriteOutputs(overwrite);
+ return commandBuilder;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/utils/D8CommandTest.java b/src/test/java/com/android/tools/r8/utils/D8CommandTest.java
index be72756df..b0869106f 100644
--- a/src/test/java/com/android/tools/r8/utils/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/utils/D8CommandTest.java
@@ -58,7 +58,7 @@ public class D8CommandTest {
@Test
public void defaultOutIsCwd() throws IOException, InterruptedException {
Path working = temp.getRoot().toPath();
- Path input = Paths.get(EXAMPLES_BUILD_DIR, "arithmetic.jar").toAbsolutePath();
+ Path input = Paths.get(EXAMPLES_BUILD_DIR + "/arithmetic.jar").toAbsolutePath();
Path output = working.resolve("classes.dex");
assertFalse(Files.exists(output));
assertEquals(0, ToolHelper.forkD8(working, input.toString()).exitCode);
@@ -91,9 +91,15 @@ public class D8CommandTest {
}
@Test
- public void existingOutputZip() throws Throwable {
+ public void existingOutputZipNoOverwrite() throws Throwable {
thrown.expect(CompilationException.class);
Path existingZip = temp.newFile("an-existing-archive.zip").toPath();
+ ToolHelper.setOverwrite(D8Command.builder().setOutputPath(existingZip), false).build();
+ }
+
+ @Test
+ public void existingOutputZip() throws Throwable {
+ Path existingZip = temp.newFile("an-existing-archive.zip").toPath();
D8Command.builder().setOutputPath(existingZip).build();
}
@@ -113,7 +119,6 @@ public class D8CommandTest {
@Test
public void existingOutputZipParse() throws Throwable {
- thrown.expect(CompilationException.class);
Path existingZip = temp.newFile("an-existing-archive.zip").toPath();
parse("--output", existingZip.toString());
}
diff --git a/src/test/java/com/android/tools/r8/utils/R8CommandTest.java b/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
index 935275aa5..15df84fe1 100644
--- a/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
@@ -98,12 +98,18 @@ public class R8CommandTest {
@Test
public void existingOutputZip() throws Throwable {
- thrown.expect(CompilationException.class);
Path existingZip = temp.newFile("an-existing-archive.zip").toPath();
R8Command.builder().setOutputPath(existingZip).build();
}
@Test
+ public void existingOutputZipNoOverwrite() throws Throwable {
+ thrown.expect(CompilationException.class);
+ Path existingZip = temp.newFile("an-existing-archive.zip").toPath();
+ ToolHelper.setOverwrite(R8Command.builder().setOutputPath(existingZip), false).build();
+ }
+
+ @Test
public void invalidOutputFileType() throws Throwable {
thrown.expect(CompilationException.class);
Path invalidType = temp.getRoot().toPath().resolve("an-invalid-output-file-type.foobar");
@@ -119,7 +125,6 @@ public class R8CommandTest {
@Test
public void existingOutputZipParse() throws Throwable {
- thrown.expect(CompilationException.class);
Path existingZip = temp.newFile("an-existing-archive.zip").toPath();
parse("--output", existingZip.toString());
}