Skip to content

Commit

Permalink
[automated] Merge branch 'release/9.0.3xx' => 'main' (#46403)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcpopMSFT authored Feb 7, 2025
2 parents 0de292a + bb116e4 commit 7dc5ce3
Show file tree
Hide file tree
Showing 32 changed files with 220 additions and 144 deletions.
15 changes: 15 additions & 0 deletions sdk.sln
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.HotReload.
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.DotNet.HotReload.Agent.PipeRpc", "src\BuiltInTools\HotReloadAgent.PipeRpc\Microsoft.DotNet.HotReload.Agent.PipeRpc.shproj", "{FA3C7F91-42A2-45AD-897C-F646B081016C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.HotReload.Agent.Data.Package", "src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.Package.csproj", "{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.DotNet.HotReload.Agent.Data", "src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.shproj", "{0762B436-F4B0-4008-9097-BB5FF6BD84AF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -975,6 +979,10 @@ Global
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|Any CPU.Build.0 = Release|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1155,19 +1163,26 @@ Global
{2FF79F82-60C1-349A-4726-7783D5A6D5DF} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{692B71D8-9C31-D1EE-6C1B-570A12B18E39} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{FA3C7F91-42A2-45AD-897C-F646B081016C} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{0762B436-F4B0-4008-9097-BB5FF6BD84AF} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FB8F26CE-4DE6-433F-B32A-79183020BBD6}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{03c5a84a-982b-4f38-ac73-ab832c645c4a}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems*{0762b436-f4b0-4008-9097-bb5ff6bd84af}*SharedItemsImports = 13
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{0a3c9afd-f6e6-4a5d-83fb-93bf66732696}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems*{1bbfa19c-03f0-4d27-9d0d-0f8172642107}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.PipeRpc\Microsoft.DotNet.HotReload.Agent.PipeRpc.projitems*{1bbfa19c-03f0-4d27-9d0d-0f8172642107}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent\Microsoft.DotNet.HotReload.Agent.projitems*{1bbfa19c-03f0-4d27-9d0d-0f8172642107}*SharedItemsImports = 5
src\BuiltInTools\AspireService\Microsoft.WebTools.AspireService.projitems*{1f0b4b3c-dc88-4740-b04f-1707102e9930}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems*{2ff79f82-60c1-349a-4726-7783d5a6d5df}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent\Microsoft.DotNet.HotReload.Agent.projitems*{418b10bd-ca42-49f3-8f4a-d8cc90c8a17d}*SharedItemsImports = 13
src\BuiltInTools\AspireService\Microsoft.WebTools.AspireService.projitems*{445efbd5-6730-4f09-943d-278e77501ffd}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems*{445efbd5-6730-4f09-943d-278e77501ffd}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.PipeRpc\Microsoft.DotNet.HotReload.Agent.PipeRpc.projitems*{445efbd5-6730-4f09-943d-278e77501ffd}*SharedItemsImports = 5
src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems*{692b71d8-9c31-d1ee-6c1b-570a12b18e39}*SharedItemsImports = 5
src\BuiltInTools\AspireService\Microsoft.WebTools.AspireService.projitems*{94c8526e-dcc2-442f-9868-3dd0ba2688be}*SharedItemsImports = 13
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{9d36039f-d0a1-462f-85b4-81763c6b02cb}*SharedItemsImports = 13
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{a9103b98-d888-4260-8a05-fa36f640698a}*SharedItemsImports = 5
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\HotReloadAgent\Microsoft.DotNet.HotReload.Agent.projitems" Label="Shared" />
<Import Project="..\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems" Label="Shared" />
<Import Project="..\HotReloadAgent.PipeRpc\Microsoft.DotNet.HotReload.Agent.PipeRpc.projitems" Label="Shared" />
<PropertyGroup>
<!--
Expand All @@ -9,7 +10,12 @@
<TargetFramework>netstandard2.1</TargetFramework>
<StrongNameKeyId>MicrosoftAspNetCore</StrongNameKeyId>

<IsPackable>false</IsPackable>
<!-- NuGet -->
<IsPackable>true</IsPackable>
<PackageId>Microsoft.DotNet.HotReload.Agent.Host</PackageId>
<PackageDescription>
Package containing Hot Reload agent host.
</PackageDescription>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--
Intentionally pinned. Supports Visual Studio in-proc agent client.
-->
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<DebugType>none</DebugType>
<GenerateDependencyFile>false</GenerateDependencyFile>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>

<!-- NuGet -->
<IsPackable>true</IsPackable>
<IsSourcePackage>true</IsSourcePackage>
<PackageId>Microsoft.DotNet.HotReload.Agent.Data</PackageId>
<IncludeBuildOutput>false</IncludeBuildOutput>
<PackageDescription>
Package containing sources of Hot Reload agent data types.
</PackageDescription>
<!-- Remove once https://github.com/NuGet/Home/issues/8583 is fixed -->
<NoWarn>$(NoWarn);NU5128</NoWarn>
</PropertyGroup>

<!-- Make sure the shared source files do not require any global usings -->
<ItemGroup>
<Using Remove="@(Using)" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>{0762B436-F4B0-4008-9097-BB5FF6BD84AF}</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>Microsoft.DotNet.HotReload</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)**\*.cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>0762B436-F4B0-4008-9097-BB5FF6BD84AF</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="Microsoft.DotNet.HotReload.Agent.Data.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,5 @@
<ItemGroup>
<Using Remove="@(Using)" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\HotReloadAgent\AgentMessageSeverity.cs" Link="AgentContracts\AgentMessageSeverity.cs" />
<Compile Include="..\HotReloadAgent\ResponseLoggingLevel.cs" Link="AgentContracts\ResponseLoggingLevel.cs" />
<Compile Include="..\HotReloadAgent\UpdateDelta.cs" Link="AgentContracts\UpdateDelta.cs" />
</ItemGroup>
<Import Project="..\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems" Label="Shared" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@
<ItemGroup>
<Using Remove="@(Using)" />
</ItemGroup>
<Import Project="..\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.projitems" Label="Shared" />
</Project>
2 changes: 2 additions & 0 deletions src/BuiltInTools/dotnet-watch.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"src\\BuiltInTools\\DotNetWatchTasks\\DotNetWatchTasks.csproj",
"src\\BuiltInTools\\HotReloadAgent\\Microsoft.DotNet.HotReload.Agent.Package.csproj",
"src\\BuiltInTools\\HotReloadAgent\\Microsoft.DotNet.HotReload.Agent.shproj",
"src\\BuiltInTools\\HotReloadAgent.Data\\Microsoft.DotNet.HotReload.Agent.Data.Package.csproj",
"src\\BuiltInTools\\HotReloadAgent.Data\\Microsoft.DotNet.HotReload.Agent.Data.shproj",
"src\\BuiltInTools\\HotReloadAgent.PipeRpc\\Microsoft.DotNet.HotReload.Agent.PipeRpc.Package.csproj",
"src\\BuiltInTools\\HotReloadAgent.PipeRpc\\Microsoft.DotNet.HotReload.Agent.PipeRpc.shproj",
"src\\BuiltInTools\\dotnet-watch\\dotnet-watch.csproj",
Expand Down
23 changes: 16 additions & 7 deletions src/BuiltInTools/dotnet-watch/Browser/BrowserConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace Microsoft.DotNet.Watch
{
internal sealed partial class BrowserConnector(DotNetWatchContext context) : IAsyncDisposable, IStaticAssetChangeApplierProvider
{
private readonly record struct ProjectKey(string projectPath, string targetFramework);

// This needs to be in sync with the version BrowserRefreshMiddleware is compiled against.
private static readonly Version s_minimumSupportedVersion = Versions.Version6_0;

Expand All @@ -23,11 +25,11 @@ internal sealed partial class BrowserConnector(DotNetWatchContext context) : IAs
[GeneratedRegex(@"Login to the dashboard at (?<url>.*)\s*$", RegexOptions.Compiled)]
private static partial Regex GetAspireDashboardUrlRegex();

private readonly object _serversGuard = new();
private readonly Dictionary<ProjectGraphNode, BrowserRefreshServer?> _servers = [];
private readonly Lock _serversGuard = new();
private readonly Dictionary<ProjectKey, BrowserRefreshServer?> _servers = [];

// interlocked
private ImmutableHashSet<ProjectGraphNode> _browserLaunchAttempted = [];
private ImmutableHashSet<ProjectKey> _browserLaunchAttempted = [];

public async ValueTask DisposeAsync()
{
Expand All @@ -48,6 +50,9 @@ await Task.WhenAll(serversToDispose.Select(async server =>
}));
}

private static ProjectKey GetProjectKey(ProjectGraphNode projectNode)
=> new(projectNode.ProjectInstance.FullPath, projectNode.GetTargetFramework());

/// <summary>
/// A single browser refresh server is created for each project that supports browser launching.
/// When the project is rebuilt we reuse the same refresh server and browser instance.
Expand All @@ -63,13 +68,15 @@ await Task.WhenAll(serversToDispose.Select(async server =>
BrowserRefreshServer? server;
bool hasExistingServer;

var key = GetProjectKey(projectNode);

lock (_serversGuard)
{
hasExistingServer = _servers.TryGetValue(projectNode, out server);
hasExistingServer = _servers.TryGetValue(key, out server);
if (!hasExistingServer)
{
server = IsServerSupported(projectNode) ? new BrowserRefreshServer(context.EnvironmentOptions, context.Reporter) : null;
_servers.Add(projectNode, server);
_servers.Add(key, server);
}
}

Expand Down Expand Up @@ -108,9 +115,11 @@ bool IStaticAssetChangeApplierProvider.TryGetApplier(ProjectGraphNode projectNod

public bool TryGetRefreshServer(ProjectGraphNode projectNode, [NotNullWhen(true)] out BrowserRefreshServer? server)
{
var key = GetProjectKey(projectNode);

lock (_serversGuard)
{
return _servers.TryGetValue(projectNode, out server) && server != null;
return _servers.TryGetValue(key, out server) && server != null;
}
}

Expand Down Expand Up @@ -156,7 +165,7 @@ void handler(OutputLine line)
matchFound = true;

if (projectOptions.IsRootProject &&
ImmutableInterlocked.Update(ref _browserLaunchAttempted, static (set, projectNode) => set.Add(projectNode), projectNode))
ImmutableInterlocked.Update(ref _browserLaunchAttempted, static (set, key) => set.Add(key), GetProjectKey(projectNode)))
{
// first build iteration of a root project:
var launchUrl = GetLaunchUrl(launchProfile.LaunchUrl, match.Groups["url"].Value);
Expand Down
16 changes: 14 additions & 2 deletions src/BuiltInTools/dotnet-watch/Browser/BrowserRefreshServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ namespace Microsoft.DotNet.Watch
{
/// <summary>
/// Communicates with aspnetcore-browser-refresh.js loaded in the browser.
/// Associated with a project instance.
/// </summary>
internal sealed class BrowserRefreshServer : IAsyncDisposable, IStaticAssetChangeApplier
{
private static readonly ReadOnlyMemory<byte> s_reloadMessage = Encoding.UTF8.GetBytes("Reload");
private static readonly ReadOnlyMemory<byte> s_waitMessage = Encoding.UTF8.GetBytes("Wait");
private static readonly JsonSerializerOptions s_jsonSerializerOptions = new(JsonSerializerDefaults.Web);

private static bool? s_lazyTlsSupported;

private readonly List<BrowserConnection> _activeConnections = [];
private readonly RSA _rsa;
private readonly IReporter _reporter;
Expand Down Expand Up @@ -326,16 +329,25 @@ public async ValueTask SendAndReceiveAsync<TRequest>(

private async Task<bool> SupportsTlsAsync()
{
var result = s_lazyTlsSupported;
if (result.HasValue)
{
return result.Value;
}

try
{
using var process = Process.Start(Options.MuxerPath, "dev-certs https --check --quiet");
await process.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(10));
return process.ExitCode == 0;
result = process.ExitCode == 0;
}
catch
{
return false;
result = false;
}

s_lazyTlsSupported = result;
return result.Value;
}

public ValueTask RefreshBrowserAsync(CancellationToken cancellationToken)
Expand Down
2 changes: 1 addition & 1 deletion src/BuiltInTools/dotnet-watch/HotReloadDotNetWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public override async Task WatchAsync(CancellationToken shutdownCancellationToke
Context.Reporter.Output(hotReloadEnabledMessage, emoji: "🔥");
}

await using var browserConnector = new BrowserConnector(Context);
using var fileWatcher = new FileWatcher(Context.Reporter);

for (var iteration = 0; !shutdownCancellationToken.IsCancellationRequested; iteration++)
Expand Down Expand Up @@ -98,7 +99,6 @@ public override async Task WatchAsync(CancellationToken shutdownCancellationToke
Context.Reporter.Verbose("Using Aspire process launcher.");
}

await using var browserConnector = new BrowserConnector(Context);
var projectMap = new ProjectNodeMap(evaluationResult.ProjectGraph, Context.Reporter);
compilationHandler = new CompilationHandler(Context.Reporter, Context.EnvironmentOptions, shutdownCancellationToken);
var scopedCssFileHandler = new ScopedCssFileHandler(Context.Reporter, projectMap, browserConnector);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Build.Graph;

namespace Microsoft.DotNet.Watch;

internal sealed class BrowserSpecificReporter(int browserId, IReporter underlyingReporter) : IReporter
Expand All @@ -12,14 +10,8 @@ internal sealed class BrowserSpecificReporter(int browserId, IReporter underlyin
public bool IsVerbose
=> underlyingReporter.IsVerbose;

public bool EnableProcessOutputReporting
=> false;

public void ReportProcessOutput(ProjectGraphNode project, OutputLine line)
=> throw new InvalidOperationException();

public void ReportProcessOutput(OutputLine line)
=> throw new InvalidOperationException();
=> underlyingReporter.ReportProcessOutput(line);

public void Report(MessageDescriptor descriptor, string prefix, object?[] args)
=> underlyingReporter.Report(descriptor, _prefix + prefix, args);
Expand Down
17 changes: 7 additions & 10 deletions src/BuiltInTools/dotnet-watch/Internal/ConsoleReporter.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Build.Graph;

namespace Microsoft.DotNet.Watch
{
/// <summary>
Expand All @@ -15,16 +13,15 @@ internal sealed class ConsoleReporter(IConsole console, bool verbose, bool quiet
public bool IsQuiet { get; } = quiet;
public bool SuppressEmojis { get; } = suppressEmojis;

private readonly object _writeLock = new();

public bool EnableProcessOutputReporting
=> false;
private readonly Lock _writeLock = new();

public void ReportProcessOutput(OutputLine line)
=> throw new InvalidOperationException();

public void ReportProcessOutput(ProjectGraphNode project, OutputLine line)
=> throw new InvalidOperationException();
{
lock (_writeLock)
{
(line.IsError ? console.Error : console.Out).WriteLine(line.Content);
}
}

private void WriteLine(TextWriter writer, string message, ConsoleColor? color, string emoji)
{
Expand Down
12 changes: 9 additions & 3 deletions src/BuiltInTools/dotnet-watch/Internal/IReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,19 @@ public bool IsVerbose
=> false;

/// <summary>
/// True to call <see cref="ReportProcessOutput"/> when launched process writes to standard output.
/// If true, the output of the process will be prefixed with the project display name.
/// Used for testing.
/// </summary>
bool EnableProcessOutputReporting { get; }
public bool PrefixProcessOutput
=> false;

/// <summary>
/// Reports the output of a process that is being watched.
/// </summary>
/// <remarks>
/// Not used to report output of dotnet-build processed launched by dotnet-watch to build or evaluate projects.
/// </remarks>
void ReportProcessOutput(OutputLine line);
void ReportProcessOutput(ProjectGraphNode project, OutputLine line);

void Report(MessageDescriptor descriptor, params object?[] args)
=> Report(descriptor, prefix: "", args);
Expand Down
Loading

0 comments on commit 7dc5ce3

Please sign in to comment.