Merge "Print encoded errors only if data binding is invoked from the IDE" into mnc-dev
diff --git a/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java b/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java
index 2561d73..5b0c0b4 100644
--- a/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java
+++ b/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java
@@ -39,4 +39,5 @@
String exportClassListTo();
boolean isLibrary();
boolean enableDebugLogs() default false;
+ boolean printEncodedError() default false;
}
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java
index 41aa12e..c9cf2a0 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java
@@ -50,6 +50,9 @@
public class BaseCompilationTest {
+
+ private static final String PRINT_ENCODED_ERRORS_PROPERTY
+ = "android.databinding.injected.print.encoded.errors";
@Rule
public TestName name = new TestName();
static Pattern VARIABLES = Pattern.compile("!@\\{([A-Za-z0-9_-]*)}");
@@ -103,8 +106,9 @@
/**
* Extracts the text in the given location from the the at the given application path.
+ *
* @param pathInApp The path, relative to the root of the application under test
- * @param location The location to extract
+ * @param location The location to extract
* @return The string that is contained in the given location
* @throws IOException If file is invalid.
*/
@@ -113,7 +117,7 @@
assertTrue(file.exists());
StringBuilder result = new StringBuilder();
List<String> lines = FileUtils.readLines(file);
- for (int i = location.startLine; i <= location.endLine; i ++) {
+ for (int i = location.startLine; i <= location.endLine; i++) {
if (i > location.startLine) {
result.append("\n");
}
@@ -144,7 +148,7 @@
protected static Map<String, String> toMap(String... keysAndValues) {
assertEquals(0, keysAndValues.length % 2);
Map<String, String> map = new HashMap<>();
- for (int i = 0; i < keysAndValues.length; i+=2) {
+ for (int i = 0; i < keysAndValues.length; i += 2) {
map.put(keysAndValues[i], keysAndValues[i + 1]);
}
return map;
@@ -203,7 +207,8 @@
replacements = addDefaults(replacements);
// how to get build folder, pass from gradle somehow ?
FileUtils.forceMkdir(testFolder);
- copyResourceTo("/AndroidManifest.xml", new File(testFolder, "app/src/main/AndroidManifest.xml"), replacements);
+ copyResourceTo("/AndroidManifest.xml",
+ new File(testFolder, "app/src/main/AndroidManifest.xml"), replacements);
copyResourceTo("/project_build.gradle", new File(testFolder, "build.gradle"), replacements);
copyResourceTo("/app_build.gradle", new File(testFolder, "app/build.gradle"), replacements);
copyResourceTo("/settings.gradle", new File(testFolder, "settings.gradle"), replacements);
@@ -226,14 +231,17 @@
FileUtils.forceMkdir(moduleFolder);
copyResourceTo("/AndroidManifest.xml",
new File(moduleFolder, "src/main/AndroidManifest.xml"), replacements);
- copyResourceTo("/module_build.gradle", new File(moduleFolder, "build.gradle"), replacements);
+ copyResourceTo("/module_build.gradle", new File(moduleFolder, "build.gradle"),
+ replacements);
}
- protected CompilationResult runGradle(String... params) throws IOException, InterruptedException {
+ protected CompilationResult runGradle(String... params)
+ throws IOException, InterruptedException {
setExecutable();
File pathToExecutable = new File(testFolder, "gradlew");
List<String> args = new ArrayList<>();
args.add(pathToExecutable.getAbsolutePath());
+ args.add("-P" + PRINT_ENCODED_ERRORS_PROPERTY + "=true");
args.add("--project-cache-dir");
args.add(new File("../.caches/", name.getMethodName()).getAbsolutePath());
Collections.addAll(args, params);
@@ -244,7 +252,7 @@
builder.environment().put("JAVA_HOME", javaHome);
}
builder.directory(testFolder);
- Process process = builder.start();
+ Process process = builder.start();
String output = IOUtils.toString(process.getInputStream());
String error = IOUtils.toString(process.getErrorStream());
int result = process.waitFor();
@@ -261,7 +269,8 @@
perms.add(PosixFilePermission.GROUP_READ);
//add others permissions
perms.add(PosixFilePermission.OTHERS_READ);
- Files.setPosixFilePermissions(Paths.get(new File(testFolder, "gradlew").getAbsolutePath()), perms);
+ Files.setPosixFilePermissions(Paths.get(new File(testFolder, "gradlew").getAbsolutePath()),
+ perms);
}
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/BuildInfoUtil.java b/compiler/src/main/java/android/databinding/annotationprocessor/BuildInfoUtil.java
index 95eb675..b74e6e5 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/BuildInfoUtil.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/BuildInfoUtil.java
@@ -17,6 +17,7 @@
package android.databinding.annotationprocessor;
import android.databinding.BindingBuildInfo;
+import android.databinding.tool.processing.ScopedException;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
@@ -32,6 +33,7 @@
sCached = extractNotNull(roundEnvironment, BindingBuildInfo.class);
if (sCached != null) {
L.setDebugLog(sCached.enableDebugLogs());
+ ScopedException.encodeOutput(sCached.printEncodedError());
}
}
return sCached;
diff --git a/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java b/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
index f48c002..046bddb 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
@@ -163,11 +163,11 @@
public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir,
/*Nullable*/ File exportClassListTo) {
- writeInfoClass(sdkDir, xmlOutDir, exportClassListTo, false);
+ writeInfoClass(sdkDir, xmlOutDir, exportClassListTo, false, false);
}
public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir, File exportClassListTo,
- boolean enableDebugLogs) {
+ boolean enableDebugLogs, boolean printEncodedErrorLogs) {
final String sdkPath = sdkDir == null ? null : StringEscapeUtils.escapeJava(sdkDir.getAbsolutePath());
final Class annotation = BindingBuildInfo.class;
final String layoutInfoPath = StringEscapeUtils.escapeJava(xmlOutDir.getAbsolutePath());
@@ -182,7 +182,8 @@
"exportClassListTo=\"" + exportClassListToPath + "\"," +
"isLibrary=" + mIsLibrary + "," +
"minSdk=" + mMinSdk + "," +
- "enableDebugLogs=" + enableDebugLogs + ")\n" +
+ "enableDebugLogs=" + enableDebugLogs + "," +
+ "printEncodedError=" + printEncodedErrorLogs + ")\n" +
"public class " + CLASS_NAME + " {}\n";
mFileWriter.writeToFile(RESOURCE_BUNDLE_PACKAGE + "." + CLASS_NAME, classString);
}
diff --git a/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java b/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
index 73f42a9..238a895 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
@@ -35,6 +35,7 @@
public static final String MSG_KEY = "msg:";
public static final String LOCATION_KEY = "loc:";
public static final String FILE_KEY = "file:";
+ private static boolean sEncodeOutput = false;
private ScopedErrorReport mScopedErrorReport;
private String mScopeLog;
@@ -55,6 +56,23 @@
@Override
public String getMessage() {
+ return sEncodeOutput ? createEncodedMessage() : createHumanReadableMessage();
+ }
+
+ private String createHumanReadableMessage() {
+ ScopedErrorReport scopedError = getScopedErrorReport();
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.getMessage()).append("\n")
+ .append("file://").append(scopedError.getFilePath());
+ if (scopedError.getLocations() != null && scopedError.getLocations().size() > 0) {
+ sb.append(" Line:");
+ sb.append(scopedError.getLocations().get(0).startLine);
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private String createEncodedMessage() {
ScopedErrorReport scopedError = getScopedErrorReport();
StringBuilder sb = new StringBuilder();
sb.append(ERROR_LOG_PREFIX)
@@ -135,4 +153,8 @@
}
return errors;
}
+
+ public static void encodeOutput(boolean encodeOutput) {
+ sEncodeOutput = encodeOutput;
+ }
}
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
index 600edcf..22e1056 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
@@ -47,6 +47,7 @@
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.api.tasks.compile.AbstractCompile;
+import android.databinding.tool.processing.ScopedException;
import android.databinding.tool.util.L;
import android.databinding.tool.writer.JavaFileWriter;
@@ -63,7 +64,11 @@
public class DataBinderPlugin implements Plugin<Project> {
+ private static final String INVOKED_FROM_IDE_PROPERTY = "android.injected.invoked.from.ide";
+ private static final String PRINT_ENCODED_ERRORS_PROPERTY
+ = "android.databinding.injected.print.encoded.errors";
private Logger logger;
+ private boolean printEncodedErrors = false;
class GradleFileWriter extends JavaFileWriter {
@@ -93,6 +98,26 @@
}
}
+ private boolean safeGetBooleanProperty(Project project, String property) {
+ boolean hasProperty = project.hasProperty(property);
+ if (!hasProperty) {
+ return false;
+ }
+ try {
+ if (Boolean.parseBoolean(String.valueOf(project.getProperties().get(property)))) {
+ return true;
+ }
+ } catch (Throwable t) {
+ L.w("unable to read property %s", project);
+ }
+ return false;
+ }
+
+ private boolean resolvePrintEncodedErrors(Project project) {
+ return safeGetBooleanProperty(project, INVOKED_FROM_IDE_PROPERTY) ||
+ safeGetBooleanProperty(project, PRINT_ENCODED_ERRORS_PROPERTY);
+ }
+
@Override
public void apply(Project project) {
if (project == null) {
@@ -105,7 +130,8 @@
if (StringUtils.isEmpty(myVersion)) {
throw new IllegalStateException("cannot read version of the plugin :/");
}
-
+ printEncodedErrors = resolvePrintEncodedErrors(project);
+ ScopedException.encodeOutput(printEncodedErrors);
project.getDependencies().add("compile", "com.android.databinding:library:" + myVersion);
boolean addAdapters = true;
if (project.hasProperty("ext")) {
@@ -308,7 +334,9 @@
task.setSdkDir(sdkDir);
task.setXmlOutFolder(xmlOutDir);
task.setExportClassListTo(generatedClassListOut);
+ task.setPrintEncodedErrors(printEncodedErrors);
task.setEnableDebugLogs(logger.isEnabled(LogLevel.DEBUG));
+
variantData.registerJavaGeneratingTask(task, codeGenTargetFolder);
}
});
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExcludeGeneratedTask.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExcludeGeneratedTask.java
index cfc7a98..a58d97a 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExcludeGeneratedTask.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExcludeGeneratedTask.java
@@ -25,6 +25,7 @@
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.bundling.Jar;
+import android.databinding.tool.processing.Scope;
import android.databinding.tool.util.L;
import java.io.File;
@@ -92,6 +93,7 @@
exclude(klass.replace('.', '/') + ".class");
}
}
+ Scope.assertNoError();
L.d("Excluding generated classes from library jar is done.");
}
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
index 4eb06b2..768fe68 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
@@ -15,9 +15,11 @@
*/
package android.databinding.tool;
-import android.databinding.tool.util.L;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;
+
+import android.databinding.tool.processing.Scope;
+
import java.io.File;
/**
@@ -28,10 +30,13 @@
private File sdkDir;
private File xmlOutFolder;
private File exportClassListTo;
+ private boolean printEncodedErrors;
private boolean enableDebugLogs = false;
@TaskAction
public void exportInfo() {
- xmlProcessor.writeInfoClass(sdkDir, xmlOutFolder, exportClassListTo, enableDebugLogs);
+ xmlProcessor.writeInfoClass(sdkDir, xmlOutFolder, exportClassListTo, enableDebugLogs,
+ printEncodedErrors);
+ Scope.assertNoError();
}
public LayoutXmlProcessor getXmlProcessor() {
@@ -66,6 +71,14 @@
this.exportClassListTo = exportClassListTo;
}
+ public boolean isPrintEncodedErrors() {
+ return printEncodedErrors;
+ }
+
+ public void setPrintEncodedErrors(boolean printEncodedErrors) {
+ this.printEncodedErrors = printEncodedErrors;
+ }
+
public boolean isEnableDebugLogs() {
return enableDebugLogs;
}
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java
index 7a6100d..320d4dc 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java
@@ -15,6 +15,7 @@
*/
package android.databinding.tool;
+import android.databinding.tool.processing.Scope;
import android.databinding.tool.util.L;
import org.gradle.api.DefaultTask;
@@ -47,6 +48,7 @@
IOException {
L.d("running process layouts task %s", getName());
xmlProcessor.processResources(minSdk);
+ Scope.assertNoError();
}
public void writeLayoutXmls() throws JAXBException {