[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).
This commit is contained in:
Rolf Bjarne Kvinge 2021-09-08 09:16:57 +02:00 коммит произвёл GitHub
Родитель 1542039f22
Коммит a0fe8c08ba
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 88 добавлений и 4 удалений

Просмотреть файл

@ -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.
<PropertyGroup>
<_CompileAppManifestDependsOn>
CollectAppManifests;
$(_CompileAppManifestDependsOn);
_DetectAppManifest;
_DetectSdkLocations;
@ -305,6 +307,11 @@ Copyright (C) 2018 Microsoft. All rights reserved.
</_CompileAppManifestDependsOn>
</PropertyGroup>
<!-- This is a public target that collects all the (partial) app manifests. The recommended way to make sure all
the desired entries are added to PartialAppManifest is to add the target that adds to PartialAppManifest
to the CollectAppManifestsDependsOn property. -->
<Target Name="CollectAppManifests" DependsOnTargets="$(CollectAppManifestsDependsOn)" />
<!-- This target has no inputs, because it must still be run if there are no input app manifests, to set default values -->
<Target Name="_CompileAppManifest"
DependsOnTargets="$(_CompileAppManifestDependsOn)"

Просмотреть файл

@ -66,7 +66,7 @@ namespace Xamarin.Tests {
};
}
public static ExecutionResult Execute (string verb, string project, Dictionary<string, string> properties, bool assert_success = true)
public static ExecutionResult Execute (string verb, string project, Dictionary<string, string> 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<string, string> ();

Просмотреть файл

@ -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 = @"<?xml version=""1.0"" encoding=""utf-8""?>
<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<TargetFramework>net6.0-macos</TargetFramework>
<OutputType>Exe</OutputType>
<CollectAppManifestsDependsOn>
$(CollectAppManifestsDependsOn);
AddPartialManifests;
</CollectAppManifestsDependsOn>
</PropertyGroup>
<Target Name=""AddPartialManifests"">
<ItemGroup>
<PartialAppManifest Include=""MyPartialManifest.plist"" />
</ItemGroup>
</Target>
</Project>";
var partialPList = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">
<plist version=""1.0"">
<dict>
<key>CFBundleDisplayName</key>
<string>PartialAppManifestDisplayName</string>
</dict>
</plist>";
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<string, string> {
{ "_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");
}
}
}

Просмотреть файл

@ -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<string, string> 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<string, string> properties)