forked from cake-build/website
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnuget.cake
117 lines (93 loc) · 3.6 KB
/
nuget.cake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#addin "nuget:https://api.nuget.org/v3/index.json?package=Polly&version=7.1.0"
#addin "nuget:https://api.nuget.org/v3/index.json?package=LitJson&version=0.13.0"
using System.Net.Http;
using Polly;
public static void DownloadPackages(this ICakeContext context, DirectoryPath addinDir, string[] packageIds)
{
var retryPolicy = Policy
.Handle<Exception>()
.WaitAndRetry(5, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
);
using (var httpClient = new HttpClient())
{
Parallel.ForEach(
packageIds,
packageId => retryPolicy.Execute(
() => context.DownloadPackage(addinDir, httpClient, packageId)
)
);
}
}
public static void DownloadPackage(this ICakeContext context, DirectoryPath addinDir, HttpClient httpClient, string packageId)
{
context.Information("[{0}] fetching meta data...", packageId);
var packageJson = httpClient.GetStringAsync($"https://api.nuget.org/v3/registration5-semver1/{packageId.ToLowerInvariant()}/index.json")
.GetAwaiter()
.GetResult();
var package = LitJson.JsonMapper.ToObject<Package>(packageJson);
var packageInfo = (
from packageItem in package?.items ?? Enumerable.Empty<PackageItem>()
from item in packageItem.items ?? Enumerable.Empty<PackageRevisions>()
where item?.catalogEntry?.version == packageItem.upper
select new
{
id = packageId,
version = packageItem?.upper,
item?.packageContent
}
).FirstOrDefault();
context.Verbose("[{0}] found {1}...", packageId, packageInfo);
var packageDir = addinDir.Combine($"{packageId}.{packageInfo.version}".ToLower());
using (var stream = httpClient.GetStreamAsync(packageInfo.packageContent).GetAwaiter().GetResult())
{
using (var zipStream = new System.IO.Compression.ZipArchive(stream))
{
var extractedFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var entry in zipStream.Entries)
{
if (!entry.FullName.StartsWith("lib") || extractedFiles.Contains(entry.Name))
{
continue;
}
extractedFiles.Add(entry.Name);
var entryPath = packageDir.CombineWithFilePath(entry.FullName);
switch (entryPath.GetExtension().ToLowerInvariant())
{
case ".xml":
case ".dll":
break;
default:
continue;
}
context.Verbose("[{0}] {1}", packageId, entry.FullName);
var directory = entryPath.GetDirectory();
context.EnsureDirectoryExists(directory);
using (System.IO.Stream source = entry.Open(),
target = context.FileSystem.GetFile(entryPath).OpenWrite())
{
source.CopyTo(target);
}
}
}
}
context.Information("[{0}] done.", packageId);
}
public class Package
{
public PackageItem[] items { get; set; }
}
public class PackageItem
{
public PackageRevisions[] items { get; set; }
public string upper { get; set; }
}
public class PackageRevisions
{
public PackageCatalogentry catalogEntry { get; set; }
public string packageContent { get; set; }
}
public class PackageCatalogentry
{
public string version { get; set; }
}