xamarin-macios/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ComputeCodesignItemsTaskTes...

502 строки
36 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using NUnit.Framework;
using Xamarin.iOS.Tasks;
using Xamarin.Utils;
#nullable enable
namespace Xamarin.MacDev.Tasks {
[TestFixture]
public class ComputeCodesignItemsTaskTests : TestBase {
[Test]
[TestCase (ApplePlatform.iOS, true)]
[TestCase (ApplePlatform.iOS, false)]
[TestCase (ApplePlatform.TVOS, true)]
[TestCase (ApplePlatform.TVOS, false)]
[TestCase (ApplePlatform.WatchOS, false)]
[TestCase (ApplePlatform.MacOSX, true)]
[TestCase (ApplePlatform.MacOSX, false)]
[TestCase (ApplePlatform.MacCatalyst, true)]
public void Compute (ApplePlatform platform, bool isDotNet)
{
var tmpdir = Cache.CreateTemporaryDirectory ();
var currentDir = Environment.CurrentDirectory;
try {
Environment.CurrentDirectory = tmpdir;
var codesignItems = new List<ITaskItem> ();
var codesignBundle = new List<ITaskItem> ();
var generateDSymItems = new List<ITaskItem> ();
var nativeStripItems = new List<ITaskItem> ();
string codeSignatureSubdirectory = string.Empty;
switch (platform) {
case ApplePlatform.MacCatalyst:
case ApplePlatform.MacOSX:
codeSignatureSubdirectory = "Contents/";
break;
}
var bundleAppMetadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "CompiledEntitlements.plist" },
{ "CodesignExtraArgs", "bundle-app-extra-args" },
{ "CodesignKeychain", "bundle-app-keychain" },
{ "CodesignResourceRules", "bundle-app-resource-rules" },
{ "CodesignSigningKey", "bundle-app-signing-key" },
{ "CodesignStampFile", "bundle-app-stamp-file" },
{ "CodesignUseHardenedRuntime", "bundle-app-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "bundle-app-use-secure-timestamp" },
{ "RequireCodeSigning", "true" },
};
var bundleAppMetadataNativeLibraries = new Dictionary<string, string> (bundleAppMetadata);
bundleAppMetadataNativeLibraries.Remove ("CodesignEntitlements");
var p1Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "p1.appex-entitlements" },
{ "CodesignExtraArgs", "p1.appex-extra-args" },
{ "CodesignKeychain", "p1.appex-keychain" },
{ "CodesignResourceRules", "p1.appex-resource-rules" },
{ "CodesignSigningKey", "" }, // empty code signing key
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "p1.appex-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "p1.appex-use-secure-timestamp" },
{ "RequireCodeSigning", "false" }, // don't require code signing
};
var p1MetadataNativeLibraries = new Dictionary<string, string> (p1Metadata);
p1MetadataNativeLibraries ["CodesignSigningKey"] = "-";
p1MetadataNativeLibraries ["CodesignStampFile"] = "_CodeSignature/CodeResources";
p1MetadataNativeLibraries.Remove ("CodesignEntitlements");
var p2Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "p2.appex-entitlements" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "p2.appex-extra-args" },
{ "CodesignKeychain", "p2.appex-keychain" },
{ "CodesignResourceRules", "p2.appex-resource-rules" },
{ "CodesignSigningKey", "p2.appex-signing-key" },
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "p2.appex-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "p2.appex-use-secure-timestamp" },
};
var p2MetadataNativeLibraries = new Dictionary<string, string> (p2Metadata);
p2MetadataNativeLibraries ["CodesignStampFile"] = "_CodeSignature/CodeResources";
p2MetadataNativeLibraries.Remove ("CodesignEntitlements");
var p3Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "p3.appex-entitlements" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "p3.appex-extra-args" },
{ "CodesignKeychain", "p3.appex-keychain" },
{ "CodesignResourceRules", "p3.appex-resource-rules" },
{ "CodesignSigningKey", "p3.appex-signing-key" },
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "p3.appex-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "p3.appex-use-secure-timestamp" },
};
var p3MetadataNativeLibraries = new Dictionary<string, string> (p3Metadata);
p3MetadataNativeLibraries ["CodesignStampFile"] = "_CodeSignature/CodeResources";
p3MetadataNativeLibraries.Remove ("CodesignEntitlements");
var w1Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "CompiledEntitlements.plist" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "bundle-app-extra-args" },
{ "CodesignKeychain", "bundle-app-keychain" },
{ "CodesignResourceRules", "bundle-app-resource-rules" },
{ "CodesignSigningKey", "bundle-app-signing-key" },
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "bundle-app-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "bundle-app-use-secure-timestamp" },
};
var w1MetadataNativeLibraries = new Dictionary<string, string> (w1Metadata);
w1MetadataNativeLibraries.Remove ("CodesignEntitlements");
var wp1Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "wp1.appex-entitlements" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "wp1.appex-extra-args" },
{ "CodesignKeychain", "wp1.appex-keychain" },
{ "CodesignResourceRules", "wp1.appex-resource-rules" },
{ "CodesignSigningKey", "" }, // empty code signing key
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "wp1.appex-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "wp1.appex-use-secure-timestamp" },
};
var wp1MetadataNativeLibraries = new Dictionary<string, string> (wp1Metadata);
wp1MetadataNativeLibraries ["CodesignSigningKey"] = "-";
wp1MetadataNativeLibraries ["CodesignStampFile"] = "_CodeSignature/CodeResources";
wp1MetadataNativeLibraries.Remove ("CodesignEntitlements");
var wp2Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "wp2.appex-entitlements" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "wp2.appex-extra-args" },
{ "CodesignKeychain", "wp2.appex-keychain" },
{ "CodesignResourceRules", "wp2.appex-resource-rules" },
{ "CodesignSigningKey", "wp2.appex-signing-key" },
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "wp2.appex-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "wp2.appex-use-secure-timestamp" },
};
var wp2MetadataNativeLibraries = new Dictionary<string, string> (wp2Metadata);
wp2MetadataNativeLibraries ["CodesignStampFile"] = "_CodeSignature/CodeResources";
wp2MetadataNativeLibraries.Remove ("CodesignEntitlements");
var wp3Metadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "wp3.appex-entitlements" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "wp3.appex-extra-args" },
{ "CodesignKeychain", "wp3.appex-keychain" },
{ "CodesignResourceRules", "wp3.appex-resource-rules" },
{ "CodesignSigningKey", "wp3.appex-signing-key" },
{ "CodesignStampFile", "" }, // empty stamp file
{ "CodesignUseHardenedRuntime", "wp3.appex-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "wp3.appex-use-secure-timestamp" },
};
var wp3MetadataNativeLibraries = new Dictionary<string, string> (wp3Metadata);
wp3MetadataNativeLibraries ["CodesignStampFile"] = "_CodeSignature/CodeResources";
wp3MetadataNativeLibraries.Remove ("CodesignEntitlements");
var createDumpMetadata = new Dictionary<string, string> {
{ "CodesignDisableTimestamp", "true" },
{ "CodesignEntitlements" , "createdump-entitlements" },
{ "RequireCodeSigning", "true" },
{ "CodesignExtraArgs", "createdump-extra-args" },
{ "CodesignKeychain", "createdump-keychain" },
{ "CodesignResourceRules", "createdump-resource-rules" },
{ "CodesignSigningKey", "createdump-signing-key" },
{ "CodesignStampFile", "createdump-stamp-file" },
{ "CodesignUseHardenedRuntime", "createdump-use-hardened-runtime" },
{ "CodesignUseSecureTimestamp", "createdump-use-secure-timestamp" },
};
codesignItems = new List<ITaskItem> {
new TaskItem ("Bundle.app/Contents/MonoBundle/createdump", createDumpMetadata),
};
codesignBundle = new List<ITaskItem> {
new TaskItem ("Bundle.app", bundleAppMetadata),
new TaskItem ("Bundle.app/PlugIns/P1.appex", p1Metadata),
new TaskItem ("Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex", p2Metadata),
new TaskItem ("Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/PlugIns/P3.appex", p3Metadata),
new TaskItem ("Bundle.app/Watch/W1.app", w1Metadata),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex", wp1Metadata),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex", wp2Metadata),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex", wp3Metadata),
};
nativeStripItems = new List<ITaskItem> {
new TaskItem ("Bundle.app/Bundle", new Dictionary<string, string> { { "StripStampFile", "bundle-strip-stamp-file" } } ),
new TaskItem ("Bundle.app/PlugIns/P1.appex/P1"),
new TaskItem ("Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/P2"),
new TaskItem ("Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/PlugIns/P3.appex/P3", new Dictionary<string, string> { { "StripStampFile", "p3-strip-stamp-file" } } ),
new TaskItem ("Bundle.app/Watch/W1.app/W1"),
new TaskItem ("Bundle.app/Watch/W1W1app/PlugIns/WP1.appex/WP1"),
new TaskItem ("Bundle.app/Watch/Watch.app/PlugIns/WP1.appex/PlugIns/WP2.appex/WP2"),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/WP3", new Dictionary<string, string> { { "StripStampFile", "wp3-strip-stamp-file" } } ),
};
generateDSymItems = new List<ITaskItem> {
new TaskItem ("Bundle.app/Bundle", new Dictionary<string, string> { { "dSYMUtilStampFile", "Bundle.app.dSYM/Contents/Info.plist" } } ),
new TaskItem ("Bundle.app/PlugIns/P1.appex/P1", new Dictionary<string, string> { { "dSYMUtilStampFile", "P1.appex.dSYM/Contents/Info.plist" } }),
new TaskItem ("Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/P2", new Dictionary<string, string> { { "dSYMUtilStampFile", "P2.appex.dSYM/Contents/Info.plist" } }),
new TaskItem ("Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/PlugIns/P3.appex/P3", new Dictionary<string, string> { { "dSYMUtilStampFile", "P3.appex.dSYM/Contents/Info.plist" } }),
new TaskItem ("Bundle.app/Watch/W1.app/W1", new Dictionary<string, string> { { "dSYMUtilStampFile", "W1.app.dSYM/Contents/Info.plist" } }),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/WP1", new Dictionary<string, string> { { "dSYMUtilStampFile", "WP1.appex.dSYM/Contents/Info.plist" } }),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/WP2", new Dictionary<string, string> { { "dSYMUtilStampFile", "WP2.appex.dSYM/Contents/Info.plist" } }),
new TaskItem ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/WP3", new Dictionary<string, string> { { "dSYMUtilStampFile", "WP3.appex.dSYM/Contents/Info.plist" } }),
};
var infos = new CodesignInfo [] {
new CodesignInfo ("Bundle.app", Platforms.All, bundleAppMetadata.Set ("CodesignAdditionalFilesToTouch", "Bundle.app.dSYM/Contents/Info.plist;bundle-strip-stamp-file")),
new CodesignInfo ("Bundle.app/a.dylib", Platforms.Mobile, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/a.dylib")),
new CodesignInfo ("Bundle.app/Contents/b.dylib", Platforms.All, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/b.dylib")),
new CodesignInfo ("Bundle.app/Contents/MonoBundle/c.dylib", Platforms.All, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/MonoBundle/c.dylib")),
new CodesignInfo ("Bundle.app/Contents/MonoBundle/SubDir/d.dylib", Platforms.All, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/MonoBundle/SubDir/d.dylib")),
new CodesignInfo ("Bundle.app/M1.metallib", Platforms.Mobile, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/M1.metallib")),
new CodesignInfo ("Bundle.app/Resources/M2.metallib", Platforms.Mobile, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Resources/M2.metallib")),
new CodesignInfo ("Bundle.app/Contents/Resources/M3.metallib", Platforms.All, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/Resources/M3.metallib")),
new CodesignInfo ("Bundle.app/Contents/Resources/SubDir/M4.metallib", Platforms.All, bundleAppMetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/Resources/SubDir/M4.metallib")),
new CodesignInfo (
"Bundle.app/PlugIns/P1.appex",
Platforms.None,
p1Metadata.
Set ("CodesignStampFile", $"Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/{codeSignatureSubdirectory}_CodeSignature/CodeResources")
),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/P1a.dylib", Platforms.Mobile, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/P1a.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/Contents/P1b.dylib", Platforms.All, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/Contents/P1b.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/Contents/MonoBundle/P1c.dylib", Platforms.All, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/Contents/MonoBundle/P1c.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/Contents/MonoBundle/SubDir/P1d.dylib", Platforms.All, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/Contents/MonoBundle/SubDir/P1d.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/PM1.metallib", Platforms.Mobile, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/PM1.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/Resources/PM2.metallib", Platforms.Mobile, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/Resources/PM2.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/Contents/Resources/PM3.metallib", Platforms.All, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/Contents/Resources/PM3.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/Contents/Resources/SubDir/PM4.metallib", Platforms.All, p1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/Contents/Resources/SubDir/PM4.metallib")),
new CodesignInfo (
"Bundle.app/PlugIns/P1.appex/plugins/P2.appex",
Platforms.All,
p2Metadata.
Set ("CodesignStampFile", $"Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/{codeSignatureSubdirectory}_CodeSignature/CodeResources").
Set ("CodesignAdditionalFilesToTouch", "P2.appex.dSYM/Contents/Info.plist")
),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/P2a.dylib", Platforms.Mobile, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/P2a.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/P2b.dylib", Platforms.All, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/P2b.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/MonoBundle/P2c.dylib", Platforms.All, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/MonoBundle/P2c.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/MonoBundle/SubDir/P2d.dylib", Platforms.All, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/MonoBundle/SubDir/P2d.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/P2M1.metallib", Platforms.Mobile, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/P2M1.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Resources/P2M2.metallib", Platforms.Mobile, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Resources/P2M2.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/Resources/P2M3.metallib", Platforms.All, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/Resources/P2M3.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/Resources/SubDir/P2M4.metallib", Platforms.All, p2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/Contents/Resources/SubDir/P2M4.metallib")),
new CodesignInfo (
"Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex",
Platforms.All,
p3Metadata.
Set ("CodesignStampFile", $"Bundle.app/PlugIns/P1.appex/PlugIns/P2.appex/PlugIns/P3.appex/{codeSignatureSubdirectory}_CodeSignature/CodeResources").
Set ("CodesignAdditionalFilesToTouch", "P3.appex.dSYM/Contents/Info.plist;p3-strip-stamp-file")
),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/P3a.dylib", Platforms.Mobile, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/P3a.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/P3b.dylib", Platforms.All, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/P3b.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/MonoBundle/P3c.dylib", Platforms.All, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/MonoBundle/P3c.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/MonoBundle/SubDir/P3d.dylib", Platforms.All, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/MonoBundle/SubDir/P3d.dylib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/P3M1.metallib", Platforms.Mobile, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/P3M1.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Resources/P3M2.metallib", Platforms.Mobile, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Resources/P3M2.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/Resources/P3M3.metallib", Platforms.All, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/Resources/P3M3.metallib")),
new CodesignInfo ("Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/Resources/SubDir/P3M4.metallib", Platforms.All, p3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/PlugIns/P1.appex/plugins/P2.appex/PlugIns/P3.appex/Contents/Resources/SubDir/P3M4.metallib")),
new CodesignInfo (
"Bundle.app/Watch/W1.app",
Platforms.All,
w1Metadata.
Set ("CodesignStampFile", $"Bundle.app/Watch/W1.app/{codeSignatureSubdirectory}_CodeSignature/CodeResources").
Set ("CodesignAdditionalFilesToTouch", "W1.app.dSYM/Contents/Info.plist")
),
new CodesignInfo ("Bundle.app/Watch/W1.app/Contents/b.dylib", Platforms.All, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/Contents/b.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/Contents/MonoBundle/c.dylib", Platforms.All, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/Contents/MonoBundle/c.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/Contents/MonoBundle/SubDir/d.dylib", Platforms.All, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/Contents/MonoBundle/SubDir/d.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/W1M1.metallib", Platforms.Mobile, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/W1M1.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/Resources/W1M2.metallib", Platforms.Mobile, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/Resources/W1M2.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/Contents/Resources/W1M3.metallib", Platforms.All, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/Contents/Resources/W1M3.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/Contents/Resources/SubDir/W1M4.metallib", Platforms.All, w1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/Contents/Resources/SubDir/W1M4.metallib")),
new CodesignInfo (
"Bundle.app/Watch/W1.app/PlugIns/WP1.appex",
Platforms.All,
wp1Metadata.
Set ("CodesignStampFile", $"Bundle.app/Watch/W1.app/PlugIns/WP1.appex/{codeSignatureSubdirectory}_CodeSignature/CodeResources").
Set ("CodesignAdditionalFilesToTouch", "WP1.appex.dSYM/Contents/Info.plist")
),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/W1a.dylib", Platforms.Mobile, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/W1a.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/W1b.dylib", Platforms.All, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/W1b.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/MonoBundle/W1c.dylib", Platforms.All, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/MonoBundle/W1c.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/MonoBundle/SubDir/W1d.dylib", Platforms.All, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/MonoBundle/SubDir/W1d.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/W1M1.metallib", Platforms.Mobile, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/W1M1.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Resources/W1M2.metallib", Platforms.Mobile, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Resources/W1M2.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/Resources/W1M3.metallib", Platforms.All, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/Resources/W1M3.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/Resources/SubDir/W1M4.metallib", Platforms.All, wp1MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/Contents/Resources/SubDir/W1M4.metallib")),
new CodesignInfo (
"Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex",
Platforms.All,
wp2Metadata.
Set ("CodesignStampFile", $"Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/{codeSignatureSubdirectory}_CodeSignature/CodeResources").
Set ("CodesignAdditionalFilesToTouch", "WP2.appex.dSYM/Contents/Info.plist")
),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/W2a.dylib", Platforms.Mobile, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/W2a.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/W2b.dylib", Platforms.All, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/W2b.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/MonoBundle/W2c.dylib", Platforms.All, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/MonoBundle/W2c.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/MonoBundle/SubDir/W2c.dylib", Platforms.All, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/MonoBundle/SubDir/W2c.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/W2M1.metallib", Platforms.Mobile, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/W2M1.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Resources/W2M2.metallib", Platforms.Mobile, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Resources/W2M2.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/Resources/W2M3.metallib", Platforms.All, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/Resources/W2M3.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/Resources/SubDir/W2M4.metallib", Platforms.All, wp2MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/Contents/Resources/SubDir/W2M4.metallib")),
new CodesignInfo (
"Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex",
Platforms.All,
wp3Metadata.
Set ("CodesignStampFile", $"Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/{codeSignatureSubdirectory}_CodeSignature/CodeResources").
Set ("CodesignAdditionalFilesToTouch", "WP3.appex.dSYM/Contents/Info.plist;wp3-strip-stamp-file")
),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/W3a.dylib", Platforms.Mobile, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/W3a.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/W3b.dylib", Platforms.All, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/W3b.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/MonoBundle/W3c.dylib", Platforms.All, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/MonoBundle/W3c.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/MonoBundle/SubDir/W3c.dylib", Platforms.All, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/MonoBundle/SubDir/W3c.dylib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/W3M1.metallib", Platforms.Mobile, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/W3M1.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Resources/W3M2.metallib", Platforms.Mobile, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Resources/W3M2.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/Resources/W3M3.metallib", Platforms.All, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/Resources/W3M3.metallib")),
new CodesignInfo ("Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/Resources/SubDir/W3M4.metallib", Platforms.All, wp3MetadataNativeLibraries.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Watch/W1.app/PlugIns/WP1.appex/PlugIns/WP2.appex/PlugIns/WP3.appex/Contents/Resources/SubDir/W3M4.metallib")),
new CodesignInfo ("Bundle.app/Contents/MonoBundle/createdump", Platforms.All, createDumpMetadata),
};
var allFiles = infos.Select (v => v.ItemSpec).ToArray ();
Touch (tmpdir, allFiles);
var task = CreateTask<ComputeCodesignItems> ();
task.AppBundleDir = "Bundle.app";
task.CodesignBundle = codesignBundle.ToArray ();
task.CodesignItems = codesignItems.ToArray ();
task.CodesignStampPath = "codesign-stamp-path/";
task.GenerateDSymItems = generateDSymItems.ToArray ();
task.NativeStripItems = nativeStripItems.ToArray ();
task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, isDotNet).ToString ();
Assert.IsTrue (task.Execute (), "Execute");
var outputCodesignItems = task.OutputCodesignItems;
Assert.That (outputCodesignItems.Select (v => v.ItemSpec), Is.Unique, "Uniqueness");
var failures = new List<string> ();
var itemsFound = new List<ITaskItem> ();
foreach (var info in infos) {
var item = outputCodesignItems.SingleOrDefault (v => string.Equals (v.ItemSpec, info.ItemSpec, StringComparison.OrdinalIgnoreCase));
info.CodesignItem = item;
if (IsPlatform (info.SignedOn, platform)) {
if (item is null) {
failures.Add ($"Expected '{info.ItemSpec}' to be signed.");
continue;
}
} else {
if (item is not null) {
failures.Add ($"Did not expect '{info.ItemSpec}' to be signed.");
continue;
}
}
if (item is null)
continue;
itemsFound.Add (item);
foreach (var kvp in info.Metadata) {
var metadata = item.GetMetadata (kvp.Key);
if (metadata == string.Empty && kvp.Value != string.Empty) {
failures.Add ($"Item '{info.ItemSpec}': Expected metadata '{kvp.Key}' not found (with value '{kvp.Value}').");
} else if (!string.Equals (metadata, kvp.Value)) {
failures.Add ($"Item '{info.ItemSpec}': Expected value '{kvp.Value}' for metadata '{kvp.Key}', but got '{metadata}' instead.\nExpected: {kvp.Value}\nActual: {metadata}");
}
}
var customMetadata = item.CopyCustomMetadata ();
var unexpectedMetadata = customMetadata.Keys.ToHashSet ();
unexpectedMetadata.ExceptWith (info.Metadata.Keys);
unexpectedMetadata.Remove ("OriginalItemSpec");
foreach (var unexpected in unexpectedMetadata) {
if (string.IsNullOrEmpty (customMetadata [unexpected]))
continue;
failures.Add ($"Item '{info.ItemSpec}': Unexpected metadata '{unexpected}' with value '{customMetadata [unexpected]}'.");
}
}
var itemsNotFound = outputCodesignItems.Where (v => !itemsFound.Contains (v)).ToArray ();
foreach (var itemNotFound in itemsNotFound) {
failures.Add ($"Did not expect '{itemNotFound.ItemSpec}' to be signed.");
}
if (failures.Count > 0) {
Console.WriteLine ($"{failures.Count} failures");
foreach (var f in failures)
Console.WriteLine (f);
Console.WriteLine ($"{failures.Count} failures");
}
Assert.That (failures, Is.Empty, "Failures");
} finally {
Environment.CurrentDirectory = currentDir;
}
}
bool IsPlatform (Platforms platforms, ApplePlatform platform)
{
switch (platform) {
case ApplePlatform.iOS:
return (platforms & Platforms.iOS) == Platforms.iOS;
case ApplePlatform.TVOS:
return (platforms & Platforms.tvOS) == Platforms.tvOS;
case ApplePlatform.MacOSX:
return (platforms & Platforms.macOS) == Platforms.macOS;
case ApplePlatform.WatchOS:
return (platforms & Platforms.watchOS) == Platforms.watchOS;
case ApplePlatform.MacCatalyst:
return (platforms & Platforms.MacCatalyst) == Platforms.MacCatalyst;
default:
throw new NotImplementedException ();
}
}
void Touch (string root, params string [] files)
{
foreach (var f in files) {
var file = Path.Combine (root, f);
if (file.EndsWith (".appex", StringComparison.OrdinalIgnoreCase) || file.EndsWith (".app", StringComparison.OrdinalIgnoreCase)) {
Directory.CreateDirectory (f);
} else {
Directory.CreateDirectory (Path.GetDirectoryName (file));
File.WriteAllText (file, string.Empty);
}
}
}
class CodesignInfo {
public string ItemSpec;
public Platforms SignedOn;
public Dictionary<string, string> Metadata;
public ITaskItem? CodesignItem;
public CodesignInfo (string item, Platforms signedOn, Dictionary<string, string>? metadata = null)
{
ItemSpec = item;
SignedOn = signedOn;
Metadata = metadata ?? new Dictionary<string, string> ();
}
}
// As opposed to ApplePlatform, this enum is a bitfield, and can represent multiple platforms in a single value.
[Flags]
enum Platforms {
None = 0,
iOS = 1,
tvOS = 2,
watchOS = 4,
macOS = 8,
MacCatalyst = 16,
Mobile = iOS | tvOS | watchOS,
Desktop = macOS | MacCatalyst,
All = Mobile | Desktop,
}
}
public static class Dictionary_Extensions {
public static Dictionary<string, string> Set (this Dictionary<string, string> self, string key, string value)
{
var rv = new Dictionary<string, string> (self);
rv [key] = value;
return rv;
}
}
public static class ITaskItem_Extensions {
public static Dictionary<string, string> CopyCustomMetadata (this ITaskItem self)
{
var rv = new Dictionary<string, string> ();
foreach (DictionaryEntry de in self.CloneCustomMetadata ()) {
rv [(string) de.Key] = (string) de.Value;
}
return rv;
}
}
}