Skip to content

Commit

Permalink
[AndroidToolTask] Log tool output as error (#229)
Browse files Browse the repository at this point in the history
Context: #208

Updates AndroidToolTask to capture all standard output from the tool and
log it as an error if the task fails.
  • Loading branch information
pjcollins authored Apr 19, 2024
1 parent c8a5b5b commit 1ea4e35
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 9 deletions.
17 changes: 16 additions & 1 deletion src/Microsoft.Android.Build.BaseTasks/AndroidToolTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

using System;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.Android.Build.Tasks
Expand All @@ -12,6 +14,8 @@ public abstract class AndroidToolTask : ToolTask

protected string WorkingDirectory { get; private set; }

StringBuilder toolOutput = new StringBuilder ();

public AndroidToolTask ()
{
WorkingDirectory = Directory.GetCurrentDirectory();
Expand All @@ -20,13 +24,24 @@ public AndroidToolTask ()
public override bool Execute ()
{
try {
return RunTask ();
bool taskResult = RunTask ();
if (!taskResult && !string.IsNullOrEmpty (toolOutput.ToString ())) {
Log.LogUnhandledToolError (TaskPrefix, toolOutput.ToString ().Trim ());
}
toolOutput.Clear ();
return taskResult;
} catch (Exception ex) {
Log.LogUnhandledException (TaskPrefix, ex);
return false;
}
}

protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance)
{
base.LogEventsFromTextOutput (singleLine, messageImportance);
toolOutput.AppendLine (singleLine);
}

// Most ToolTask's do not override Execute and
// just expect the base to be called
public virtual bool RunTask () => base.Execute ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,10 @@ static void LogUnhandledException (Action<string,string> logCodedError, string p
else
logCodedError (prefix + "7000", ex.ToString ());
}

public static void LogUnhandledToolError (this TaskLoggingHelper log, string prefix, string toolOutput)
{
log.LogCodedError ($"XA{prefix}0000", toolOutput);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Android.Build.BaseTasks.Tests.Utilities;
using Microsoft.Android.Build.Tasks;
using NUnit.Framework;
using Microsoft.Build.Framework;
using Xamarin.Build;
using NUnit.Framework.Internal;
using System.Linq;

namespace Microsoft.Android.Build.BaseTasks.Tests
{
[TestFixture]
public class AndroidToolTaskTests
{
public class MyAndroidTask : AndroidTask {
List<BuildErrorEventArgs> errors;
List<BuildWarningEventArgs> warnings;
List<BuildMessageEventArgs> messages;
MockBuildEngine engine;

public class MyAndroidTask : AndroidTask
{
public override string TaskPrefix {get;} = "MAT";
public string Key { get; set; }
public string Value { get; set; }
Expand All @@ -25,7 +31,8 @@ public override bool RunTask ()
}
}

public class MyOtherAndroidTask : AndroidTask {
public class MyOtherAndroidTask : AndroidTask
{
public override string TaskPrefix {get;} = "MOAT";
public string Key { get; set; }
public bool ProjectSpecific { get; set; } = false;
Expand All @@ -40,15 +47,31 @@ public override bool RunTask ()
}
}

public class DotnetToolOutputTestTask : AndroidToolTask
{
public override string TaskPrefix {get;} = "DTOT";
protected override string ToolName => "dotnet";
protected override string GenerateFullPathToTool () => ToolExe;
public string CommandLineArgs { get; set; } = "--info";
protected override string GenerateCommandLineCommands () => CommandLineArgs;
}

[SetUp]
public void TestSetup()
{
errors = new List<BuildErrorEventArgs> ();
warnings = new List<BuildWarningEventArgs> ();
messages = new List<BuildMessageEventArgs> ();
engine = new MockBuildEngine (TestContext.Out, errors, warnings, messages);
}

[Test]
[TestCase (true, true, true)]
[TestCase (false, false, true)]
[TestCase (true, false, false)]
[TestCase (false, true, false)]
public void TestRegisterTaskObjectCanRetrieveCorrectItem (bool projectSpecificA, bool projectSpecificB, bool expectedResult)
{
var engine = new MockBuildEngine (TestContext.Out) {
};
var task = new MyAndroidTask () {
BuildEngine = engine,
Key = "Foo",
Expand All @@ -72,8 +95,6 @@ public void TestRegisterTaskObjectCanRetrieveCorrectItem (bool projectSpecificA,
[TestCase (false, true, false)]
public void TestRegisterTaskObjectFailsWhenDirectoryChanges (bool projectSpecificA, bool projectSpecificB, bool expectedResult)
{
var engine = new MockBuildEngine (TestContext.Out) {
};
MyAndroidTask task;
var currentDir = Directory.GetCurrentDirectory ();
Directory.SetCurrentDirectory (Path.Combine (currentDir, ".."));