diff --git a/docs/build-apps/build-properties.md b/docs/build-apps/build-properties.md index f7544d71943..e83b81c7a28 100644 --- a/docs/build-apps/build-properties.md +++ b/docs/build-apps/build-properties.md @@ -11,6 +11,12 @@ MSBuild properties control the behavior of the They're specified within the project file, for example **MyApp.csproj**, within an MSBuild PropertyGroup. +## AltoolPath + +The full path to the `altool` tool. + +The default behavior is to use `xcrun altool`. + ## AppIcon The `AppIcon` item group can be used to specify an app icon for the app. diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolUpload.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolUpload.cs index 68198b11951..fe4d94d86c3 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolUpload.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolUpload.cs @@ -1,24 +1,7 @@ -using Microsoft.Build.Framework; -using Xamarin.Messaging.Build.Client; +#nullable enable namespace Xamarin.MacDev.Tasks { - public class ALToolUpload : ALToolTaskBase, ICancelableTask { + public class ALToolUpload : ALToolTaskBase { protected override string ALToolAction => "--upload-app"; - - public override bool Execute () - { - if (ShouldExecuteRemotely ()) - return new TaskRunner (SessionId, BuildEngine4).RunAsync (this).Result; - - return base.Execute (); - } - - public override void Cancel () - { - if (ShouldExecuteRemotely ()) - BuildConnection.CancelAsync (BuildEngine4).Wait (); - - base.Cancel (); - } } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolValidate.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolValidate.cs index 0175e3f293b..122d2fc1096 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolValidate.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ALToolValidate.cs @@ -1,24 +1,7 @@ -using Microsoft.Build.Framework; -using Xamarin.Messaging.Build.Client; +#nullable enable namespace Xamarin.MacDev.Tasks { - public class ALToolValidate : ALToolTaskBase, ICancelableTask { + public class ALToolValidate : ALToolTaskBase { protected override string ALToolAction => "--validate-app"; - - public override bool Execute () - { - if (ShouldExecuteRemotely ()) - return new TaskRunner (SessionId, BuildEngine4).RunAsync (this).Result; - - return base.Execute (); - } - - public override void Cancel () - { - if (ShouldExecuteRemotely ()) - BuildConnection.CancelAsync (BuildEngine4).Wait (); - - base.Cancel (); - } } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs index 7950453d6b6..3d161d60e3b 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Build.Utilities; using Microsoft.Build.Framework; @@ -7,86 +10,71 @@ using Xamarin.Utils; using Xamarin.Localization.MSBuild; - -// Disable until we get around to enable + fix any issues. -#nullable disable +using Xamarin.Messaging.Build.Client; namespace Xamarin.MacDev.Tasks { - public abstract class ALToolTaskBase : XamarinToolTask { - string sdkDevPath; - StringBuilder toolOutput; + public abstract class ALToolTaskBase : XamarinTask, ICancelableTask { + CancellationTokenSource? cancellationTokenSource; - [Required] - public string Username { get; set; } + public string AltoolPath { get; set; } = string.Empty; [Required] - public string Password { get; set; } + public string Username { get; set; } = string.Empty; [Required] - public string FilePath { get; set; } - - protected override string ToolName { - get { return "altool"; } - } + public string Password { get; set; } = string.Empty; [Required] - public string SdkDevPath { - get { return sdkDevPath; } - set { - sdkDevPath = value; + public string FilePath { get; set; } = string.Empty; + + static string GetExecutable (List arguments, string toolName, string toolPathOverride) + { + if (string.IsNullOrEmpty (toolPathOverride)) { + arguments.Insert (0, toolName); + return "xcrun"; } + return toolPathOverride; } - string DevicePlatformBinDir { - get { return Path.Combine (SdkDevPath, "usr", "bin"); } - } + [Required] + public string SdkDevPath { get; set; } = string.Empty; protected abstract string ALToolAction { get; } public override bool Execute () { - toolOutput = new StringBuilder (); + if (ShouldExecuteRemotely ()) + return new TaskRunner (SessionId, BuildEngine4).RunAsync (this).Result; - base.Execute (); + var args = GenerateCommandLineCommands (); + var executable = GetExecutable (args, "altool", AltoolPath); - LogErrorsFromOutput (toolOutput.ToString ()); + if (Log.HasLoggedErrors) + return false; - return !HasLoggedErrors; + cancellationTokenSource = new CancellationTokenSource (); + var rv = ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Result; + LogErrorsFromOutput (rv.StandardOutput?.ToString ()); + return !Log.HasLoggedErrors; } - protected override string GenerateFullPathToTool () + protected virtual List GenerateCommandLineCommands () { - if (!string.IsNullOrEmpty (ToolPath)) - return Path.Combine (ToolPath, ToolExe); - - var path = Path.Combine (DevicePlatformBinDir, ToolExe); - - return File.Exists (path) ? path : ToolExe; - } - - protected override string GenerateCommandLineCommands () - { - var args = new CommandLineArgumentBuilder (); + var args = new List (); args.Add (ALToolAction); args.Add ("--file"); - args.AddQuoted (FilePath); + args.Add (FilePath); args.Add ("--type"); - args.AddQuoted (GetFileTypeValue ()); + args.Add (GetFileTypeValue ()); args.Add ("--username"); - args.AddQuoted (Username); + args.Add (Username); args.Add ("--password"); - args.AddQuoted (Password); + args.Add (Password); args.Add ("--output-format"); args.Add ("xml"); - return args.ToString (); - } - - protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance) - { - toolOutput.Append (singleLine); - Log.LogMessage (messageImportance, "{0}", singleLine); + return args; } string GetFileTypeValue () @@ -99,11 +87,16 @@ string GetFileTypeValue () } } - void LogErrorsFromOutput (string output) + void LogErrorsFromOutput (string? output) { try { +#if NET if (string.IsNullOrEmpty (output)) return; +#else + if (output is null || string.IsNullOrEmpty (output)) + return; +#endif var plist = PObject.FromString (output) as PDictionary; var errors = PObject.Create (PObjectType.Array) as PArray; @@ -113,7 +106,7 @@ void LogErrorsFromOutput (string output) foreach (var error in errors) { var dict = error as PDictionary; if (dict?.TryGetValue ("message", out message) == true) { - Log.LogError (ToolName, null, null, null, 0, 0, 0, 0, "{0}", message.Value); + Log.LogError ("altool", null, null, null, 0, 0, 0, 0, "{0}", message.Value); } } } @@ -121,5 +114,14 @@ void LogErrorsFromOutput (string output) Log.LogWarning (MSBStrings.W0095, ex.Message, output); } } + + public void Cancel () + { + if (ShouldExecuteRemotely ()) { + BuildConnection.CancelAsync (BuildEngine4).Wait (); + } else { + cancellationTokenSource?.Cancel (); + } + } } } diff --git a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets index 26c184774f0..d31364f2eac 100644 --- a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets @@ -94,6 +94,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.