SkiaSharp/cake/UtilsManaged.cake

339 строки
13 KiB
C#

void PackageNuGet(FilePath nuspecPath, DirectoryPath outputPath, bool allowDefaultExcludes = false)
{
EnsureDirectoryExists(outputPath);
var settings = new NuGetPackSettings {
OutputDirectory = MakeAbsolute(outputPath),
BasePath = nuspecPath.GetDirectory(),
Properties = new Dictionary<string, string> {
// NU5048: The 'PackageIconUrl'/'iconUrl' element is deprecated. Consider using the 'PackageIcon'/'icon' element instead.
// NU5105: The package version 'xxx' uses SemVer 2.0.0 or components of SemVer 1.0.0 that are not supported on legacy clients.
// NU5125: The 'licenseUrl' element will be deprecated. Consider using the 'license' element instead.
{ "NoWarn", "NU5048,NU5105,NU5125" }
},
};
if (allowDefaultExcludes) {
settings.ArgumentCustomization = args => args.Append("-NoDefaultExcludes");
}
NuGetPack(nuspecPath, settings);
}
void RunTests(FilePath testAssembly, bool is32)
{
var dir = testAssembly.GetDirectory();
var settings = new XUnit2Settings {
ReportName = "TestResults",
XmlReport = true,
UseX86 = is32,
NoAppDomain = true,
Parallelism = ParallelismOption.All,
OutputDirectory = dir,
WorkingDirectory = dir,
ArgumentCustomization = args => args.Append("-verbose"),
};
var traits = CreateTraitsDictionary(UNSUPPORTED_TESTS);
foreach (var trait in traits) {
settings.ExcludeTrait(trait.Name, trait.Value);
}
XUnit2(new [] { testAssembly }, settings);
}
void RunNetCoreTests(FilePath testAssembly)
{
var dir = testAssembly.GetDirectory();
var buildSettings = new DotNetCoreBuildSettings {
Configuration = CONFIGURATION,
WorkingDirectory = dir,
};
DotNetCoreBuild(testAssembly.GetFilename().ToString(), buildSettings);
var settings = new DotNetCoreTestSettings {
Configuration = CONFIGURATION,
NoBuild = true,
TestAdapterPath = ".",
Loggers = new [] { "xunit" },
WorkingDirectory = dir,
Verbosity = DotNetCoreVerbosity.Normal,
ArgumentCustomization = args => {
if (COVERAGE)
args = args
.Append("/p:CollectCoverage=true")
.Append("/p:CoverletOutputFormat=cobertura")
.Append("/p:CoverletOutput=Coverage/");
return args;
},
};
var traits = CreateTraitsDictionary(UNSUPPORTED_TESTS);
var filter = string.Join("&", traits.Select(t => $"{t.Name}!={t.Value}"));
if (!string.IsNullOrEmpty(filter)) {
settings.Filter = filter;
}
DotNetCoreTest(testAssembly.GetFilename().ToString(), settings);
}
void RunNetCorePublish(FilePath testProject, DirectoryPath output)
{
var dir = testProject.GetDirectory();
var settings = new DotNetCorePublishSettings {
Configuration = CONFIGURATION,
NoBuild = true,
WorkingDirectory = dir,
OutputDirectory = output,
};
DotNetCorePublish(testProject.GetFilename().ToString(), settings);
}
void RunCodeCoverage(string testResultsGlob, DirectoryPath output)
{
try {
RunProcess("reportgenerator", new ProcessSettings {
Arguments =
$"-reports:{testResultsGlob} " +
$"-targetdir:{output} " +
$"-reporttypes:HtmlInline_AzurePipelines;Cobertura " +
$"-assemblyfilters:-*.Tests"
});
} catch (Exception ex) {
Error("Make sure to install the 'dotnet-reportgenerator-globaltool' .NET Core global tool.");
Error(ex);
throw;
}
var xml = $"{output}/Cobertura.xml";
var root = FindRegexMatchGroupsInFile(xml, @"<source>(.*)<\/source>", 0)[1].Value;
ReplaceTextInFiles(xml, root, "");
}
IEnumerable<(string Name, string Value)> CreateTraitsDictionary(string args)
{
if (!string.IsNullOrEmpty(args)) {
var traits = args.Split(';');
foreach (var trait in traits) {
var kv = trait.Split('=');
if (kv.Length != 2)
continue;
yield return (kv[0], kv[1]);
}
}
}
void DecompressArchive(FilePath archive, DirectoryPath outputDir)
{
using (var stream = System.IO.File.OpenRead(archive.FullPath))
using (var reader = ReaderFactory.Open(stream)) {
while(reader.MoveToNextEntry()) {
if (!reader.Entry.IsDirectory) {
reader.WriteEntryToDirectory(outputDir.FullPath, new ExtractionOptions {
ExtractFullPath = true,
Overwrite = true
});
}
}
}
}
IEnumerable<(DirectoryPath path, string platform)> GetPlatformDirectories(DirectoryPath rootDir)
{
var platformDirs = GetDirectories($"{rootDir}/*");
// try find any cross-platform frameworks
foreach (var dir in platformDirs) {
var d = dir.GetDirectoryName().ToLower();
if (d.StartsWith("netstandard") || d.StartsWith("portable") || d.Equals("net6.0")) {
// we just want this single platform
yield return (dir, null);
yield break;
}
}
// there were no cross-platform libraries, so process each platform
foreach (var dir in platformDirs) {
var d = dir.GetDirectoryName().ToLower();
if (d.StartsWith("monoandroid") || (d.StartsWith("net") && d.Contains("-android")))
yield return (dir, "android");
else if (d.StartsWith("net4"))
yield return (dir, "net");
else if (d.StartsWith("uap"))
yield return (dir, "uwp");
else if (d.StartsWith("xamarinios") || d.StartsWith("xamarin.ios") || (d.StartsWith("net") && d.Contains("-ios")))
yield return (dir, "ios");
else if (d.StartsWith("xamarinmac") || d.StartsWith("xamarin.mac") || (d.StartsWith("net") && d.Contains("-macos")))
yield return (dir, "macos");
else if (d.StartsWith("xamarintvos") || d.StartsWith("xamarin.tvos") || (d.StartsWith("net") && d.Contains("-tvos")))
yield return (dir, "tvos");
else if (d.StartsWith("xamarinwatchos") || d.StartsWith("xamarin.watchos") || (d.StartsWith("net") && d.Contains("-watchos")))
yield return (dir, "watchos");
else if (d.StartsWith("tizen") || (d.StartsWith("net") && d.Contains("-tizen")))
yield return (dir, "tizen");
else if (d.StartsWith("net") && d.Contains("-windows"))
yield return (dir, "windows");
else if (d.StartsWith("net") && d.Contains("-maccatalyst"))
yield return (dir, "maccatalyst");
else if (d.StartsWith("netcoreapp"))
continue; // skip this one for now
else
throw new Exception($"Unknown platform '{d}' found at '{dir}'.");
}
}
string[] GetReferenceSearchPaths()
{
var refs = new List<string>();
if (IsRunningOnWindows()) {
var vs = VS_INSTALL ?? VSWhereLatest(new VSWhereLatestSettings { Requires = "Component.Xamarin" });
var referenceAssemblies = $"{vs}/Common7/IDE/ReferenceAssemblies/Microsoft/Framework";
var pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
refs.AddRange(GetDirectories("./output/docs/temp/*").Select(d => d.FullPath));
refs.Add($"{referenceAssemblies}/MonoTouch/v1.0");
refs.Add($"{referenceAssemblies}/MonoAndroid/v1.0");
refs.Add($"{referenceAssemblies}/MonoAndroid/v9.0");
refs.Add($"{referenceAssemblies}/Xamarin.iOS/v1.0");
refs.Add($"{referenceAssemblies}/Xamarin.TVOS/v1.0");
refs.Add($"{referenceAssemblies}/Xamarin.WatchOS/v1.0");
refs.Add($"{referenceAssemblies}/Xamarin.Mac/v2.0");
refs.Add($"{pf}/Windows Kits/10/UnionMetadata/Facade");
refs.Add($"{pf}/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0");
refs.Add($"{pf}/Windows Kits/10/References/Windows.Foundation.FoundationContract/1.0.0.0");
refs.Add($"{pf}/GtkSharp/2.12/lib");
refs.Add($"{pf}/GtkSharp/2.12/lib/gtk-sharp-2.0");
refs.Add($"{vs}/Common7/IDE/PublicAssemblies");
} else {
// TODO
}
return refs.ToArray();
}
string[] GetDotNetPacksSearchPaths()
{
var refs = new List<string>();
RunProcess("dotnet", "--list-sdks", out var sdks);
var last = sdks.Last();
var start = last.IndexOf("[") + 1;
var latestSdk = (DirectoryPath)(last.Substring(start, last.Length - start - 1));
var dotnetRoot = latestSdk.Combine("..");
foreach(var pack in GetDirectories(dotnetRoot.Combine("packs").FullPath + "/*.Ref.*")) {
var latestPath = GetDirectories(pack.FullPath + "/*").Last();
refs.AddRange(GetDirectories(latestPath.FullPath + "/ref/net*").Select(d => d.FullPath));
}
foreach(var pack in GetDirectories(dotnetRoot.Combine("packs").FullPath + "/*.Ref")) {
var latestPath = GetDirectories(pack.FullPath + "/*").Last();
refs.AddRange(GetDirectories(latestPath.FullPath + "/ref/net*").Select(d => d.FullPath));
}
return refs.ToArray();
}
async Task<NuGetDiff> CreateNuGetDiffAsync()
{
var comparer = new NuGetDiff();
comparer.SearchPaths.AddRange(GetDotNetPacksSearchPaths());
comparer.SearchPaths.AddRange(GetReferenceSearchPaths());
comparer.PackageCache = PACKAGE_CACHE_PATH.FullPath;
await AddDep("OpenTK.GLControl", "NET40");
await AddDep("Tizen.NET", "netstandard2.0");
await AddDep("Xamarin.Forms", "netstandard2.0");
await AddDep("Xamarin.Forms", "MonoAndroid90");
await AddDep("Xamarin.Forms", "Xamarin.iOS10");
await AddDep("Xamarin.Forms", "Xamarin.Mac");
await AddDep("Xamarin.Forms", "tizen40");
await AddDep("Xamarin.Forms", "uap10.0.16299");
await AddDep("Xamarin.Forms.Platform.WPF", "net461");
await AddDep("Xamarin.Forms.Platform.GTK", "net45");
await AddDep("GtkSharp", "netstandard2.0");
await AddDep("GdkSharp", "netstandard2.0");
await AddDep("GLibSharp", "netstandard2.0");
await AddDep("AtkSharp", "netstandard2.0");
await AddDep("System.Memory", "netstandard2.0");
await AddDep("Uno.UI", "netstandard2.0");
await AddDep("Uno.UI", "MonoAndroid90");
await AddDep("Uno.UI", "xamarinios10");
await AddDep("Uno.UI", "xamarinmac20");
await AddDep("Uno.UI", "UAP");
await AddDep("Microsoft.WindowsAppSDK.Foundation", "net5.0-windows");
await AddDep("Microsoft.WindowsAppSDK.WinUI", "net5.0-windows10.0.18362.0");
await AddDep("Microsoft.WindowsAppSDK.InteractiveExperiences", "net5.0-windows10.0.17763.0");
await AddDep("Microsoft.Maui.Graphics", "netstandard2.0");
await AddDep("Microsoft.Windows.SDK.NET.Ref", "");
await AddDep("OpenTK.GLControl", "NET40", "reference");
await AddDep("Xamarin.Forms", "Xamarin.iOS10", "reference");
await AddDep("Xamarin.Forms", "Xamarin.Mac", "reference");
await AddDep("Xamarin.Forms", "uap10.0", "reference");
return comparer;
async Task AddDep(string id, string platform, string type = "release")
{
var version = GetVersion(id, type);
var root = await comparer.ExtractCachedPackageAsync(id, version);
comparer.SearchPaths.Add(System.IO.Path.Combine(root, "lib", platform));
}
}
async Task DownloadPackageAsync(string id, DirectoryPath outputDirectory)
{
var version = "0.0.0-";
if (!string.IsNullOrEmpty(PREVIEW_LABEL) && PREVIEW_LABEL.StartsWith("pr."))
version += PREVIEW_LABEL.ToLower();
else if (!string.IsNullOrEmpty(GIT_SHA))
version += "commit." + GIT_SHA.ToLower();
else if (!string.IsNullOrEmpty(GIT_BRANCH_NAME))
version += "branch." + GIT_BRANCH_NAME.Replace("/", ".").ToLower();
else
version += "branch.main";
version += ".*";
var filter = new NuGetVersions.Filter {
IncludePrerelease = true,
SourceUrl = PREVIEW_FEED_URL,
VersionRange = VersionRange.Parse(version),
};
var latestVersion = await NuGetVersions.GetLatestAsync(id, filter);
var comparer = new NuGetDiff(PREVIEW_FEED_URL);
comparer.PackageCache = PACKAGE_CACHE_PATH.FullPath;
await Download(id, latestVersion);
async Task Download(string currentId, NuGetVersion currentVersion)
{
currentId = currentId.ToLower();
Information($"Downloading '{currentId}' version '{currentVersion}'...");
if (currentId == "_nativeassets.maccatalyst") {
Warning($"Skipping '{currentId}' because we do not yet have this package working...");
return;
}
var root = await comparer.ExtractCachedPackageAsync(currentId, currentVersion);
var toolsDir = $"{root}/tools/";
if (DirectoryExists(toolsDir)) {
var allFiles = GetFiles(toolsDir + "**/*");
foreach (var file in allFiles) {
var relative = MakeAbsolute(Directory(toolsDir)).GetRelativePath(file);
var dir = $"{outputDirectory}/{relative.GetDirectory()}";
EnsureDirectoryExists(dir);
CopyFileToDirectory(file, dir);
}
}
var nuspec = $"{root}/{currentId}.nuspec";
var xdoc = XDocument.Load(nuspec);
var xmlns = xdoc.Root.Name.Namespace;
var dependencies = xdoc.Root.Descendants(xmlns + "dependency").ToArray();
foreach (var dep in dependencies) {
var depId = dep.Attribute("id").Value;
var depVersion = dep.Attribute("version").Value;
await Download(depId, NuGetVersion.Parse(depVersion));
}
}
}