Skip to content

Commit

Permalink
Refresh browser for all transitively referencing projects (9.0.1xx)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed Nov 24, 2024
1 parent ff3f83c commit 2b72907
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ private async ValueTask DisplayResultsAsync(WatchHotReloadService.Updates update
switch (updates.Status)
{
case ModuleUpdateStatus.None:
_reporter.Output("No hot reload changes to apply.");
_reporter.Output("No C# changes to apply.");
break;

case ModuleUpdateStatus.Ready:
Expand Down
61 changes: 41 additions & 20 deletions src/BuiltInTools/dotnet-watch/HotReload/ScopedCssFileHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections;
using System.Diagnostics;
using Microsoft.Build.Graph;
using Microsoft.Build.Framework;
using Microsoft.DotNet.Watcher.Internal;
using Microsoft.Extensions.Tools.Internal;

Expand Down Expand Up @@ -52,41 +53,61 @@ public async ValueTask HandleFileChangesAsync(IReadOnlyList<ChangedFile> files,
}
}

var logger = reporter.IsVerbose ? new[] { new Build.Logging.ConsoleLogger() } : null;
if (!hasApplicableFiles)
{
return;
}

var logger = reporter.IsVerbose ? new[] { new Build.Logging.ConsoleLogger(LoggerVerbosity.Minimal) } : null;

var tasks = projectsToRefresh.Select(async projectNode =>
var buildTasks = projectsToRefresh.Select(projectNode => Task.Run(() =>
{
if (!projectNode.ProjectInstance.DeepCopy().Build(BuildTargetName, logger))
try
{
return false;
if (!projectNode.ProjectInstance.DeepCopy().Build(BuildTargetName, logger))
{
return null;
}
}
if (browserConnector.TryGetRefreshServer(projectNode, out var browserRefreshServer))
catch (Exception e)
{
await HandleBrowserRefresh(browserRefreshServer, projectNode.ProjectInstance.FullPath, cancellationToken);
reporter.Error($"[{projectNode.GetDisplayName()}] Target {BuildTargetName} failed to build: {e}");
return null;
}
return true;
});
return projectNode;
}));

var results = await Task.WhenAll(tasks).WaitAsync(cancellationToken);
var buildResults = await Task.WhenAll(buildTasks).WaitAsync(cancellationToken);

if (hasApplicableFiles)
var browserRefreshTasks = buildResults.Where(p => p != null)!.GetTransitivelyReferencingProjects().Select(async projectNode =>
{
var successfulCount = results.Sum(r => r ? 1 : 0);

if (successfulCount == results.Length)
{
reporter.Output("Hot reload of scoped css succeeded.", emoji: "🔥");
}
else if (successfulCount > 0)
if (browserConnector.TryGetRefreshServer(projectNode, out var browserRefreshServer))
{
reporter.Output($"Hot reload of scoped css partially succeeded: {successfulCount} project(s) out of {results.Length} were updated.", emoji: "🔥");
reporter.Verbose($"[{projectNode.GetDisplayName()}] Refreshing browser.");
await HandleBrowserRefresh(browserRefreshServer, projectNode.ProjectInstance.FullPath, cancellationToken);
}
else
{
reporter.Output("Hot reload of scoped css failed.", emoji: "🔥");
reporter.Verbose($"[{projectNode.GetDisplayName()}] No refresh server.");
}
});

await Task.WhenAll(browserRefreshTasks).WaitAsync(cancellationToken);

var successfulCount = buildResults.Sum(r => r != null ? 1 : 0);

if (successfulCount == buildResults.Length)
{
reporter.Output("Hot reload of scoped css succeeded.", emoji: "🔥");
}
else if (successfulCount > 0)
{
reporter.Output($"Hot reload of scoped css partially succeeded: {successfulCount} project(s) out of {buildResults.Length} were updated.", emoji: "🔥");
}
else
{
reporter.Output("Hot reload of scoped css failed.", emoji: "🔥");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,28 @@ public static bool IsNetCoreApp(this ProjectGraphNode projectNode, Version minVe

public static IEnumerable<string> GetCapabilities(this ProjectGraphNode projectNode)
=> projectNode.ProjectInstance.GetItems("ProjectCapability").Select(item => item.EvaluatedInclude);

public static IEnumerable<ProjectGraphNode> GetTransitivelyReferencingProjects(this IEnumerable<ProjectGraphNode> projects)
{
var visited = new HashSet<ProjectGraphNode>();
var queue = new Queue<ProjectGraphNode>();
foreach (var project in projects)
{
queue.Enqueue(project);
}

while (queue.Count > 0)
{
var project = queue.Dequeue();
if (visited.Add(project))
{
foreach (var referencingProject in project.ReferencingProjects)
{
queue.Enqueue(referencingProject);
}
}
}

return visited;
}
}

0 comments on commit 2b72907

Please sign in to comment.