-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
GenerateServiceWorkerAssetsManifest.cs
92 lines (73 loc) · 3.21 KB
/
GenerateServiceWorkerAssetsManifest.cs
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.Serialization.Json;
using System.Security.Cryptography;
using Microsoft.Build.Framework;
namespace Microsoft.NET.Sdk.BlazorWebAssembly
{
public partial class GenerateServiceWorkerAssetsManifest : Task
{
[Required]
public ITaskItem[] Assets { get; set; }
public string Version { get; set; }
[Required]
public string OutputPath { get; set; }
[Output]
public string CalculatedVersion { get; set; }
public override bool Execute()
{
using var fileStream = File.Create(OutputPath);
CalculatedVersion = GenerateAssetManifest(fileStream);
return true;
}
internal string GenerateAssetManifest(Stream stream)
{
var assets = new AssetsManifestFileEntry[Assets.Length];
System.Threading.Tasks.Parallel.For(0, assets.Length, i =>
{
var item = Assets[i];
var hash = item.GetMetadata("FileHash");
var url = item.GetMetadata("AssetUrl");
if (string.IsNullOrEmpty(hash))
{
// Some files that are part of the service worker manifest may not have their hashes previously
// calcualted. Calculate them at this time.
using var sha = SHA256.Create();
using var file = File.OpenRead(item.ItemSpec);
var bytes = sha.ComputeHash(file);
hash = Convert.ToBase64String(bytes);
}
assets[i] = new AssetsManifestFileEntry
{
hash = "sha256-" + hash,
url = url,
};
});
var version = Version;
if (string.IsNullOrEmpty(version))
{
// If a version isn't specified (which is likely the most common case), construct a Version by combining
// the file names + hashes of all the inputs.
var combinedHash = string.Join(
Environment.NewLine,
assets.OrderBy(f => f.url, StringComparer.Ordinal).Select(f => f.hash));
using var sha = SHA256.Create();
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(combinedHash));
version = Convert.ToBase64String(bytes).Substring(0, 8);
}
var data = new AssetsManifestFile
{
version = version,
assets = assets,
};
using var streamWriter = new StreamWriter(stream, Encoding.UTF8, bufferSize: 50, leaveOpen: true);
streamWriter.Write("self.assetsManifest = ");
streamWriter.Flush();
using var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, ownsStream: false, indent: true);
new DataContractJsonSerializer(typeof(AssetsManifestFile)).WriteObject(jsonWriter, data);
jsonWriter.Flush();
streamWriter.WriteLine(";");
return version;
}
}
}