Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Fix up lint output resource paths.
Browse files Browse the repository at this point in the history
Fixes #3360

The lint tool is run against our `$(IntermediateOutputPath)`
directory, as a result we end up with paths which point to
that directory.

We should be fixing those paths up to point to the normal
`Resources` directory in the project, just like we do
with `aapt/aapt2`.
  • Loading branch information
dellis1972 committed Aug 22, 2019
1 parent d762aa9 commit 69f413c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 14 deletions.
7 changes: 3 additions & 4 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs
Expand Up @@ -418,10 +418,9 @@ protected void LogEventsFromTextOutput (string singleLine, MessageImportance mes

// Try to map back to the original resource file, so when the user
// double clicks the error, it won't take them to the obj/Debug copy
if (file.StartsWith (resourceDirectory, StringComparison.InvariantCultureIgnoreCase)) {
file = file.Substring (resourceDirectory.Length).TrimStart (Path.DirectorySeparatorChar);
file = resource_name_case_map.ContainsKey (file) ? resource_name_case_map [file] : file;
file = Path.Combine ("Resources", file);
string newfile = MonoAndroidHelper.FixUpAndroidResourcePath (file, resourceDirectory, string.Empty, resource_name_case_map);
if (!string.IsNullOrEmpty (newfile)) {
file = newfile;
}

// Strip any "Error:" text from aapt's output
Expand Down
11 changes: 2 additions & 9 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs
Expand Up @@ -164,16 +164,9 @@ protected bool LogAapt2EventsFromOutput (string singleLine, MessageImportance me
foreach (var dir in ResourceDirectories) {
var resourceDirectory = dir.ItemSpec;
var resourceDirectoryFullPath = ResourceDirectoryFullPath (resourceDirectory);
string newfile = null;
if (file.StartsWith (resourceDirectory, StringComparison.InvariantCultureIgnoreCase)) {
newfile = file.Substring (resourceDirectory.Length).TrimStart (Path.DirectorySeparatorChar);
}
if (file.StartsWith (resourceDirectoryFullPath, StringComparison.InvariantCultureIgnoreCase)) {
newfile = file.Substring (resourceDirectoryFullPath.Length).TrimStart (Path.DirectorySeparatorChar);
}

string newfile = MonoAndroidHelper.FixUpAndroidResourcePath (file, resourceDirectory, resourceDirectoryFullPath, resource_name_case_map);
if (!string.IsNullOrEmpty (newfile)) {
newfile = resource_name_case_map.ContainsKey (newfile) ? resource_name_case_map [newfile] : newfile;
newfile = Path.Combine ("Resources", newfile);
file = newfile;
break;
}
Expand Down
20 changes: 19 additions & 1 deletion src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs
Expand Up @@ -38,6 +38,7 @@ public class Lint : ToolTask
const string NoFileWarningOrErrorRegExString = @"(?<type>Warning|Error):(?<text>.+)";
Regex codeErrorRegEx = new Regex (CodeErrorRegExString, RegexOptions.Compiled);
Regex noFileWarningOrErrorRegEx = new Regex(NoFileWarningOrErrorRegExString, RegexOptions.Compiled);
protected Dictionary<string, string> resource_name_case_map;
bool matched = false;
string file;
int line;
Expand Down Expand Up @@ -147,6 +148,8 @@ public class Lint : ToolTask
get { return OS.IsWindows ? "lint.bat" : "lint"; }
}

public string ResourceNameCaseMap { get; set; }

public Lint ()
{
ResourceDirectories = new ITaskItem[0];
Expand Down Expand Up @@ -208,6 +211,8 @@ public override bool Execute ()

EnvironmentVariables = new [] { "JAVA_HOME=" + JavaSdkPath };

resource_name_case_map = MonoAndroidHelper.LoadResourceCaseMap (ResourceNameCaseMap);

base.Execute ();

return !Log.HasLoggedErrors;
Expand Down Expand Up @@ -279,8 +284,21 @@ protected override void LogEventsFromTextOutput (string singleLine, MessageImpor
}
matched = true;
file = match.Groups ["file"].Value;
if (!string.IsNullOrEmpty (file))
if (!string.IsNullOrEmpty (file)) {
file = Path.Combine (TargetDirectory, file);
// Try to map back to the original resource file, so when the user
// double clicks the error, it won't take them to the obj/Debug copy
if (ResourceDirectories != null) {
foreach (var dir in ResourceDirectories) {
var resourceDirectory = Path.Combine (TargetDirectory, dir.ItemSpec);
string newfile = MonoAndroidHelper.FixUpAndroidResourcePath (file, resourceDirectory, string.Empty, resource_name_case_map);
if (!string.IsNullOrEmpty (newfile)) {
file = newfile;
break;
}
}
}
}
line = 0;
int.TryParse (match.Groups ["line"].Value, out line);
text = match.Groups ["text"].Value.Trim ();
Expand Down
Expand Up @@ -1560,6 +1560,48 @@ void FixLintOnWindows ()
}
}

[Test]
public void CheckLintResourceFileReferencesAreFixed ()
{
FixLintOnWindows ();

var proj = new XamarinAndroidApplicationProject () {
PackageReferences = {
KnownPackages.AndroidSupportV4_27_0_2_1,
KnownPackages.SupportConstraintLayout_1_0_2_2,
},
};
proj.SetProperty ("AndroidLintEnabled", true.ToString ());
proj.AndroidResources.Add (new AndroidItem.AndroidResource ("Resources\\layout\\test.axml") {
TextContent = () => {
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<ConstraintLayout xmlns:android=""http://schemas.android.com/apk/res/android""
xmlns:app=""http://schemas.android.com/apk/res-auto""
android:orientation=""vertical""
android:layout_width=""fill_parent""
android:layout_height=""fill_parent"">
<TextView android:id=""@+id/foo""
android:layout_width=""150dp""
android:layout_height=""wrap_content""
app:layout_constraintTop_toTopOf=""parent""
/>
<EditText
android:id=""@+id/phone""
android:layout_width=""fill_parent""
android:layout_height=""wrap_content""
android:hint=""Hint me up.""
/>
</ConstraintLayout>";
}
});
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Project should have built.");
StringAssertEx.Contains ("XA0102", b.LastBuildOutput, "Output should contain XA0102 warnings");
var errorFilePath = Path.Combine (proj.IntermediateOutputPath, "android", proj.IntermediateOutputPath, "res", "layout", "test.xml");
StringAssertEx.DoesNotContain (errorFilePath, b.LastBuildOutput, $"Path {errorFilePath} should have been replaced.");
}
}

[Test]
public void CheckLintErrorsAndWarnings ()
{
Expand Down
17 changes: 17 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs
Expand Up @@ -613,5 +613,22 @@ public static string TryGetAndroidJarPath (TaskLoggingHelper log, string platfor
}
return result;
}

public static string FixUpAndroidResourcePath (string file, string resourceDirectory, string resourceDirectoryFullPath, Dictionary<string, string> resource_name_case_map)
{
string newfile = null;
if (file.StartsWith (resourceDirectory, StringComparison.InvariantCultureIgnoreCase)) {
newfile = file.Substring (resourceDirectory.Length).TrimStart (Path.DirectorySeparatorChar);
}
if (!string.IsNullOrEmpty (resourceDirectoryFullPath) && file.StartsWith (resourceDirectoryFullPath, StringComparison.InvariantCultureIgnoreCase)) {
newfile = file.Substring (resourceDirectoryFullPath.Length).TrimStart (Path.DirectorySeparatorChar);
}
if (!string.IsNullOrEmpty (newfile)) {
newfile = resource_name_case_map.ContainsKey (newfile) ? resource_name_case_map [newfile] : newfile;
newfile = Path.Combine ("Resources", newfile);
return newfile;
}
return string.Empty;
}
}
}
Expand Up @@ -1126,6 +1126,7 @@ because xbuild doesn't support framework reference assemblies.
ToolPath="$(LintToolPath)"
ToolExe="$(LintToolExe)"
JavaSdkPath="$(_JavaSdkDirectory)"
ResourceNameCaseMap="$(_AndroidResourceNameCaseMap)"
/>
</Target>

Expand Down

0 comments on commit 69f413c

Please sign in to comment.