Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 47 additions & 17 deletions src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Xml.Linq;
using System.Linq;
using Xamarin.Android.Tools;
using System.Collections.Generic;
using System.Text;

namespace Xamarin.Android.Tasks
{
Expand Down Expand Up @@ -152,33 +154,41 @@ public Lint ()
LibraryJars = new ITaskItem[0];
}


string [] disabledIssues = new string [] {
static readonly Dictionary<string, Version> DisabledIssuesByVersion = new Dictionary<string, Version> () {
// We need to hard code this test in because Lint will issue an Error
// if android:debuggable appears in the manifest. We actually need that
// in debug mode. It seems the android tools do some magic to
// decide if its needed or not.
"HardcodedDebugMode",
{ "HardcodedDebugMode", new Version(1, 0) },
// We need to hard code this test as disabled in because Lint will issue a warning
// for all the resources not used. Now because we don't have any Java code
// that means for EVERYTHING! Which will be a HUGE amount of warnings for a large project
"UnusedResources",
{ "UnusedResources", new Version(1, 0) },
// We need to hard code this test as disabled in because Lint will issue a warning
// for the MonoPackageManager.java since we have to use a static to keep track of the
// application instance.
"StaticFieldLeak",
// We don't call base.Super () for onCreate so we need to ignore this too.
"MissingSuperCall",
{ "StaticFieldLeak", new Version(26, 0, 2) },
};

static readonly Regex lintVersionRegex = new Regex (@"version[\t\s]+(?<version>[\d\.]+)");

public override bool Execute ()
{
foreach (var disabled in disabledIssues) {
if (string.IsNullOrEmpty (DisabledIssues) || !DisabledIssues.Contains (disabled))
DisabledIssues = disabled + (!string.IsNullOrEmpty (DisabledIssues) ? "," + DisabledIssues : "");
}

Log.LogDebugMessage ("Lint Task");

if (string.IsNullOrEmpty (ToolPath) || !File.Exists (GenerateFullPathToTool ())) {
Log.LogCodedError ("XA5205", $"Cannot find `{ToolName}` in the Android SDK. Please set its path via /p:LintToolPath.");
return false;
}

Version lintToolVersion = GetLintVersion (GenerateFullPathToTool ());
foreach (var issue in DisabledIssuesByVersion) {
if (lintToolVersion >= issue.Value) {
if (string.IsNullOrEmpty (DisabledIssues) || !DisabledIssues.Contains (issue.Key))
DisabledIssues = issue.Key + (!string.IsNullOrEmpty (DisabledIssues) ? "," + DisabledIssues : "");
}
}

Log.LogDebugMessage (" TargetDirectory: {0}", TargetDirectory);
Log.LogDebugMessage (" EnabledChecks: {0}", EnabledIssues);
Log.LogDebugMessage (" DisabledChecks: {0}", DisabledIssues);
Expand All @@ -190,11 +200,6 @@ public override bool Execute ()
Log.LogDebugTaskItems (" LibraryDirectories:", LibraryDirectories);
Log.LogDebugTaskItems (" LibraryJars:", LibraryJars);

if (string.IsNullOrEmpty (ToolPath) || !File.Exists (GenerateFullPathToTool ())) {
Log.LogCodedError ("XA5205", $"Cannot find `{ToolName}` in the Android SDK. Please set its path via /p:LintToolPath.");
return false;
}

base.Execute ();

return !Log.HasLoggedErrors;
Expand Down Expand Up @@ -304,6 +309,31 @@ XDocument MergeConfigFiles()
}
return config;
}

Version GetLintVersion (string tool)
{
var sb = new StringBuilder ();
var result = MonoAndroidHelper.RunProcess (tool, "--version", (s, e) => {
if (!string.IsNullOrEmpty (e.Data))
sb.AppendLine (e.Data);
}, (s, e) => {
if (!string.IsNullOrEmpty (e.Data))
sb.AppendLine (e.Data);
}
);
if (result != 0) {
Log.LogWarning ($"Could not get version from '{tool}'");
return new Version ();
}
var versionInfo = sb.ToString ();
// lint: version 26.0.2
var versionNumberMatch = lintVersionRegex.Match (versionInfo);
Version versionNumber;
if (versionNumberMatch.Success && Version.TryParse (versionNumberMatch.Groups ["version"]?.Value, out versionNumber)) {
return versionNumber;
}
return new Version ();
}
}
}