-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathScriptRunner.cs
96 lines (84 loc) · 3.96 KB
/
ScriptRunner.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
93
94
95
96
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
namespace Microsoft.DotNet.HotReload.Utils.Generator.Runners;
/// Generate deltas by reading a script from a configuration file
/// listing the changed versions of the project source files.
public class ScriptRunner : Runner {
Script.ParsedScript? parsedScript;
public ScriptRunner (Config config) : base (config) {
if (!string.IsNullOrEmpty(config.OutputSummaryPath)) {
var writer = new JsonSummaryWriter(config.OutputSummaryPath);
OutputsReady = writer.OutputsReady;
OutputsDone = writer.OutputsDone;
}
}
private class JsonSummaryWriter {
private string OutputPath {get; }
private readonly List<OutputSummary.Delta> deltas;
public JsonSummaryWriter(string outputPath) {
OutputPath = outputPath;
deltas = new List<OutputSummary.Delta>();
}
internal void OutputsReady(DeltaNaming names, DeltaOutputStreams _streams) {
// FIXME: propagate the name of the updated assembly
deltas.Add(new OutputSummary.Delta("", names.Dmeta, names.Dil, names.Dpdb));
}
internal async Task OutputsDone(CancellationToken ct = default) {
using var s = File.OpenWrite(OutputPath);
var summary = new OutputSummary.OutputSummary(deltas.ToArray());
await System.Text.Json.JsonSerializer.SerializeAsync(s, summary, cancellationToken: ct);
}
}
protected override async Task PrepareToRun(CancellationToken ct = default)
{
var scriptPath = config.ScriptPath;
var parser = new Microsoft.DotNet.HotReload.Utils.Generator.Script.Json.Parser(scriptPath);
Script.ParsedScript parsed;
using (var scriptStream = new FileStream(scriptPath, FileMode.Open)) {
parsed = await parser.ReadAsync (scriptStream, ct);
}
parsedScript = parsed;
}
protected override bool PrepareCapabilitiesCore (out EnC.EditAndContinueCapabilities capabilities) {
capabilities = EnC.EditAndContinueCapabilities.None;
if (parsedScript == null || parsedScript.Capabilities == null)
return false;
capabilities = parsedScript.Capabilities.Value;
if (!config.NoWarnUnknownCapabilities) {
foreach (var unk in parsedScript.UnknownCapabilities) {
Console.WriteLine ($"Unknown EnC capability '{unk}' in '{config.ScriptPath}', ignored.");
}
}
return true;
}
public override IAsyncEnumerable<Delta> SetupDeltas (BaselineArtifacts baselineArtifacts, CancellationToken ct = default)
{
if (parsedScript == null)
return Util.AsyncEnumerableExtras.Empty<Delta>();
return ScriptedPlanInputs (parsedScript, baselineArtifacts, ct);
}
private static async IAsyncEnumerable<Delta> ScriptedPlanInputs (Script.ParsedScript parsedScript, BaselineArtifacts baselineArtifacts, [EnumeratorCancellation] CancellationToken ct = default)
{
await Task.CompletedTask; // to make compiler happy
var resolver = baselineArtifacts.DocResolver;
var artifacts = parsedScript.Changes.Select(c => new Delta(Plan.Change.Create(ResolveForScript(resolver, c.Document), c.Update)));
foreach (var a in artifacts) {
yield return a;
if (ct.IsCancellationRequested)
break;
}
}
private static DocumentId ResolveForScript (DocResolver resolver, string relativePath) {
if (resolver.TryResolveDocumentId(relativePath, out var id))
return id;
throw new DiffyException($"Could not find {relativePath} in {resolver.Project.Name}", exitStatus: 12);
}
}