From a0fe8c08ba3c37ec9d149ee669e17b328308d750 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 8 Sep 2021 09:16:57 +0200 Subject: [PATCH] [msbuild] Add a public target/property to make customers able to add to the PartialAppManifest item group in their own targets. Fixes #12336. (#12645) Also add a test. Fixes https://github.com/xamarin/xamarin-macios/issues/12336 (for the second time). --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 9 ++- tests/common/DotNet.cs | 4 +- .../TargetTests/CollectAppManifestsTests.cs | 74 +++++++++++++++++++ .../TestHelpers/BuildEngine.cs | 5 +- 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 tests/msbuild/Xamarin.MacDev.Tests/TargetTests/CollectAppManifestsTests.cs diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index c9524815ab..b2e1237762 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -277,7 +277,8 @@ Copyright (C) 2018 Microsoft. All rights reserved. 1. The user can specify values in multiple ways: * An Info.plist in their project file (by using a `None` item with filename "Info.plist" or with a `Link` metadata with filename "Info.plist"). We figure this out in the DetectAppManifest target. - * A partial plist in their project (using the `PartialAppManifest` item group) + * A partial plist in their project (using the `PartialAppManifest` item group). Developers can add targets to the public CollectAppManifestsDependsOn + property to run targets that add to the `PartialAppManifest` item group before we process them. * Some MSBuild properties can also add values. The precedence is: MSBuild properties can be overridden by the Info.plist, which can be overridden by a partial plist. @@ -296,6 +297,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. <_CompileAppManifestDependsOn> + CollectAppManifests; $(_CompileAppManifestDependsOn); _DetectAppManifest; _DetectSdkLocations; @@ -305,6 +307,11 @@ Copyright (C) 2018 Microsoft. All rights reserved. + + + properties, bool assert_success = true) + public static ExecutionResult Execute (string verb, string project, Dictionary properties, bool assert_success = true, string target = null) { if (!File.Exists (project)) throw new FileNotFoundException ($"The project file '{project}' does not exist."); @@ -94,6 +94,8 @@ namespace Xamarin.Tests { } } } + if (!string.IsNullOrEmpty (target)) + args.Add ("/t:" + target); var binlogPath = Path.Combine (Path.GetDirectoryName (project), $"log-{verb}-{DateTime.Now:yyyyMMdd_HHmmss}.binlog"); args.Add ($"/bl:{binlogPath}"); var env = new Dictionary (); diff --git a/tests/msbuild/Xamarin.MacDev.Tests/TargetTests/CollectAppManifestsTests.cs b/tests/msbuild/Xamarin.MacDev.Tests/TargetTests/CollectAppManifestsTests.cs new file mode 100644 index 0000000000..f2bbe22aec --- /dev/null +++ b/tests/msbuild/Xamarin.MacDev.Tests/TargetTests/CollectAppManifestsTests.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Mono.Cecil; +using NUnit.Framework; +using Xamarin.MacDev; + +using Xamarin.Tests; +using Xamarin.Utils; + +namespace Xamarin.MacDev.Tasks { + [TestFixture] + public class CollectAppManifestsTests { + [Test] + public void PartialAppManifest () + { + var csproj = @" + + + net6.0-macos + Exe + + + $(CollectAppManifestsDependsOn); + AddPartialManifests; + + + + + + + + +"; + + var partialPList = @" + + + + CFBundleDisplayName + PartialAppManifestDisplayName + +"; + + var tmpdir = Cache.CreateTemporaryDirectory (); + Configuration.CopyDotNetSupportingFiles (tmpdir); + var csprojPath = Path.Combine (tmpdir, "PartialAppManifest.csproj"); + File.WriteAllText (csprojPath, csproj); + + // Create an empty main app manifest + var mainPListPath = Path.Combine (tmpdir, "Info.plist"); + new PDictionary ().Save (mainPListPath); + + // Save our custom partial app manifest + var partialPListPath = Path.Combine (tmpdir, "MyPartialManifest.plist"); + File.WriteAllText (partialPListPath, partialPList); + + var engine = new BuildEngine (); + var properties = new Dictionary { + { "_CreateAppManifest", "true" }, + }; + var rv = engine.RunTarget (ApplePlatform.MacOSX, ExecutionMode.DotNet, csprojPath, target: "_WriteAppManifest", properties: properties); + Assert.AreEqual (0, rv.ExitCode, "Exit code"); + + var appManifestPath = Path.Combine (tmpdir, "bin", "Debug", "net6.0-macos", "osx-x64", "PartialAppManifest.app", "Contents", "Info.plist"); + Assert.That (appManifestPath, Does.Exist, "App manifest existence"); + + var plist = PDictionary.FromFile (appManifestPath); + Assert.AreEqual ("PartialAppManifestDisplayName", plist.GetCFBundleDisplayName (), "Bundle display name"); + } + } +} + diff --git a/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs b/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs index 66b74bc863..67f9d447ec 100644 --- a/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs +++ b/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs @@ -55,7 +55,8 @@ namespace Xamarin.Tests { Console.WriteLine ($"Binlog: {rv.BinLogPath}"); - ParseBinLog (rv.BinLogPath); + if (File.Exists (rv.BinLogPath)) + ParseBinLog (rv.BinLogPath); return rv; } @@ -236,7 +237,7 @@ namespace Xamarin.Tests { static ExecutionResult Dotnet (string project, string command, string target, Dictionary properties) { - return DotNet.Execute (command, project, properties, assert_success: false); + return DotNet.Execute (command, project, properties, assert_success: false, target: target); } static ExecutionResult MSBuild (ApplePlatform platform, string project, string target, Dictionary properties)