Skip to content

Commit 2d400aa

Browse files
jpobstjonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] Improve AAPT error granularity (#3577)
Context: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/735263 Context: https://android.googlesource.com/platform/frameworks/base/+/563abce4ed0a0d9f08f8839a8f15b548b3dcd4d1/tools/aapt Context: https://gist.github.com/grendello/72c1ce5f6e8cdd3aefd393b983576d9a Errors and warning *codes* for errors and warnings reported *within Visual Studio* from developers participating in the [Visual Studio Customer Experience Improvement Program][0] are reported "telemetry" events, but *only* the error and warning codes are reported. The warning and error message contents are not sent. Unfortunately all `aapt`-related errors are reported as APT0000, which reduces the utility of telemetry, making it more difficult to better understand where our build system could be improved. @grendello created a `grep` pipeline for the `aapt` sources to try to extract plausible error messages that we can compare against. The exact pipeline has been lost, but this is an in-progress pipeline for finding error messages from the `aapt2` sources: rgrep -Pzoh '(?s)(->|\.)Error.*?;\n' * | \ tr -d '\n' | tr ';' '\n'| \ sed -e 's/^[ \t]*//g' -e 's/^.*Error([ \t]*DiagMessage[ \t]*(.*)[ \t]*<<//g' -e 's/^.*Error(.*)//g;' -e 's/^;$//g' | \ sort | uniq Improve the `<Aapt/>` task to check against this list of "known" error strings and associate them with unique `APTxxxx` codes. This will allow for more meaningful documentation to be written in the future, and will allow our telemetry to be more meaningful and permit improved focusing of future efforts. [0]: https://docs.microsoft.com/en-us/visualstudio/ide/visual-studio-experience-improvement-program?view=vs-2019
1 parent 87f9f9a commit 2d400aa

File tree

3 files changed

+173
-9
lines changed

3 files changed

+173
-9
lines changed

src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs

Lines changed: 168 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ protected void LogEventsFromTextOutput (string singleLine, MessageImportance mes
414414
return;
415415
}
416416
if (level.Contains ("warning")) {
417-
LogCodedWarning ("APT0000", singleLine);
417+
LogCodedWarning (GetErrorCode (singleLine), singleLine);
418418
return;
419419
}
420420

@@ -430,16 +430,180 @@ protected void LogEventsFromTextOutput (string singleLine, MessageImportance mes
430430
message = message.Substring ("error: ".Length);
431431

432432
if (level.Contains ("error") || (line != 0 && !string.IsNullOrEmpty (file))) {
433-
LogCodedError ("APT0000", message, file, line);
433+
LogCodedError (GetErrorCode (message), message, file, line);
434434
return;
435435
}
436436
}
437437

438438
if (!apptResult) {
439-
LogCodedError ("APT0000", string.Format ("{0} \"{1}\".", singleLine.Trim (), singleLine.Substring (singleLine.LastIndexOfAny (new char [] { '\\', '/' }) + 1)), ToolName);
439+
var message = string.Format ("{0} \"{1}\".", singleLine.Trim (), singleLine.Substring (singleLine.LastIndexOfAny (new char [] { '\\', '/' }) + 1));
440+
LogCodedError (GetErrorCode (message), message, ToolName);
440441
} else {
441-
LogCodedWarning ("APT0000", singleLine);
442+
LogCodedWarning (GetErrorCode (singleLine), singleLine);
442443
}
443444
}
445+
446+
static string GetErrorCode (string message)
447+
{
448+
foreach (var tuple in error_codes)
449+
if (message.IndexOf (tuple.Item2, StringComparison.OrdinalIgnoreCase) >= 0)
450+
return tuple.Item1;
451+
452+
return "APT1000";
453+
}
454+
455+
static readonly List<Tuple<string, string>> error_codes = new List<Tuple<string, string>> () {
456+
Tuple.Create ("APT1001", "can't use '-u' with add"),
457+
Tuple.Create ("APT1002", "dump failed because assets could not be loaded"),
458+
Tuple.Create ("APT1003", "dump failed because no AndroidManifest.xml found"),
459+
Tuple.Create ("APT1004", "dump failed because the resource table is invalid/corrupt"),
460+
Tuple.Create ("APT1005", "during crunch - archive is toast"),
461+
Tuple.Create ("APT1006", "failed to get platform version code"),
462+
Tuple.Create ("APT1007", "failed to get platform version name"),
463+
Tuple.Create ("APT1008", "failed to get XML element name (bad string pool)"),
464+
Tuple.Create ("APT1009", "failed to write library table"),
465+
Tuple.Create ("APT1010", "getting resolved resource attribute"),
466+
Tuple.Create ("APT1011", "Key string data is corrupt"),
467+
Tuple.Create ("APT1012", "list -a failed because assets could not be loaded"),
468+
Tuple.Create ("APT1013", "manifest does not start with <manifest> tag"),
469+
Tuple.Create ("APT1014", "missing 'android:name' for permission"),
470+
Tuple.Create ("APT1015", "missing 'android:name' for uses-permission"),
471+
Tuple.Create ("APT1016", "missing 'android:name' for uses-permission-sdk-23"),
472+
Tuple.Create ("APT1017", "Missing entries, quit"),
473+
Tuple.Create ("APT1018", "must specify zip file name"),
474+
Tuple.Create ("APT1019", "No AndroidManifest.xml file found"),
475+
Tuple.Create ("APT1020", "No argument supplied for '-A' option"),
476+
Tuple.Create ("APT1021", "No argument supplied for '-c' option"),
477+
Tuple.Create ("APT1022", "No argument supplied for '--custom-package' option"),
478+
Tuple.Create ("APT1023", "No argument supplied for '-D' option"),
479+
Tuple.Create ("APT1024", "No argument supplied for '-e' option"),
480+
Tuple.Create ("APT1025", "No argument supplied for '--extra-packages' option"),
481+
Tuple.Create ("APT1026", "No argument supplied for '--feature-after' option"),
482+
Tuple.Create ("APT1027", "No argument supplied for '--feature-of' option"),
483+
Tuple.Create ("APT1028", "No argument supplied for '-F' option"),
484+
Tuple.Create ("APT1029", "No argument supplied for '-g' option"),
485+
Tuple.Create ("APT1030", "No argument supplied for '--ignore-assets' option"),
486+
Tuple.Create ("APT1031", "No argument supplied for '-I' option"),
487+
Tuple.Create ("APT1032", "No argument supplied for '-j' option"),
488+
Tuple.Create ("APT1033", "No argument supplied for '--max-res-version' option"),
489+
Tuple.Create ("APT1034", "No argument supplied for '--max-sdk-version' option"),
490+
Tuple.Create ("APT1035", "No argument supplied for '--min-sdk-version' option"),
491+
Tuple.Create ("APT1036", "No argument supplied for '-M' option"),
492+
Tuple.Create ("APT1037", "No argument supplied for '-o' option"),
493+
Tuple.Create ("APT1038", "No argument supplied for '-output-text-symbols' option"),
494+
Tuple.Create ("APT1039", "No argument supplied for '-P' option"),
495+
Tuple.Create ("APT1040", "No argument supplied for '--preferred-density' option"),
496+
Tuple.Create ("APT1041", "No argument supplied for '--private-symbols' option"),
497+
Tuple.Create ("APT1042", "No argument supplied for '--product' option"),
498+
Tuple.Create ("APT1043", "No argument supplied for '--rename-instrumentation-target-package' option"),
499+
Tuple.Create ("APT1044", "No argument supplied for '--rename-manifest-package' option"),
500+
Tuple.Create ("APT1045", "No argument supplied for '-S' option"),
501+
Tuple.Create ("APT1046", "No argument supplied for '--split' option"),
502+
Tuple.Create ("APT1047", "No argument supplied for '--target-sdk-version' option"),
503+
Tuple.Create ("APT1048", "No argument supplied for '--version-code' option"),
504+
Tuple.Create ("APT1049", "No argument supplied for '--version-name' option"),
505+
Tuple.Create ("APT1050", "no dump file specified"),
506+
Tuple.Create ("APT1051", "no dump option specified"),
507+
Tuple.Create ("APT1052", "no dump xmltree resource file specified"),
508+
Tuple.Create ("APT1053", "no input files"),
509+
Tuple.Create ("APT1054", "no <manifest> tag found in platform AndroidManifest.xml"),
510+
Tuple.Create ("APT1055", "out of memory creating package chunk for ResTable_header"),
511+
Tuple.Create ("APT1056", "out of memory creating ResTable_entry"),
512+
Tuple.Create ("APT1057", "out of memory creating ResTable_header"),
513+
Tuple.Create ("APT1058", "out of memory creating ResTable_package"),
514+
Tuple.Create ("APT1059", "out of memory creating ResTable_type"),
515+
Tuple.Create ("APT1060", "out of memory creating ResTable_typeSpec"),
516+
Tuple.Create ("APT1061", "out of memory creating Res_value"),
517+
Tuple.Create ("APT1062", "Out of memory for string pool"),
518+
Tuple.Create ("APT1063", "Out of memory padding string pool"),
519+
Tuple.Create ("APT1064", "parsing XML"),
520+
Tuple.Create ("APT1065", "Platform AndroidManifest.xml is corrupt"),
521+
Tuple.Create ("APT1066", "Platform AndroidManifest.xml not found"),
522+
Tuple.Create ("APT1067", "print resolved resource attribute"),
523+
Tuple.Create ("APT1068", "retrieving parent for item:"),
524+
Tuple.Create ("APT1069", "specify zip file name (only)"),
525+
Tuple.Create ("APT1070", "Type string data is corrupt"),
526+
Tuple.Create ("APT1071", "Unable to parse generated resources, aborting"),
527+
Tuple.Create ("APT1072", "Invalid BCP 47 tag in directory name"), // ERROR: Invalid BCP 47 tag in directory name: %s
528+
Tuple.Create ("APT1073", "parsing preferred density"), // Error parsing preferred density: %s
529+
Tuple.Create ("APT1074", "Asset package include"), // ERROR: Asset package include '%s' not found
530+
Tuple.Create ("APT1075", "base feature package"), // ERROR: base feature package '%s' not found
531+
Tuple.Create ("APT1076", "Split configuration"), // ERROR: Split configuration '%s' is already defined in another split
532+
Tuple.Create ("APT1077", "failed opening/creating"), // ERROR: failed opening/creating '%s' as Zip file
533+
Tuple.Create ("APT1078", "as Zip file for writing"), // ERROR: unable to open '%s' as Zip file for writing
534+
Tuple.Create ("APT1079", "as Zip file"), // ERROR: failed opening '%s' as Zip file
535+
Tuple.Create ("APT1080", "included asset path"), // ERROR: included asset path %s could not be loaded
536+
Tuple.Create ("APT1081", "getting 'android:name' attribute"),
537+
Tuple.Create ("APT1082", "getting 'android:name'"),
538+
Tuple.Create ("APT1083", "getting 'android:versionCode' attribute"),
539+
Tuple.Create ("APT1084", "getting 'android:versionName' attribute"),
540+
Tuple.Create ("APT1085", "getting 'android:compileSdkVersion' attribute"),
541+
Tuple.Create ("APT1086", "getting 'android:installLocation' attribute"),
542+
Tuple.Create ("APT1087", "getting 'android:icon' attribute"),
543+
Tuple.Create ("APT1088", "getting 'android:testOnly' attribute"),
544+
Tuple.Create ("APT1089", "getting 'android:banner' attribute"),
545+
Tuple.Create ("APT1090", "getting 'android:isGame' attribute"),
546+
Tuple.Create ("APT1091", "getting 'android:debuggable' attribute"),
547+
Tuple.Create ("APT1092", "getting 'android:minSdkVersion' attribute"),
548+
Tuple.Create ("APT1093", "getting 'android:targetSdkVersion' attribute"),
549+
Tuple.Create ("APT1094", "getting 'android:label' attribute"),
550+
Tuple.Create ("APT1095", "getting compatible screens"),
551+
Tuple.Create ("APT1096", "getting 'android:name' attribute for uses-library"),
552+
Tuple.Create ("APT1097", "getting 'android:name' attribute for receiver"),
553+
Tuple.Create ("APT1098", "getting 'android:permission' attribute for receiver"),
554+
Tuple.Create ("APT1099", "getting 'android:name' attribute for service"),
555+
Tuple.Create ("APT1100", "getting 'android:name' attribute for meta-data tag in service"),
556+
Tuple.Create ("APT1101", "getting 'android:name' attribute for meta-data"),
557+
Tuple.Create ("APT1102", "getting 'android:permission' attribute for service"),
558+
Tuple.Create ("APT1103", "getting 'android:permission' attribute for provider"),
559+
Tuple.Create ("APT1104", "getting 'android:exported' attribute for provider"),
560+
Tuple.Create ("APT1105", "getting 'android:grantUriPermissions' attribute for provider"),
561+
Tuple.Create ("APT1106", "getting 'android:value' or 'android:resource' attribute for meta-data"),
562+
Tuple.Create ("APT1107", "getting 'android:resource' attribute for meta-data tag in service"),
563+
Tuple.Create ("APT1108", "getting AID category for service"),
564+
Tuple.Create ("APT1109", "getting 'name' attribute"),
565+
Tuple.Create ("APT1110", "unknown dump option"),
566+
Tuple.Create ("APT1111", "failed opening Zip archive"),
567+
Tuple.Create ("APT1112", "exists but is not regular file"), // ERROR: output file '%s' exists but is not regular file
568+
Tuple.Create ("APT1113", "failed to parse split configuration"),
569+
Tuple.Create ("APT1114", "packaging of"), // ERROR: packaging of '%s' failed
570+
Tuple.Create ("APT1115", "9-patch image"), // ERROR: 9-patch image %s malformed
571+
Tuple.Create ("APT1116", "Failure processing PNG image"),
572+
Tuple.Create ("APT1117", "Unknown command"),
573+
Tuple.Create ("APT1118", "exists (use '-f' to force overwrite)"),
574+
Tuple.Create ("APT1119", "exists and is not a regular file"),
575+
Tuple.Create ("APT1120", "unable to process assets while packaging"),
576+
Tuple.Create ("APT1121", "unable to process jar files while packaging"),
577+
Tuple.Create ("APT1122", "Unknown option"),
578+
Tuple.Create ("APT1123", "Unknown flag"),
579+
Tuple.Create ("APT1124", "Zip flush failed, archive may be hosed"),
580+
Tuple.Create ("APT1125", "exists twice (check for with"), // ERROR: '%s' exists twice (check for with & w/o '.gz'?)
581+
Tuple.Create ("APT1126", "unable to uncompress entry"),
582+
Tuple.Create ("APT1127", "as a zip file"), // ERROR: unable to open '%s' as a zip file: %d
583+
Tuple.Create ("APT1128", "unable to process"), // ERROR: unable to process '%s'
584+
Tuple.Create ("APT1129", "malformed resource filename"),
585+
Tuple.Create ("APT1130", "AndroidManifest.xml already defines"), // Error: AndroidManifest.xml already defines %s (in %s); cannot insert new value %s
586+
Tuple.Create ("APT1131", "In <declare-styleable>"), // ERROR: In <declare-styleable> %s, unable to find attribute %s
587+
Tuple.Create ("APT1132", "Feature package"), // ERROR: Feature package '%s' not found
588+
Tuple.Create ("APT1133", "declaring public resource"), // Error declaring public resource %s/%s for included package %s
589+
Tuple.Create ("APT1134", "with value"), // Error: %s (at '%s' with value '%s')
590+
Tuple.Create ("APT1135", "is not a single item or a bag"), // Error: entry %s is not a single item or a bag
591+
Tuple.Create ("APT1136", "adding span for style tag"),
592+
Tuple.Create ("APT1137", "parsing XML"),
593+
Tuple.Create ("APT1138", "access denied"), // ERROR: '%s' access denied
594+
Tuple.Create ("APT1139", "included asset path"), // ERROR: included asset path %s could not be loaded
595+
Tuple.Create ("APT1140", "is corrupt"), // ERROR: Resource %s is corrupt
596+
Tuple.Create ("APT1141", "dump failed because resource"), // ERROR: dump failed because resource %s [not] found
597+
Tuple.Create ("APT1142", "not found"), // ERROR: '%s' not found
598+
Tuple.Create ("APT1043", "asset directory"), // ERROR: asset directory '%s' does not exist
599+
Tuple.Create ("APT1044", "input directory"), // ERROR: input directory '%s' does not exist
600+
Tuple.Create ("APT1045", "resource directory"), // ERROR: resource directory '%s' does not exist
601+
Tuple.Create ("APT1046", "is not a directory"), // ERROR: '%s' is not a directory
602+
Tuple.Create ("APT1047", "opening zip file"), // error opening zip file %s
603+
Tuple.Create ("APT1143", "AndroidManifest.xml is corrupt"),
604+
Tuple.Create ("APT1144", "Invalid file name: must contain only"),
605+
Tuple.Create ("APT1145", "has no default translation"),
606+
Tuple.Create ("APT1146", "max res"),
607+
};
444608
}
445609
}

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public void ReportAaptWarningsForBlankLevel ([Values (false, true)] bool useAapt
195195
using (var b = CreateApkBuilder ($"temp/{TestName}")) {
196196
b.ThrowOnBuildFailure = false;
197197
Assert.IsFalse (b.Build (proj), "Build should have failed.");
198-
StringAssertEx.Contains ("APT0000", b.LastBuildOutput, "An error message with a blank \"level\", should be reported as an error!");
198+
StringAssertEx.Contains (useAapt2 ? "APT0000" : "APT1144", b.LastBuildOutput, "An error message with a blank \"level\", should be reported as an error!");
199199
Assert.IsTrue (b.Clean (proj), "Clean should have succeeded.");
200200
}
201201
}
@@ -1281,8 +1281,8 @@ public void CheckMaxResWarningIsEmittedAsAWarning([Values (false, true)] bool us
12811281
if (useAapt2) {
12821282
StringAssertEx.DoesNotContain ("APT0000", builder.LastBuildOutput, "Build output should not contain an APT0000 warning");
12831283
} else {
1284-
var expected = builder.RunningMSBuild ? "warning APT0000: max res 26, skipping values-v27" : "warning APT0000: warning : max res 26, skipping values-v27";
1285-
StringAssertEx.Contains (expected, builder.LastBuildOutput, "Build output should contain an APT0000 warning about 'max res 26, skipping values-v27'");
1284+
var expected = builder.RunningMSBuild ? "warning APT1146: max res 26, skipping values-v27" : "warning APT1146: warning : max res 26, skipping values-v27";
1285+
StringAssertEx.Contains (expected, builder.LastBuildOutput, "Build output should contain an APT1146 warning about 'max res 26, skipping values-v27'");
12861286
}
12871287
}
12881288
}
@@ -1309,7 +1309,7 @@ public void CheckDefaultTranslationWarnings ()
13091309
});
13101310
using (var builder = CreateApkBuilder (path, false, false)) {
13111311
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
1312-
StringAssertEx.Contains ($"warning APT0000: warning: string '{name}' has no default translation.", builder.LastBuildOutput, "Build output should contain an APT0000 warning about 'no default translation'");
1312+
StringAssertEx.Contains ($"warning APT1145: warning: string '{name}' has no default translation.", builder.LastBuildOutput, "Build output should contain an APT0000 warning about 'no default translation'");
13131313
}
13141314
}
13151315

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public void Bug12935 ([Values (true, false)] bool useAapt2)
116116
proj.TargetFrameworkVersion = "v4.0.3";
117117
proj.AndroidManifest = string.Format (TargetSdkManifest, "15");
118118
Assert.IsFalse (builder.Build (proj), "Build for TargetFrameworkVersion 15 should have failed");
119-
StringAssertEx.Contains ("APT0000: ", builder.LastBuildOutput);
119+
StringAssertEx.Contains (useAapt2 ? "APT0000: " : "APT1134: ", builder.LastBuildOutput);
120120
StringAssertEx.Contains ("1 Error(s)", builder.LastBuildOutput);
121121
}
122122
}

0 commit comments

Comments
 (0)