This commit is contained in:
Miljenko Cvjetko moljac 2018-09-02 23:15:35 +02:00
Родитель fa4a9d1161 973df145f1
Коммит 1c637b4a40
3 изменённых файлов: 623 добавлений и 52 удалений

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

@ -1,29 +1,16 @@
// Tools needed by cake addins
#tool nuget:?package=XamarinComponent&version=1.1.0.49
#tool nuget:?package=ILRepack&version=2.0.13
#tool nuget:?package=Cake.MonoApiTools&version=2.0.0
#tool nuget:?package=Microsoft.DotNet.BuildTools.GenAPI&version=1.0.0-beta-00081
#tool nuget:?package=NUnit.Runners&version=2.6.4
#tool nuget:?package=Paket
#tool nuget:?package=Cake.MonoApiTools&version=3.0.1
//#tool nuget:?package=Microsoft.DotNet.BuildTools.GenAPI&version=1.0.0-beta-00081
#tool nuget:?package=vswhere
// Cake Addins
#addin nuget:?package=Cake.FileHelpers&version=3.0.0
#addin nuget:?package=Cake.Json&version=3.0.1
#addin nuget:?package=Newtonsoft.Json&version=9.0.1
#addin nuget:?package=Cake.Yaml&version=2.1.0
#addin nuget:?package=YamlDotNet&version=4.2.1
#addin nuget:?package=Cake.Xamarin&version=3.0.0
#addin nuget:?package=Cake.XCode&version=4.0.0
#addin nuget:?package=Cake.Xamarin.Build&version=4.0.0
#addin nuget:?package=Cake.FileHelpers&version=3.1.0
#addin nuget:?package=Cake.Compression&version=0.1.6
#addin nuget:?package=Cake.Android.SdkManager&version=3.0.0
#addin nuget:?package=Cake.Android.Adb&version=3.0.0
#addin nuget:?package=Cake.MonoApiTools&version=2.0.0
#addin nuget:?package=Cake.Xamarin.Binding.Util&version=2.0.0
#addin nuget:?package=Cake.MonoApiTools&version=3.0.1
// From Cake.Xamarin.Build, dumps out versions of things
LogSystemInfo ();
//LogSystemInfo ();
var TARGET = Argument ("t", Argument ("target", "Default"));
var BUILD_CONFIG = Argument ("config", "Release");
@ -138,7 +125,7 @@ Task ("diff")
.IsDependentOn ("merge")
.Does (() =>
{
var SEARCH_DIRS = new FilePath [] {
var SEARCH_DIRS = new DirectoryPath [] {
MONODROID_PATH,
"/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xbuild-frameworks/MonoAndroid/v1.0/",
"/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/mono/2.1/"
@ -217,46 +204,46 @@ Task ("ci-setup")
ReplaceTextInFiles(glob, "{BUILD_TIMESTAMP}", buildTimestamp);
});
Task ("genapi")
.IsDependentOn ("libs")
.Does (() =>
{
var GenApiToolPath = GetFiles ("./tools/**/GenAPI.exe").FirstOrDefault ();
// Task ("genapi")
// .IsDependentOn ("libs")
// .Does (() =>
// {
// var GenApiToolPath = GetFiles ("./tools/**/GenAPI.exe").FirstOrDefault ();
// For some reason GenAPI.exe can't handle absolute paths on mac/unix properly, so always make them relative
// GenAPI.exe -libPath:$(MONOANDROID) -out:Some.generated.cs -w:TypeForwards ./relative/path/to/Assembly.dll
var libDirPrefix = IsRunningOnWindows () ? "output/" : "";
// // For some reason GenAPI.exe can't handle absolute paths on mac/unix properly, so always make them relative
// // GenAPI.exe -libPath:$(MONOANDROID) -out:Some.generated.cs -w:TypeForwards ./relative/path/to/Assembly.dll
// var libDirPrefix = IsRunningOnWindows () ? "output/" : "";
var libs = new FilePath [] {
"./" + libDirPrefix + "Xamarin.Android.Support.Compat.dll",
"./" + libDirPrefix + "Xamarin.Android.Support.Core.UI.dll",
"./" + libDirPrefix + "Xamarin.Android.Support.Core.Utils.dll",
"./" + libDirPrefix + "Xamarin.Android.Support.Fragment.dll",
"./" + libDirPrefix + "Xamarin.Android.Support.Media.Compat.dll",
};
// var libs = new FilePath [] {
// "./" + libDirPrefix + "Xamarin.Android.Support.Compat.dll",
// "./" + libDirPrefix + "Xamarin.Android.Support.Core.UI.dll",
// "./" + libDirPrefix + "Xamarin.Android.Support.Core.Utils.dll",
// "./" + libDirPrefix + "Xamarin.Android.Support.Fragment.dll",
// "./" + libDirPrefix + "Xamarin.Android.Support.Media.Compat.dll",
// };
foreach (var lib in libs) {
var genName = lib.GetFilename () + ".generated.cs";
// foreach (var lib in libs) {
// var genName = lib.GetFilename () + ".generated.cs";
var libPath = IsRunningOnWindows () ? MakeAbsolute (lib).FullPath : lib.FullPath;
var monoDroidPath = IsRunningOnWindows () ? "\"" + MONODROID_PATH + "\"" : MONODROID_PATH;
// var libPath = IsRunningOnWindows () ? MakeAbsolute (lib).FullPath : lib.FullPath;
// var monoDroidPath = IsRunningOnWindows () ? "\"" + MONODROID_PATH + "\"" : MONODROID_PATH;
Information ("GenAPI: {0}", lib.FullPath);
// Information ("GenAPI: {0}", lib.FullPath);
StartProcess (GenApiToolPath, new ProcessSettings {
Arguments = string.Format("-libPath:{0} -out:{1}{2} -w:TypeForwards {3}",
monoDroidPath + "," + MSCORLIB_PATH,
IsRunningOnWindows () ? "" : "./",
genName,
libPath),
WorkingDirectory = "./output/",
});
}
// StartProcess (GenApiToolPath, new ProcessSettings {
// Arguments = string.Format("-libPath:{0} -out:{1}{2} -w:TypeForwards {3}",
// monoDroidPath + "," + MSCORLIB_PATH,
// IsRunningOnWindows () ? "" : "./",
// genName,
// libPath),
// WorkingDirectory = "./output/",
// });
// }
MSBuild ("./AndroidSupport.TypeForwarders.sln", c => c.Configuration = BUILD_CONFIG);
// MSBuild ("./AndroidSupport.TypeForwarders.sln", c => c.Configuration = BUILD_CONFIG);
CopyFile ("./support-v4/source/bin/" + BUILD_CONFIG + "/Xamarin.Android.Support.v4.dll", "./output/Xamarin.Android.Support.v4.dll");
});
// CopyFile ("./support-v4/source/bin/" + BUILD_CONFIG + "/Xamarin.Android.Support.v4.dll", "./output/Xamarin.Android.Support.v4.dll");
// });
// Task ("buildtasks")
// .Does (() =>

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

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cake" version="0.27.0" />
<package id="Cake" version="0.30.0" />
</packages>

584
nuget.cake Normal file
Просмотреть файл

@ -0,0 +1,584 @@
///////////////////////////////////////////////////////////////////////////////
// COMMAND LINE ARGUMENTS
//
// --localSource [a directory path or URL to a NuGet source]
// This can be used to provide access to the build
// artifacts to use as the base for the fat
// packages.
// --packagesPath [a directory path to download NuGet packages to]
// This can be used to change where the existing
// packages get downloaded to temporarily.
// --workingPath [a directory path to perform work inside of]
// This can be used to change the directory which
// is used to process files for packaging.
// --outputPath [a directory path to output processed packages to]
// This can be used to change the output path of the
// processed packages.
// --keepLatestVersion [True|False]
// This can be used to indicate that the latest
// version should not be incremented, rather use
// the version in the fat package.
// --incrementVersion [True|False]
// This can be used to indicate that the fat packages
// should have new versions.
// --packLatestOnly [True|False]
// This can be used to indicate that only the latest
// version should be packed.
// --useExplicitVersion [True|False]
// This can be used to indicate that the dependencies
// should use hard/exact versions: [x.x.x]
///////////////////////////////////////////////////////////////////////////////
// EXAMPLE USE CASE
//
// In order to have this script run as part of CI to make fat packages, use the
// following options:
//
// .\build.ps1 `
// --localSource="<path-to-build-directory>" `
// --incrementVersion=False `
// --packLatestOnly=True `
// --useExplicitVersion=True
// --packagesPath="./externals/packages"
// --workingPath="./working/packages"
// --outputPath="./output/packages"
//
///////////////////////////////////////////////////////////////////////////////
#addin nuget:?package=Cake.FileHelpers&version=3.0.0
#addin nuget:?package=NuGet.Packaging&version=4.7.0&loaddependencies=true
#addin nuget:?package=NuGet.Protocol&version=4.7.0&loaddependencies=true
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using NuGet.Common;
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using NuGet.Versioning;
var target = Argument("target", "Default");
var localSource = Argument("localSource", "");
var keepLatestVersion = Argument("keepLatestVersion", false);
var incrementVersion = Argument("incrementVersion", true);
var packLatestOnly = Argument("packLatestOnly", false);
var useExplicitVersion = Argument("useExplicitVersion", true);
var packagesPath = (DirectoryPath)Argument("packagesPath", "externals/packages");
var workingPath = (DirectoryPath)Argument("workingPath", "working/packages");
var outputPath = (DirectoryPath)Argument("outputPath", "output/packages");
var apiLevelVersion = new Dictionary<int, NuGetFramework> {
// { 1, NuGetFramework.Parse("monoandroid1.0") },
// { 15, NuGetFramework.Parse("monoandroid4.0.3") },
// { 19, NuGetFramework.Parse("monoandroid4.4") },
// { 21, NuGetFramework.Parse("monoandroid5.0") },
// { 22, NuGetFramework.Parse("monoandroid5.1") },
{ 23, NuGetFramework.Parse("monoandroid6.0") },
{ 24, NuGetFramework.Parse("monoandroid7.0") },
{ 25, NuGetFramework.Parse("monoandroid7.1") },
{ 26, NuGetFramework.Parse("monoandroid8.0") },
{ 27, NuGetFramework.Parse("monoandroid8.1") },
{ 28, NuGetFramework.Parse("monoandroid9.0") },
};
var minimumVersion = new Dictionary<string, NuGetVersion> {
{ "xamarin.android.arch", new NuGetVersion(1, 0, 0) },
{ "xamarin.android.support", new NuGetVersion(23, 4, 0) },
};
var blacklistIdPrefix = new List<string> {
"xamarin.build.download",
};
var seedPackages = new [] {
"Xamarin.Android.Support.Animated.Vector.Drawable",
"Xamarin.Android.Support.Annotations",
"Xamarin.Android.Support.Compat",
// "Xamarin.Android.Support.Constraint.Layout",
// "Xamarin.Android.Support.Constraint.Layout.Solver",
"Xamarin.Android.Support.Content",
"Xamarin.Android.Support.Core.UI",
"Xamarin.Android.Support.Core.Utils",
"Xamarin.Android.Support.CustomTabs",
"Xamarin.Android.Support.Design",
"Xamarin.Android.Support.Dynamic.Animation",
"Xamarin.Android.Support.Emoji",
"Xamarin.Android.Support.Emoji.AppCompat",
"Xamarin.Android.Support.Emoji.Bundled",
"Xamarin.Android.Support.Exif",
"Xamarin.Android.Support.Fragment",
"Xamarin.Android.Support.InstantVideo",
"Xamarin.Android.Support.Media.Compat",
"Xamarin.Android.Support.Percent",
"Xamarin.Android.Support.Recommendation",
"Xamarin.Android.Support.TV.Provider",
"Xamarin.Android.Support.Transition",
"Xamarin.Android.Support.Vector.Drawable",
"Xamarin.Android.Support.Wear",
//"Xamarin.Android.Support.Wearable",
"Xamarin.Android.Support.v13",
"Xamarin.Android.Support.v14.Preference",
"Xamarin.Android.Support.v17.Leanback",
"Xamarin.Android.Support.v17.Preference.Leanback",
"Xamarin.Android.Support.v4",
"Xamarin.Android.Support.v7.AppCompat",
"Xamarin.Android.Support.v7.CardView",
"Xamarin.Android.Support.v7.GridLayout",
"Xamarin.Android.Support.v7.MediaRouter",
"Xamarin.Android.Support.v7.Palette",
"Xamarin.Android.Support.v7.Preference",
"Xamarin.Android.Support.v7.RecyclerView",
"Xamarin.Android.Support.v8.RenderScript",
};
bool IsBlacklisted(string id)
{
id = id.ToLower();
if (blacklistIdPrefix.Contains(id))
return true;
if (blacklistIdPrefix.Any(p => id.StartsWith(p)))
return true;
return false;
}
NuGetVersion GetSupportVersion(FilePath nuspec)
{
var xdoc = XDocument.Load(nuspec.FullPath);
var ns = xdoc.Root.Name.Namespace;
var xmd = xdoc.Root.Element(ns + "metadata");
var xid = xmd.Element(ns + "id");
string version;
if (xid.Value.ToLower().StartsWith("xamarin.android.arch")) {
version = xmd
.Descendants(ns + "dependency")
.First(e => e.Attribute("id").Value.ToLower().StartsWith("xamarin.android.support"))
.Attribute("version")
.Value;
} else {
version = xmd.Element(ns + "version").Value;
}
return NuGetVersion.Parse(version);
}
NuGetVersion GetNewVersion(string id, string old)
{
return GetNewVersion(id, NuGetVersion.Parse(old));
}
NuGetVersion GetNewVersion(string id, NuGetVersion old)
{
if (keepLatestVersion) {
var latest = GetLatestVersion(id);
if (old == latest)
return old;
}
if (!incrementVersion)
return old;
return new NuGetVersion(
old.Major,
old.Minor,
old.Patch,
990 + old.Revision,
(string)null, // old.Release,
(string)null); // old.Metadata);
}
NuGetVersion GetNewVersion(string id, VersionRange old)
{
return GetNewVersion(id, old.MinVersion ?? old.MaxVersion);
}
NuGetVersion GetLatestVersion(string id)
{
return GetDirectories($"{packagesPath}/{id}/*")
.Select(d => NuGetVersion.Parse(d.GetDirectoryName()))
.OrderByDescending(v => v)
.FirstOrDefault();
}
Task("DownloadNuGets")
.Does(async () =>
{
var nugetSources = new List<SourceRepository> {
Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json")
};
if (!string.IsNullOrEmpty(localSource)) {
nugetSources.Add(Repository.Factory.GetCoreV3(localSource));
}
var nugetCache = new SourceCacheContext();
var nugetLogger = NullLogger.Instance;
var processedIds = new List<string>();
// download the bits from nuget.org and any local packages
await DownloadNuGetsAsync(seedPackages);
async Task DownloadNuGetsAsync(IEnumerable<string> ids)
{
EnsureDirectoryExists(packagesPath);
foreach (var id in ids.Select(i => i.ToLower())) {
// skip ids that have already been downloaded
if (processedIds.Contains(id))
continue;
// skip packages that we don't want
if (IsBlacklisted(id))
continue;
// mark this id as processed
processedIds.Add(id);
// get the versions for each nuget
Information($"Making sure that all the versions of '{id}' are available for processing...");
foreach (var nugetSource in nugetSources) {
var mdRes = await nugetSource.GetResourceAsync<MetadataResource>();
var allVersions = await mdRes.GetVersions(id, false, false, nugetCache, nugetLogger, default);
// process the versions
foreach (var version in allVersions) {
// skip versions tht are lower than what we want to support
var min = minimumVersion[minimumVersion.Keys.First(k => id.StartsWith(k))];
if (version < min)
continue;
var identity = new PackageIdentity(id, version);
var dest = packagesPath.Combine(id).Combine(version.ToNormalizedString());
var destFile = dest.CombineWithFilePath($"{id}.{version.ToNormalizedString()}.nupkg");
// download the packages, if needed
if (!FileExists(destFile)) {
Information($" - Downloading '{identity}'...");
EnsureDirectoryExists(dest);
var byIdRes = await nugetSource.GetResourceAsync<FindPackageByIdResource>();
using (var downloader = await byIdRes.GetPackageDownloaderAsync(identity, nugetCache, nugetLogger, default)) {
await downloader.CopyNupkgFileToAsync(destFile.FullPath, default);
}
Unzip(destFile, dest);
}
// download dependencies
var packageRes = await nugetSource.GetResourceAsync<PackageMetadataResource>();
var metadata = await packageRes.GetMetadataAsync(identity, nugetCache, nugetLogger, default);
var deps = metadata.DependencySets.SelectMany(g => g.Packages).Select(p => p.Id);
await DownloadNuGetsAsync(deps);
}
}
}
}
});
Task("PrepareWorkingDirectory")
.IsDependentOn("DownloadNuGets")
.Does(() =>
{
EnsureDirectoryExists(workingPath);
CleanDirectories(workingPath.FullPath);
// copy the downloaded files into the working directory
Information($"Copying packages...");
foreach (var idDir in GetDirectories($"{packagesPath}/*")) {
var id = idDir.GetDirectoryName();
// skip packages that don't want
if (IsBlacklisted(id))
continue;
Information($" - Copying all versions of '{id}'...");
// we only want to copy the latest of each major version
var versions = GetFiles($"{idDir}/*/*.nuspec")
.Select(n => new { Dir = n.GetDirectory().GetDirectoryName(), Ver = GetSupportVersion(n) })
.OrderByDescending(n => n.Ver)
.GroupBy(n => n.Ver.Major, n => n.Dir)
.Select(g => g.FirstOrDefault());
foreach (var version in versions) {
CopyDirectory($"{packagesPath}/{id}/{version}", $"{workingPath}/{id}/{GetNewVersion(id, version)}");
}
}
// remove all the files we do not want in the nugets
Information($"Removing junk...");
var junkFiles =
GetFiles($"{workingPath}/*/*.json") +
GetFiles($"{workingPath}/*/*/*.nupkg") +
GetFiles($"{workingPath}/*/*/.signature.p7s") +
GetFiles($"{workingPath}/*/*/[Content_Types].xml");
foreach (var junk in junkFiles) {
DeleteFile(junk);
}
var junkDirs =
GetDirectories($"{workingPath}/*/*/_rels") +
GetDirectories($"{workingPath}/*/*/package");
foreach (var junk in junkDirs) {
DeleteDirectory(junk, new DeleteDirectorySettings {
Force = true,
Recursive = true
});
}
// put all the nuspecs and contents into a standard format for processing
Information($"Normalizing packages...");
foreach (var idDir in GetDirectories($"{workingPath}/*")) {
var id = idDir.GetDirectoryName();
// skip packages that don't want
if (IsBlacklisted(id))
continue;
Information($" - Normalizing all versions of '{id}'...");
var nuspecs = GetFiles($"{idDir}/*/*.nuspec");
foreach (var nuspec in nuspecs) {
var targetFw = NormalizeNuspec(nuspec);
NormalizeContents(nuspec.GetDirectory(), targetFw, "lib");
NormalizeContents(nuspec.GetDirectory(), targetFw, "build");
NormalizeContents(nuspec.GetDirectory(), targetFw, "proguard");
// change the path to the proguard.txt files, nothing clever, just a replace
var oldLink = @"..\..\proguard\proguard.txt";
var newLink = $@"..\..\proguard\{targetFw.GetShortFolderName()}\proguard.txt";
var targets = $"{nuspec.GetDirectory()}/build/{targetFw.GetShortFolderName()}/*.targets";
ReplaceTextInFiles(targets, oldLink, newLink);
}
}
void NormalizeContents(DirectoryPath dir, NuGetFramework fw, string subdir)
{
if (!DirectoryExists($"{dir}/{subdir}"))
return;
// temp checks
if (GetDirectories($"{dir}/{subdir}/*/*").Any())
throw new Exception($"'{dir}' contains sub directories.");
// make sure the files are in the right folder, but
// only if there is one folder - more means this is
// already a fat package
if (GetDirectories($"{dir}/{subdir}/*").Count() == 1) {
EnsureDirectoryExists(dir.Combine("temp"));
MoveFiles($"{dir}/{subdir}/**/*", dir.Combine("temp"));
CleanDirectories($"{dir}/{subdir}");
MoveDirectory(dir.Combine("temp"), dir.Combine(subdir).Combine(fw.GetShortFolderName()));
}
}
NuGetFramework NormalizeNuspec(FilePath nuspec)
{
var version = GetSupportVersion(nuspec);
var targetFw = apiLevelVersion[version.Major];
var xdoc = XDocument.Load(nuspec.FullPath);
var ns = xdoc.Root.Name.Namespace;
var xmd = xdoc.Root.Element(ns + "metadata");
// set the new version of the package
var xv = xmd.Element(ns + "version");
xv.Value = GetNewVersion(xmd.Element(ns + "id").Value, version).ToNormalizedString();
// make sure the <dependencies> element exists
var xdeps = xmd.Element(ns + "dependencies");
if (xdeps == null) {
xdeps = new XElement(ns + "dependencies");
xmd.Add(xdeps);
}
// move the loose dependencies into a group
var xlooseDeps = xdeps.Elements(ns + "dependency");
if (xlooseDeps.Any()) {
xdeps.Add(new XElement(ns + "group",
new XAttribute("targetFramework", targetFw.GetShortFolderName()),
xlooseDeps));
}
// some packages have the wrong <group> targets, so recreate everything
var xnewGroups = new Dictionary<int, XElement>();
foreach (var pair in apiLevelVersion) {
if (pair.Key > version.Major)
continue;
xnewGroups.Add(pair.Key, new XElement(ns + "group",
new XAttribute("targetFramework", pair.Value.GetShortFolderName())));
}
// move the old dependencies into the new groups if they contain a support version
// if not, then just use the version of the nuspec
var xgroups = xdeps.Elements(ns + "group");
foreach (var xoldGroup in xgroups) {
var xgroupDeps = xoldGroup.Elements(ns + "dependency");
var firstSupportVersion = xgroupDeps
.Where(x => x.Attribute("id").Value.ToLower().StartsWith("xamarin.android.support"))
.Select(x => VersionRange.Parse(x.Attribute("version").Value))
.FirstOrDefault();
var minVersion = firstSupportVersion?.MinVersion ?? version;
xnewGroups[minVersion.Major].Add(xgroupDeps);
}
// set the new versions of the dependencies
foreach (var xdep in xnewGroups.Values.Elements(ns + "dependency")) {
if (IsBlacklisted(xdep.Attribute("id").Value))
continue;
var xdv = xdep.Attribute("version");
var range = VersionRange.Parse(xdv.Value);
xdv.Value = GetNewVersion(xdep.Attribute("id").Value.ToLower(), range).ToNormalizedString();
if (useExplicitVersion) {
xdv.Value = $"[{xdv.Value}]";
}
}
// swap out the old dependencies for the new ones
xdeps.RemoveAll();
xdeps.Add(xnewGroups.Values);
xdoc.Save(nuspec.FullPath);
return targetFw;
}
});
Task("CreateFatNuGets")
.IsDependentOn("PrepareWorkingDirectory")
.Does(async () =>
{
var idDirs = GetDirectories($"{workingPath}/*");
foreach (var idDir in idDirs) {
var id = idDir.GetDirectoryName();
// skip packages that don't want
if (IsBlacklisted(id))
continue;
Information($"Processing all versions of '{id}'...");
var versions = GetDirectories($"{idDir}/*")
.Select(d => d.GetDirectoryName())
.Select(v => NuGetVersion.Parse(v))
.OrderByDescending(v => v)
.ToList();
// merge the older packages into the latest
foreach (var cutoffVersion in versions) {
Information($" - Processing version '{cutoffVersion}' of '{id}'...");
var includedVersions = versions.Where(v => v < cutoffVersion).ToArray();
MergeNuspecs(id, cutoffVersion, includedVersions);
MergeContents(id, cutoffVersion, includedVersions, "lib");
MergeContents(id, cutoffVersion, includedVersions, "build");
MergeContents(id, cutoffVersion, includedVersions, "proguard");
CreateDummyLibs(id, cutoffVersion);
}
}
void CreateDummyLibs(string id, NuGetVersion version)
{
var root = $"{workingPath}/{id}/{version.ToNormalizedString()}/lib";
foreach (var pair in apiLevelVersion) {
var dir = $"{root}/{pair.Value.GetShortFolderName()}";
if (!DirectoryExists(dir)) {
EnsureDirectoryExists(dir);
FileWriteText($"{dir}/_._", "");
} else {
// jump out as soon as we find a folder because we don't
// want to add newer dummy folders
break;
}
}
}
void MergeContents(string id, NuGetVersion version, NuGetVersion[] includedVersions, string subdir)
{
var dest = $"{workingPath}/{id}/{version.ToNormalizedString()}/{subdir}";
foreach (var included in includedVersions) {
var src = $"{workingPath}/{id}/{included.ToNormalizedString()}/{subdir}";
if (DirectoryExists(src)) {
CopyDirectory(src, dest);
}
}
}
void MergeNuspecs(string id, NuGetVersion version, NuGetVersion[] includedVersions)
{
var nuspec = $"{workingPath}/{id}/{version.ToNormalizedString()}/{id}.nuspec";
var xdoc = XDocument.Load(nuspec);
var ns = xdoc.Root.Name.Namespace;
var xmd = xdoc.Root.Element(ns + "metadata");
var xdeps = xmd.Element(ns + "dependencies");
var xgroups = xdeps.Elements(ns + "group");
foreach (var included in includedVersions) {
var includedNuspec = $"{workingPath}/{id}/{included.ToNormalizedString()}/{id}.nuspec";
var xincluded = XDocument.Load(includedNuspec);
var ins = xincluded.Root.Name.Namespace;
var ixmd = xincluded.Root.Element(ins + "metadata");
var ixdeps = ixmd.Element(ins + "dependencies");
var ixgroups = ixdeps.Elements(ins + "group");
foreach (var ixgroup in ixgroups) {
var xgroup = xgroups.FirstOrDefault(g => g.Attribute("targetFramework").Value == ixgroup.Attribute("targetFramework").Value);
xgroup.Add(ixgroup.Elements());
}
}
xdoc.Save(nuspec);
}
});
Task("PackNuGets")
.IsDependentOn("CreateFatNuGets")
.Does(async () =>
{
EnsureDirectoryExists(outputPath);
CleanDirectories(outputPath.FullPath);
var idDirs = GetDirectories($"{workingPath}/*");
foreach (var idDir in idDirs) {
var id = idDir.GetDirectoryName();
// skip packages that don't want
if (IsBlacklisted(id))
continue;
var versions = GetDirectories($"{workingPath}/{id}/*")
.Select(d => new { Dir = d, Ver = NuGetVersion.Parse(d.GetDirectoryName()) })
.OrderByDescending(v => v.Ver);
foreach (var version in versions) {
var nuspec = GetFiles($"{version.Dir}/*.nuspec").FirstOrDefault();
Information($"Packing {nuspec}...");
NuGetPack(nuspec, new NuGetPackSettings {
Version = version.Ver.ToString(),
BasePath = nuspec.GetDirectory(),
OutputDirectory = outputPath
});
if (packLatestOnly)
break;
}
}
});
Task("Default")
.IsDependentOn("DownloadNuGets")
.IsDependentOn("PrepareWorkingDirectory")
.IsDependentOn("CreateFatNuGets")
.IsDependentOn("PackNuGets");
RunTarget(target);