diff --git a/Directory.Packages.props b/Directory.Packages.props
index 568b021b857d..a009d6abf9fc 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -37,6 +37,7 @@
+
@@ -81,8 +82,6 @@
-
-
diff --git a/NuGet.config b/NuGet.config
index 2e6c417c5f7d..7a06aa9e3e33 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -31,8 +31,6 @@
-
-
diff --git a/eng/Publishing.props b/eng/Publishing.props
index 2eb794f98bb4..802134fadee4 100644
--- a/eng/Publishing.props
+++ b/eng/Publishing.props
@@ -43,6 +43,10 @@
+
+
+
+
-
-
-
+
diff --git a/eng/Version.Details.props b/eng/Version.Details.props
index c7629de2576b..285e073b2908 100644
--- a/eng/Version.Details.props
+++ b/eng/Version.Details.props
@@ -6,120 +6,121 @@ This file should be imported by eng/Versions.props
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-preview.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 18.1.0-preview-25521-106
- 18.1.0-preview-25521-106
- 10.0.0-beta.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 10.0.0-preview.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 2.0.0-preview.1.25521.106
- 2.2.0-beta.25521.106
- 11.0.0-beta.25521.106
- 11.0.0-beta.25521.106
- 11.0.0-beta.25521.106
- 11.0.0-beta.25521.106
- 11.0.0-beta.25521.106
- 11.0.0-beta.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 11.0.0-beta.25521.106
- 11.0.0-beta.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 15.0.0-alpha1.25521.106
- 10.0.0-rc.1.25521.106
- 5.3.0-1.25521.106
- 5.3.0-1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-preview.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 18.1.0-preview-25567-101
+ 18.1.0-preview-25567-101
+ 11.0.0-beta.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 10.0.0-preview.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 2.0.0-preview.1.25567.101
+ 2.2.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 15.0.0-alpha1.25567.101
+ 10.0.0-rc.3.25567.101
+ 5.3.0-1.25567.101
+ 5.3.0-1.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
10.0.0-preview.7.25377.103
- 10.0.0-preview.25521.106
- 10.0.0-rc.1.25521.106
- 18.1.0-preview-25521-106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-beta.25521.106
- 10.0.0-beta.25521.106
- 10.0.0-beta.25521.106
- 10.0.0-beta.25521.106
- 10.0.0-beta.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 11.0.100-alpha.25521.106
- 18.1.0-preview-25521-106
- 18.1.0-preview-25521-106
- 3.2.0-preview.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 2.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
- 10.0.0-rc.1.25521.106
+ 10.0.0-preview.25567.101
+ 10.0.0-rc.3.25567.101
+ 18.1.0-preview-25567-101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.0-beta.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 11.0.100-alpha.25567.101
+ 18.1.0-preview-25567-101
+ 18.1.0-preview-25567-101
+ 3.2.0-preview.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 3.0.0-alpha.1.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
+ 10.0.0-rc.3.25567.101
2.1.0
@@ -146,7 +147,7 @@ This file should be imported by eng/Versions.props
-
+
$(dotnetdevcertsPackageVersion)
$(dotnetuserjwtsPackageVersion)
$(dotnetusersecretsPackageVersion)
@@ -181,6 +182,7 @@ This file should be imported by eng/Versions.props
$(MicrosoftCodeAnalysisCSharpCodeStylePackageVersion)
$(MicrosoftCodeAnalysisCSharpFeaturesPackageVersion)
$(MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion)
+ $(MicrosoftCodeAnalysisExternalAccessHotReloadPackageVersion)
$(MicrosoftCodeAnalysisPublicApiAnalyzersPackageVersion)
$(MicrosoftCodeAnalysisRazorToolingInternalPackageVersion)
$(MicrosoftCodeAnalysisWorkspacesCommonPackageVersion)
@@ -195,8 +197,8 @@ This file should be imported by eng/Versions.props
$(MicrosoftDotNetSignToolPackageVersion)
$(MicrosoftDotNetWebItemTemplates100PackageVersion)
$(MicrosoftDotNetWebProjectTemplates100PackageVersion)
- $(MicrosoftDotNetXUnitExtensionsPackageVersion)
$(MicrosoftDotNetXliffTasksPackageVersion)
+ $(MicrosoftDotNetXUnitExtensionsPackageVersion)
$(MicrosoftExtensionsConfigurationIniPackageVersion)
$(MicrosoftExtensionsDependencyModelPackageVersion)
$(MicrosoftExtensionsFileProvidersAbstractionsPackageVersion)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 22cf917b852a..7ff30ffaac10 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,62 +1,62 @@
-
+
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
@@ -68,61 +68,61 @@
https://github.com/dotnet/dotnet
6a953e76162f3f079405f80e28664fa51b136740
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
https://github.com/nuget/nuget.client
@@ -193,45 +193,45 @@
https://github.com/nuget/nuget.client
97c64b5dfcc39b3babf6b3dfa828aa737860c145
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
+
+
+ https://github.com/dotnet/dotnet
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
https://github.com/microsoft/testfx
@@ -561,9 +565,9 @@
https://github.com/microsoft/testfx
b2b75ecb52bcff592001df6d08f5fffccd945fdd
-
+
https://github.com/dotnet/dotnet
- ce8b0d8b87e180c6c044ee5828bd4fffab60951d
+ f67b36f27be47c1fe753f85bfd86ba10fcdf4c4e
diff --git a/eng/Versions.props b/eng/Versions.props
index 9c3a258e46fc..277e2b929ef8 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -29,7 +29,6 @@
compiler API targeted by analyzer assemblies. This is mostly an issue on source-build as
in that build mode analyzer assemblies always target the live compiler API. -->
true
- true
true
diff --git a/eng/common/core-templates/steps/install-microbuild-impl.yml b/eng/common/core-templates/steps/install-microbuild-impl.yml
index 9fdf3a116774..b9e0143ee92a 100644
--- a/eng/common/core-templates/steps/install-microbuild-impl.yml
+++ b/eng/common/core-templates/steps/install-microbuild-impl.yml
@@ -20,15 +20,15 @@ parameters:
steps:
- ${{ if eq(parameters.enablePreviewMicrobuild, 'true') }}:
- task: MicroBuildSigningPluginPreview@4
- displayName: Install Preview MicroBuild plugin (Windows)
+ displayName: Install Preview MicroBuild plugin
inputs: ${{ parameters.microbuildTaskInputs }}
env: ${{ parameters.microbuildEnv }}
continueOnError: ${{ parameters.continueOnError }}
condition: ${{ parameters.condition }}
- ${{ else }}:
- task: MicroBuildSigningPlugin@4
- displayName: Install MicroBuild plugin (Windows)
+ displayName: Install MicroBuild plugin
inputs: ${{ parameters.microbuildTaskInputs }}
env: ${{ parameters.microbuildEnv }}
continueOnError: ${{ parameters.continueOnError }}
- condition: ${{ parameters.condition }}
\ No newline at end of file
+ condition: ${{ parameters.condition }}
diff --git a/eng/common/core-templates/steps/install-microbuild.yml b/eng/common/core-templates/steps/install-microbuild.yml
index 3d42d9a56615..f60e87e47202 100644
--- a/eng/common/core-templates/steps/install-microbuild.yml
+++ b/eng/common/core-templates/steps/install-microbuild.yml
@@ -21,16 +21,14 @@ parameters:
steps:
- ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- ${{ if eq(parameters.enableMicrobuildForMacAndLinux, 'true') }}:
- # Installing .NET 8 is required to use the MicroBuild signing plugin on non-Windows platforms
+ # Needed to download the MicroBuild plugin nupkgs on Mac and Linux when nuget.exe is unavailable
- task: UseDotNet@2
displayName: Install .NET 8.0 SDK for MicroBuild Plugin
inputs:
packageType: sdk
version: 8.0.x
- # Installing the SDK in a '.dotnet-microbuild' directory is required for signing.
- # See target FindDotNetPathForMicroBuild in arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
- # Do not remove '.dotnet-microbuild' from the path without changing the corresponding logic.
- installationPath: $(Agent.TempDirectory)/.dotnet-microbuild
+ installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet
+ workingDirectory: ${{ parameters.microBuildOutputFolder }}
condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
- script: |
diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml
index 10f825e270a0..5a927b4c7bcb 100644
--- a/eng/common/core-templates/steps/publish-logs.yml
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -26,8 +26,10 @@ steps:
# If the file exists - sensitive data for redaction will be sourced from it
# (single entry per line, lines starting with '# ' are considered comments and skipped)
arguments: -InputPath '$(System.DefaultWorkingDirectory)/PostBuildLogs'
- -BinlogToolVersion ${{parameters.BinlogToolVersion}}
+ -BinlogToolVersion '${{parameters.BinlogToolVersion}}'
-TokensFilePath '$(System.DefaultWorkingDirectory)/eng/BinlogSecretsRedactionFile.txt'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
'$(publishing-dnceng-devdiv-code-r-build-re)'
'$(MaestroAccessToken)'
'$(dn-bot-all-orgs-artifact-feeds-rw)'
diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml
index eff4573c6e5f..ac019e2d0337 100644
--- a/eng/common/core-templates/steps/source-index-stage1-publish.yml
+++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml
@@ -14,8 +14,8 @@ steps:
workingDirectory: $(Agent.TempDirectory)
- script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
displayName: "Source Index: Download netsourceindex Tools"
# Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
workingDirectory: $(Agent.TempDirectory)
diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh
index f7bd4af0c8db..64b87d0bcc3c 100755
--- a/eng/common/native/install-dependencies.sh
+++ b/eng/common/native/install-dependencies.sh
@@ -27,7 +27,7 @@ case "$os" in
libssl-dev libkrb5-dev pigz cpio
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
- elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then
+ elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos"]; then
pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)"
$pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
elif [ "$ID" = "amzn" ]; then
diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1
index b7fc19591507..fc0218a013d1 100644
--- a/eng/common/post-build/redact-logs.ps1
+++ b/eng/common/post-build/redact-logs.ps1
@@ -7,7 +7,9 @@ param(
# File with strings to redact - separated by newlines.
# For comments start the line with '# ' - such lines are ignored
[Parameter(Mandatory=$false)][string] $TokensFilePath,
- [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact
+ [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeed,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey
)
try {
diff --git a/sdk.slnx b/sdk.slnx
index c8592eeb1f7b..5077b0285a6c 100644
--- a/sdk.slnx
+++ b/sdk.slnx
@@ -59,6 +59,8 @@
+
+
@@ -325,6 +327,8 @@
+
+
diff --git a/src/BuiltInTools/DotNetDeltaApplier/Microsoft.Extensions.DotNetDeltaApplier.csproj b/src/BuiltInTools/DotNetDeltaApplier/Microsoft.Extensions.DotNetDeltaApplier.csproj
index 87a397c3dd15..6391d60021e1 100644
--- a/src/BuiltInTools/DotNetDeltaApplier/Microsoft.Extensions.DotNetDeltaApplier.csproj
+++ b/src/BuiltInTools/DotNetDeltaApplier/Microsoft.Extensions.DotNetDeltaApplier.csproj
@@ -8,6 +8,8 @@
-->
net6.0;net10.0
MicrosoftAspNetCore
+
+ true
diff --git a/src/BuiltInTools/Watch.Aspire/DotNetWatchLauncher.cs b/src/BuiltInTools/Watch.Aspire/DotNetWatchLauncher.cs
new file mode 100644
index 000000000000..260b35c23042
--- /dev/null
+++ b/src/BuiltInTools/Watch.Aspire/DotNetWatchLauncher.cs
@@ -0,0 +1,84 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.DotNet.Watch;
+
+internal static class DotNetWatchLauncher
+{
+ public static async Task RunAsync(string workingDirectory, DotNetWatchOptions options)
+ {
+ var globalOptions = new GlobalOptions()
+ {
+ Quiet = options.IsQuiet,
+ Verbose = options.IsVerbose,
+ NoHotReload = false,
+ NonInteractive = true,
+ };
+
+ var commandArguments = new List();
+ if (options.NoLaunchProfile)
+ {
+ commandArguments.Add("--no-launch-profile");
+ }
+
+ commandArguments.AddRange(options.ApplicationArguments);
+
+ var rootProjectOptions = new ProjectOptions()
+ {
+ IsRootProject = true,
+ ProjectPath = options.ProjectPath,
+ WorkingDirectory = workingDirectory,
+ TargetFramework = null,
+ BuildArguments = [],
+ NoLaunchProfile = options.NoLaunchProfile,
+ LaunchProfileName = null,
+ Command = "run",
+ CommandArguments = [.. commandArguments],
+ LaunchEnvironmentVariables = [],
+ };
+
+ var muxerPath = Path.GetFullPath(Path.Combine(options.SdkDirectory, "..", "..", "dotnet" + PathUtilities.ExecutableExtension));
+
+ var console = new PhysicalConsole(TestFlags.None);
+ var reporter = new ConsoleReporter(console, globalOptions.Verbose, globalOptions.Quiet, suppressEmojis: false);
+ var environmentOptions = EnvironmentOptions.FromEnvironment(muxerPath);
+ var processRunner = new ProcessRunner(environmentOptions.GetProcessCleanupTimeout(isHotReloadEnabled: true));
+ var loggerFactory = new LoggerFactory(reporter);
+ var logger = loggerFactory.CreateLogger(DotNetWatchContext.DefaultLogComponentName);
+
+ using var context = new DotNetWatchContext()
+ {
+ ProcessOutputReporter = reporter,
+ LoggerFactory = loggerFactory,
+ Logger = logger,
+ BuildLogger = loggerFactory.CreateLogger(DotNetWatchContext.BuildLogComponentName),
+ ProcessRunner = processRunner,
+ Options = globalOptions,
+ EnvironmentOptions = environmentOptions,
+ RootProjectOptions = rootProjectOptions,
+ BrowserRefreshServerFactory = new BrowserRefreshServerFactory(),
+ BrowserLauncher = new BrowserLauncher(logger, reporter, environmentOptions),
+ };
+
+ using var shutdownHandler = new ShutdownHandler(console, logger);
+
+ try
+ {
+ var watcher = new HotReloadDotNetWatcher(context, console, runtimeProcessLauncherFactory: null);
+ await watcher.WatchAsync(shutdownHandler.CancellationToken);
+ }
+ catch (OperationCanceledException) when (shutdownHandler.CancellationToken.IsCancellationRequested)
+ {
+ // Ctrl+C forced an exit
+ }
+ catch (Exception e)
+ {
+ logger.LogError("An unexpected error occurred: {Exception}", e.ToString());
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/BuiltInTools/Watch.Aspire/DotNetWatchOptions.cs b/src/BuiltInTools/Watch.Aspire/DotNetWatchOptions.cs
new file mode 100644
index 000000000000..2ccf84b885b5
--- /dev/null
+++ b/src/BuiltInTools/Watch.Aspire/DotNetWatchOptions.cs
@@ -0,0 +1,82 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Immutable;
+using System.CommandLine;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Microsoft.DotNet.Watch;
+
+internal sealed class DotNetWatchOptions
+{
+ ///
+ /// The .NET SDK directory to load msbuild from (e.g. C:\Program Files\dotnet\sdk\10.0.100).
+ /// Also used to locate `dotnet` executable.
+ ///
+ public required string SdkDirectory { get; init; }
+
+ public required string ProjectPath { get; init; }
+ public required ImmutableArray ApplicationArguments { get; init; }
+ public bool IsVerbose { get; init; }
+ public bool IsQuiet { get; init; }
+ public bool NoLaunchProfile { get; init; }
+
+ public static bool TryParse(string[] args, [NotNullWhen(true)] out DotNetWatchOptions? options)
+ {
+ var sdkOption = new Option("--sdk") { Arity = ArgumentArity.ExactlyOne, Required = true, AllowMultipleArgumentsPerToken = false };
+ var projectOption = new Option("--project") { Arity = ArgumentArity.ExactlyOne, Required = true, AllowMultipleArgumentsPerToken = false };
+ var quietOption = new Option("--quiet") { Arity = ArgumentArity.Zero };
+ var verboseOption = new Option("--verbose") { Arity = ArgumentArity.Zero };
+ var noLaunchProfileOption = new Option("--no-launch-profile") { Arity = ArgumentArity.Zero };
+ var applicationArguments = new Argument("arguments") { Arity = ArgumentArity.ZeroOrMore };
+
+ verboseOption.Validators.Add(v =>
+ {
+ if (v.GetValue(quietOption) && v.GetValue(verboseOption))
+ {
+ v.AddError("Cannot specify both '--quiet' and '--verbose' options.");
+ }
+ });
+
+ var rootCommand = new RootCommand()
+ {
+ Directives = { new EnvironmentVariablesDirective() },
+ Options =
+ {
+ sdkOption,
+ projectOption,
+ quietOption,
+ verboseOption,
+ noLaunchProfileOption
+ },
+ Arguments =
+ {
+ applicationArguments
+ }
+ };
+
+ var parseResult = rootCommand.Parse(args);
+ if (parseResult.Errors.Count > 0)
+ {
+ foreach (var error in parseResult.Errors)
+ {
+ Console.Error.WriteLine(error);
+ }
+
+ options = null;
+ return false;
+ }
+
+ options = new DotNetWatchOptions()
+ {
+ SdkDirectory = parseResult.GetRequiredValue(sdkOption),
+ ProjectPath = parseResult.GetRequiredValue(projectOption),
+ IsQuiet = parseResult.GetValue(quietOption),
+ IsVerbose = parseResult.GetValue(verboseOption),
+ ApplicationArguments = [.. parseResult.GetValue(applicationArguments) ?? []],
+ NoLaunchProfile = parseResult.GetValue(noLaunchProfileOption),
+ };
+
+ return true;
+ }
+}
diff --git a/src/BuiltInTools/Watch.Aspire/Microsoft.DotNet.HotReload.Watch.Aspire.csproj b/src/BuiltInTools/Watch.Aspire/Microsoft.DotNet.HotReload.Watch.Aspire.csproj
new file mode 100644
index 000000000000..fb08c258b800
--- /dev/null
+++ b/src/BuiltInTools/Watch.Aspire/Microsoft.DotNet.HotReload.Watch.Aspire.csproj
@@ -0,0 +1,40 @@
+
+
+
+
+ $(SdkTargetFramework)
+ MicrosoftAspNetCore
+ Exe
+ Microsoft.DotNet.Watch
+ true
+
+
+ true
+ true
+ true
+ Microsoft.DotNet.HotReload.Watch.Aspire
+
+ A supporting package for Aspire CLI:
+ https://github.com/dotnet/aspire
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BuiltInTools/Watch.Aspire/Program.cs b/src/BuiltInTools/Watch.Aspire/Program.cs
new file mode 100644
index 000000000000..37de5ceca579
--- /dev/null
+++ b/src/BuiltInTools/Watch.Aspire/Program.cs
@@ -0,0 +1,12 @@
+using Microsoft.Build.Locator;
+using Microsoft.DotNet.Watch;
+
+if (!DotNetWatchOptions.TryParse(args, out var options))
+{
+ return -1;
+}
+
+MSBuildLocator.RegisterMSBuildPath(options.SdkDirectory);
+
+var workingDirectory = Directory.GetCurrentDirectory();
+return await DotNetWatchLauncher.RunAsync(workingDirectory, options) ? 0 : 1;
diff --git a/src/BuiltInTools/Watch.Aspire/Properties/AssemblyInfo.cs b/src/BuiltInTools/Watch.Aspire/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000000..74a1e15ab7a8
--- /dev/null
+++ b/src/BuiltInTools/Watch.Aspire/Properties/AssemblyInfo.cs
@@ -0,0 +1,7 @@
+// 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.CompilerServices;
+
+[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Watch.Aspire.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/BlazorWebAssemblyAppModel.cs b/src/BuiltInTools/Watch/AppModels/BlazorWebAssemblyAppModel.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/AppModels/BlazorWebAssemblyAppModel.cs
rename to src/BuiltInTools/Watch/AppModels/BlazorWebAssemblyAppModel.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/BlazorWebAssemblyHostedAppModel.cs b/src/BuiltInTools/Watch/AppModels/BlazorWebAssemblyHostedAppModel.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/AppModels/BlazorWebAssemblyHostedAppModel.cs
rename to src/BuiltInTools/Watch/AppModels/BlazorWebAssemblyHostedAppModel.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/DefaultAppModel.cs b/src/BuiltInTools/Watch/AppModels/DefaultAppModel.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/AppModels/DefaultAppModel.cs
rename to src/BuiltInTools/Watch/AppModels/DefaultAppModel.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/HotReloadAppModel.cs b/src/BuiltInTools/Watch/AppModels/HotReloadAppModel.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/AppModels/HotReloadAppModel.cs
rename to src/BuiltInTools/Watch/AppModels/HotReloadAppModel.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/WebApplicationAppModel.cs b/src/BuiltInTools/Watch/AppModels/WebApplicationAppModel.cs
similarity index 97%
rename from src/BuiltInTools/dotnet-watch/HotReload/AppModels/WebApplicationAppModel.cs
rename to src/BuiltInTools/Watch/AppModels/WebApplicationAppModel.cs
index 4ca515a862a6..cefcd43cf320 100644
--- a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/WebApplicationAppModel.cs
+++ b/src/BuiltInTools/Watch/AppModels/WebApplicationAppModel.cs
@@ -40,7 +40,7 @@ internal abstract class WebApplicationAppModel(DotNetWatchContext context) : Hot
protected WebAssemblyHotReloadClient CreateWebAssemblyClient(ILogger clientLogger, ILogger agentLogger, BrowserRefreshServer browserRefreshServer, ProjectGraphNode clientProject)
{
var capabilities = clientProject.GetWebAssemblyCapabilities().ToImmutableArray();
- var targetFramework = clientProject.GetTargetFrameworkVersion() ?? throw new InvalidOperationException("Project doesn't define TargetFrameworkVersion");
+ var targetFramework = clientProject.GetTargetFrameworkVersion() ?? throw new InvalidOperationException($"Project doesn't define {PropertyNames.TargetFrameworkMoniker}");
return new WebAssemblyHotReloadClient(clientLogger, agentLogger, browserRefreshServer, capabilities, targetFramework, context.EnvironmentOptions.TestFlags.HasFlag(TestFlags.MockBrowser));
}
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/AppModels/WebServerAppModel.cs b/src/BuiltInTools/Watch/AppModels/WebServerAppModel.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/AppModels/WebServerAppModel.cs
rename to src/BuiltInTools/Watch/AppModels/WebServerAppModel.cs
diff --git a/src/BuiltInTools/dotnet-watch/Aspire/AspireServiceFactory.cs b/src/BuiltInTools/Watch/Aspire/AspireServiceFactory.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Aspire/AspireServiceFactory.cs
rename to src/BuiltInTools/Watch/Aspire/AspireServiceFactory.cs
diff --git a/src/BuiltInTools/dotnet-watch/Browser/BrowserLauncher.cs b/src/BuiltInTools/Watch/Browser/BrowserLauncher.cs
similarity index 98%
rename from src/BuiltInTools/dotnet-watch/Browser/BrowserLauncher.cs
rename to src/BuiltInTools/Watch/Browser/BrowserLauncher.cs
index c841191e0208..de999b11e0a5 100644
--- a/src/BuiltInTools/dotnet-watch/Browser/BrowserLauncher.cs
+++ b/src/BuiltInTools/Watch/Browser/BrowserLauncher.cs
@@ -108,7 +108,7 @@ private bool CanLaunchBrowser(ProjectOptions projectOptions, [NotNullWhen(true)]
return false;
}
- if (!CommandLineOptions.IsCodeExecutionCommand(projectOptions.Command))
+ if (!projectOptions.IsCodeExecutionCommand)
{
logger.LogDebug("Command '{Command}' does not support launching browsers.", projectOptions.Command);
return false;
diff --git a/src/BuiltInTools/dotnet-watch/Browser/BrowserRefreshServerFactory.cs b/src/BuiltInTools/Watch/Browser/BrowserRefreshServerFactory.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Browser/BrowserRefreshServerFactory.cs
rename to src/BuiltInTools/Watch/Browser/BrowserRefreshServerFactory.cs
diff --git a/src/BuiltInTools/dotnet-watch/Build/BuildNames.cs b/src/BuiltInTools/Watch/Build/BuildNames.cs
similarity index 97%
rename from src/BuiltInTools/dotnet-watch/Build/BuildNames.cs
rename to src/BuiltInTools/Watch/Build/BuildNames.cs
index d92d5af86c14..f5f8c3463a3f 100644
--- a/src/BuiltInTools/dotnet-watch/Build/BuildNames.cs
+++ b/src/BuiltInTools/Watch/Build/BuildNames.cs
@@ -7,6 +7,7 @@ internal static class PropertyNames
{
public const string TargetFramework = nameof(TargetFramework);
public const string TargetFrameworkIdentifier = nameof(TargetFrameworkIdentifier);
+ public const string TargetFrameworkMoniker = nameof(TargetFrameworkMoniker);
public const string TargetPath = nameof(TargetPath);
public const string EnableDefaultItems = nameof(EnableDefaultItems);
public const string TargetFrameworks = nameof(TargetFrameworks);
diff --git a/src/BuiltInTools/dotnet-watch/Build/BuildReporter.cs b/src/BuiltInTools/Watch/Build/BuildReporter.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Build/BuildReporter.cs
rename to src/BuiltInTools/Watch/Build/BuildReporter.cs
diff --git a/src/BuiltInTools/Watch/Build/BuildUtilities.cs b/src/BuiltInTools/Watch/Build/BuildUtilities.cs
new file mode 100644
index 000000000000..1a336530697e
--- /dev/null
+++ b/src/BuiltInTools/Watch/Build/BuildUtilities.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.Watch;
+
+internal static class BuildUtilities
+{
+ // Parses name=value pairs passed to --property. Skips invalid input.
+ public static IEnumerable<(string key, string value)> ParseBuildProperties(IEnumerable arguments)
+ => from argument in arguments
+ let colon = argument.IndexOf(':')
+ where colon >= 0 && argument[0..colon] is "--property" or "-property" or "/property" or "/p" or "-p" or "--p"
+ let eq = argument.IndexOf('=', colon)
+ where eq >= 0
+ let name = argument[(colon + 1)..eq].Trim()
+ let value = argument[(eq + 1)..]
+ where name is not []
+ select (name, value);
+}
diff --git a/src/BuiltInTools/dotnet-watch/Build/EvaluationResult.cs b/src/BuiltInTools/Watch/Build/EvaluationResult.cs
similarity index 99%
rename from src/BuiltInTools/dotnet-watch/Build/EvaluationResult.cs
rename to src/BuiltInTools/Watch/Build/EvaluationResult.cs
index d4090ce69840..bb04a3683a7e 100644
--- a/src/BuiltInTools/dotnet-watch/Build/EvaluationResult.cs
+++ b/src/BuiltInTools/Watch/Build/EvaluationResult.cs
@@ -36,7 +36,7 @@ public static ImmutableDictionary GetGlobalBuildOptions(IEnumera
{
// See https://github.com/dotnet/project-system/blob/main/docs/well-known-project-properties.md
- return CommandLineOptions.ParseBuildProperties(buildArguments)
+ return BuildUtilities.ParseBuildProperties(buildArguments)
.ToImmutableDictionary(keySelector: arg => arg.key, elementSelector: arg => arg.value)
.SetItem(PropertyNames.DotNetWatchBuild, "true")
.SetItem(PropertyNames.DesignTimeBuild, "true")
diff --git a/src/BuiltInTools/dotnet-watch/Build/FileItem.cs b/src/BuiltInTools/Watch/Build/FileItem.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Build/FileItem.cs
rename to src/BuiltInTools/Watch/Build/FileItem.cs
diff --git a/src/BuiltInTools/dotnet-watch/Build/FilePathExclusions.cs b/src/BuiltInTools/Watch/Build/FilePathExclusions.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Build/FilePathExclusions.cs
rename to src/BuiltInTools/Watch/Build/FilePathExclusions.cs
diff --git a/src/BuiltInTools/dotnet-watch/Build/ProjectGraphFactory.cs b/src/BuiltInTools/Watch/Build/ProjectGraphFactory.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Build/ProjectGraphFactory.cs
rename to src/BuiltInTools/Watch/Build/ProjectGraphFactory.cs
diff --git a/src/BuiltInTools/dotnet-watch/Build/ProjectGraphUtilities.cs b/src/BuiltInTools/Watch/Build/ProjectGraphUtilities.cs
similarity index 95%
rename from src/BuiltInTools/dotnet-watch/Build/ProjectGraphUtilities.cs
rename to src/BuiltInTools/Watch/Build/ProjectGraphUtilities.cs
index 6cb4c6b57a04..40314297b76a 100644
--- a/src/BuiltInTools/dotnet-watch/Build/ProjectGraphUtilities.cs
+++ b/src/BuiltInTools/Watch/Build/ProjectGraphUtilities.cs
@@ -1,9 +1,9 @@
// 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.Versioning;
using Microsoft.Build.Execution;
using Microsoft.Build.Graph;
-using Microsoft.DotNet.Cli;
namespace Microsoft.DotNet.Watch;
@@ -19,7 +19,16 @@ public static IEnumerable GetTargetFrameworks(this ProjectGraphNode proj
=> projectNode.GetStringListPropertyValue(PropertyNames.TargetFrameworks);
public static Version? GetTargetFrameworkVersion(this ProjectGraphNode projectNode)
- => EnvironmentVariableNames.TryParseTargetFrameworkVersion(projectNode.ProjectInstance.GetPropertyValue(PropertyNames.TargetFrameworkVersion));
+ {
+ try
+ {
+ return new FrameworkName(projectNode.ProjectInstance.GetPropertyValue(PropertyNames.TargetFrameworkMoniker)).Version;
+ }
+ catch
+ {
+ return null;
+ }
+ }
public static IEnumerable GetWebAssemblyCapabilities(this ProjectGraphNode projectNode)
=> projectNode.GetStringListPropertyValue(PropertyNames.WebAssemblyHotReloadCapabilities);
diff --git a/src/BuiltInTools/dotnet-watch/Build/ProjectInstanceId.cs b/src/BuiltInTools/Watch/Build/ProjectInstanceId.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Build/ProjectInstanceId.cs
rename to src/BuiltInTools/Watch/Build/ProjectInstanceId.cs
diff --git a/src/BuiltInTools/dotnet-watch/Build/ProjectNodeMap.cs b/src/BuiltInTools/Watch/Build/ProjectNodeMap.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Build/ProjectNodeMap.cs
rename to src/BuiltInTools/Watch/Build/ProjectNodeMap.cs
diff --git a/src/BuiltInTools/dotnet-watch/CommandLine/DotNetWatchContext.cs b/src/BuiltInTools/Watch/Context/DotNetWatchContext.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/CommandLine/DotNetWatchContext.cs
rename to src/BuiltInTools/Watch/Context/DotNetWatchContext.cs
diff --git a/src/BuiltInTools/dotnet-watch/CommandLine/EnvironmentOptions.cs b/src/BuiltInTools/Watch/Context/EnvironmentOptions.cs
similarity index 88%
rename from src/BuiltInTools/dotnet-watch/CommandLine/EnvironmentOptions.cs
rename to src/BuiltInTools/Watch/Context/EnvironmentOptions.cs
index d0e84844de86..20b850688437 100644
--- a/src/BuiltInTools/dotnet-watch/CommandLine/EnvironmentOptions.cs
+++ b/src/BuiltInTools/Watch/Context/EnvironmentOptions.cs
@@ -41,10 +41,10 @@ internal sealed record EnvironmentOptions(
TestFlags TestFlags = TestFlags.None,
string TestOutput = "")
{
- public static EnvironmentOptions FromEnvironment() => new
+ public static EnvironmentOptions FromEnvironment(string muxerPath) => new
(
WorkingDirectory: Directory.GetCurrentDirectory(),
- MuxerPath: GetMuxerPathFromEnvironment(),
+ MuxerPath: ValidateMuxerPath(muxerPath),
ProcessCleanupTimeout: EnvironmentVariables.ProcessCleanupTimeout,
IsPollingEnabled: EnvironmentVariables.IsPollingEnabled,
SuppressHandlingStaticContentFiles: EnvironmentVariables.SuppressHandlingStaticContentFiles,
@@ -69,12 +69,10 @@ public TimeSpan GetProcessCleanupTimeout(bool isHotReloadEnabled)
public bool RunningAsTest { get => (TestFlags & TestFlags.RunningAsTest) != TestFlags.None; }
- private static string GetMuxerPathFromEnvironment()
+ private static string ValidateMuxerPath(string path)
{
- var muxerPath = Environment.ProcessPath;
- Debug.Assert(muxerPath != null);
- Debug.Assert(Path.GetFileNameWithoutExtension(muxerPath) == "dotnet", $"Invalid muxer path {muxerPath}");
- return muxerPath;
+ Debug.Assert(Path.GetFileNameWithoutExtension(path) == "dotnet");
+ return path;
}
public string? GetBinLogPath(string projectPath, string operationName, GlobalOptions options)
diff --git a/src/BuiltInTools/dotnet-watch/CommandLine/EnvironmentVariables.cs b/src/BuiltInTools/Watch/Context/EnvironmentVariables.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/CommandLine/EnvironmentVariables.cs
rename to src/BuiltInTools/Watch/Context/EnvironmentVariables.cs
diff --git a/src/BuiltInTools/dotnet-watch/CommandLine/GlobalOptions.cs b/src/BuiltInTools/Watch/Context/GlobalOptions.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/CommandLine/GlobalOptions.cs
rename to src/BuiltInTools/Watch/Context/GlobalOptions.cs
diff --git a/src/BuiltInTools/dotnet-watch/CommandLine/ProjectOptions.cs b/src/BuiltInTools/Watch/Context/ProjectOptions.cs
similarity index 85%
rename from src/BuiltInTools/dotnet-watch/CommandLine/ProjectOptions.cs
rename to src/BuiltInTools/Watch/Context/ProjectOptions.cs
index 12b8b889f1f7..20eb2eed69eb 100644
--- a/src/BuiltInTools/dotnet-watch/CommandLine/ProjectOptions.cs
+++ b/src/BuiltInTools/Watch/Context/ProjectOptions.cs
@@ -27,4 +27,10 @@ internal sealed record ProjectOptions
/// Additional environment variables to set to the running process.
///
public required IReadOnlyList<(string name, string value)> LaunchEnvironmentVariables { get; init; }
+
+ ///
+ /// Returns true if the command executes the code of the target project.
+ ///
+ public bool IsCodeExecutionCommand
+ => Command is "run" or "test";
}
diff --git a/src/BuiltInTools/dotnet-watch/FileWatcher/ChangeKind.cs b/src/BuiltInTools/Watch/FileWatcher/ChangeKind.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/FileWatcher/ChangeKind.cs
rename to src/BuiltInTools/Watch/FileWatcher/ChangeKind.cs
diff --git a/src/BuiltInTools/dotnet-watch/FileWatcher/DirectoryWatcher.cs b/src/BuiltInTools/Watch/FileWatcher/DirectoryWatcher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/FileWatcher/DirectoryWatcher.cs
rename to src/BuiltInTools/Watch/FileWatcher/DirectoryWatcher.cs
diff --git a/src/BuiltInTools/dotnet-watch/FileWatcher/EventBasedDirectoryWatcher.cs b/src/BuiltInTools/Watch/FileWatcher/EventBasedDirectoryWatcher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/FileWatcher/EventBasedDirectoryWatcher.cs
rename to src/BuiltInTools/Watch/FileWatcher/EventBasedDirectoryWatcher.cs
diff --git a/src/BuiltInTools/dotnet-watch/FileWatcher/FileWatcher.cs b/src/BuiltInTools/Watch/FileWatcher/FileWatcher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/FileWatcher/FileWatcher.cs
rename to src/BuiltInTools/Watch/FileWatcher/FileWatcher.cs
diff --git a/src/BuiltInTools/dotnet-watch/FileWatcher/PollingDirectoryWatcher.cs b/src/BuiltInTools/Watch/FileWatcher/PollingDirectoryWatcher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/FileWatcher/PollingDirectoryWatcher.cs
rename to src/BuiltInTools/Watch/FileWatcher/PollingDirectoryWatcher.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/CompilationHandler.cs b/src/BuiltInTools/Watch/HotReload/CompilationHandler.cs
similarity index 95%
rename from src/BuiltInTools/dotnet-watch/HotReload/CompilationHandler.cs
rename to src/BuiltInTools/Watch/HotReload/CompilationHandler.cs
index 55770d524293..2929d4f1e71e 100644
--- a/src/BuiltInTools/dotnet-watch/HotReload/CompilationHandler.cs
+++ b/src/BuiltInTools/Watch/HotReload/CompilationHandler.cs
@@ -6,7 +6,7 @@
using Microsoft.Build.Graph;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.ExternalAccess.Watch.Api;
+using Microsoft.CodeAnalysis.ExternalAccess.HotReload.Api;
using Microsoft.DotNet.HotReload;
using Microsoft.Extensions.Logging;
@@ -16,7 +16,7 @@ internal sealed class CompilationHandler : IDisposable
{
public readonly IncrementalMSBuildWorkspace Workspace;
private readonly ILogger _logger;
- private readonly WatchHotReloadService _hotReloadService;
+ private readonly HotReloadService _hotReloadService;
private readonly ProcessRunner _processRunner;
///
@@ -35,7 +35,7 @@ internal sealed class CompilationHandler : IDisposable
///
/// All updates that were attempted. Includes updates whose application failed.
///
- private ImmutableList _previousUpdates = [];
+ private ImmutableList _previousUpdates = [];
private bool _isDisposed;
@@ -44,7 +44,7 @@ public CompilationHandler(ILogger logger, ProcessRunner processRunner)
_logger = logger;
_processRunner = processRunner;
Workspace = new IncrementalMSBuildWorkspace(logger);
- _hotReloadService = new WatchHotReloadService(Workspace.CurrentSolution.Services, () => ValueTask.FromResult(GetAggregateCapabilities()));
+ _hotReloadService = new HotReloadService(Workspace.CurrentSolution.Services, () => ValueTask.FromResult(GetAggregateCapabilities()));
}
public void Dispose()
@@ -299,7 +299,7 @@ private static void PrepareCompilations(Solution solution, string projectPath, C
}
public async ValueTask<(
- ImmutableArray projectUpdates,
+ ImmutableArray projectUpdates,
ImmutableArray projectsToRebuild,
ImmutableArray projectsToRedeploy,
ImmutableArray projectsToRestart)> HandleManagedCodeChangesAsync(
@@ -315,14 +315,14 @@ private static void PrepareCompilations(Solution solution, string projectPath, C
let runningProject = GetCorrespondingRunningProject(project, runningProjects)
where runningProject != null
let autoRestartProject = autoRestart || runningProject.ProjectNode.IsAutoRestartEnabled()
- select (project.Id, info: new WatchHotReloadService.RunningProjectInfo() { RestartWhenChangesHaveNoEffect = autoRestartProject }))
+ select (project.Id, info: new HotReloadService.RunningProjectInfo() { RestartWhenChangesHaveNoEffect = autoRestartProject }))
.ToImmutableDictionary(e => e.Id, e => e.info);
var updates = await _hotReloadService.GetUpdatesAsync(currentSolution, runningProjectInfos, cancellationToken);
await DisplayResultsAsync(updates, runningProjectInfos, cancellationToken);
- if (updates.Status is WatchHotReloadService.Status.NoChangesToApply or WatchHotReloadService.Status.Blocked)
+ if (updates.Status is HotReloadService.Status.NoChangesToApply or HotReloadService.Status.Blocked)
{
// If Hot Reload is blocked (due to compilation error) we ignore the current
// changes and await the next file change.
@@ -364,7 +364,7 @@ private static void PrepareCompilations(Solution solution, string projectPath, C
return (updates.ProjectUpdates, projectsToRebuild, projectsToRedeploy, projectsToRestart);
}
- public async ValueTask ApplyUpdatesAsync(ImmutableArray updates, CancellationToken cancellationToken)
+ public async ValueTask ApplyUpdatesAsync(ImmutableArray updates, CancellationToken cancellationToken)
{
Debug.Assert(!updates.IsEmpty);
@@ -403,7 +403,7 @@ await ForEachProjectAsync(projectsToUpdate, async (runningProject, cancellationT
}
// msbuild workspace doesn't set TFM if the project is not multi-targeted
- var tfm = WatchHotReloadService.GetTargetFramework(project);
+ var tfm = HotReloadService.GetTargetFramework(project);
if (tfm == null)
{
return projectsWithPath[0];
@@ -412,18 +412,18 @@ await ForEachProjectAsync(projectsToUpdate, async (runningProject, cancellationT
return projectsWithPath.SingleOrDefault(p => string.Equals(p.ProjectNode.GetTargetFramework(), tfm, StringComparison.OrdinalIgnoreCase));
}
- private async ValueTask DisplayResultsAsync(WatchHotReloadService.Updates2 updates, ImmutableDictionary runningProjectInfos, CancellationToken cancellationToken)
+ private async ValueTask DisplayResultsAsync(HotReloadService.Updates updates, ImmutableDictionary runningProjectInfos, CancellationToken cancellationToken)
{
switch (updates.Status)
{
- case WatchHotReloadService.Status.ReadyToApply:
+ case HotReloadService.Status.ReadyToApply:
break;
- case WatchHotReloadService.Status.NoChangesToApply:
+ case HotReloadService.Status.NoChangesToApply:
_logger.Log(MessageDescriptor.NoCSharpChangesToApply);
break;
- case WatchHotReloadService.Status.Blocked:
+ case HotReloadService.Status.Blocked:
_logger.Log(MessageDescriptor.UnableToApplyChanges);
break;
@@ -451,7 +451,7 @@ await ForEachProjectAsync(
void ReportCompilationDiagnostics(DiagnosticSeverity severity)
{
- foreach (var diagnostic in updates.CompilationDiagnostics)
+ foreach (var diagnostic in updates.PersistentDiagnostics)
{
if (diagnostic.Id == "CS8002")
{
@@ -492,7 +492,7 @@ void ReportRudeEdits()
.Where(p => !updates.ProjectsToRestart.ContainsKey(p))
.ToHashSet();
- foreach (var (projectId, diagnostics) in updates.RudeEdits)
+ foreach (var (projectId, diagnostics) in updates.TransientDiagnostics)
{
foreach (var diagnostic in diagnostics)
{
@@ -689,7 +689,7 @@ public bool TryGetRunningProject(string projectPath, out ImmutableArray> projects, Func action, CancellationToken cancellationToken)
=> Task.WhenAll(projects.SelectMany(entry => entry.Value).Select(project => action(project, cancellationToken))).WaitAsync(cancellationToken);
- private static ImmutableArray ToManagedCodeUpdates(ImmutableArray updates)
+ private static ImmutableArray ToManagedCodeUpdates(ImmutableArray updates)
=> [.. updates.Select(update => new HotReloadManagedCodeUpdate(update.ModuleId, update.MetadataDelta, update.ILDelta, update.PdbDelta, update.UpdatedTypes, update.RequiredCapabilities))];
}
}
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/HotReloadDotNetWatcher.cs b/src/BuiltInTools/Watch/HotReload/HotReloadDotNetWatcher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/HotReloadDotNetWatcher.cs
rename to src/BuiltInTools/Watch/HotReload/HotReloadDotNetWatcher.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/HotReloadEventSource.cs b/src/BuiltInTools/Watch/HotReload/HotReloadEventSource.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/HotReloadEventSource.cs
rename to src/BuiltInTools/Watch/HotReload/HotReloadEventSource.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/IncrementalMSBuildWorkspace.cs b/src/BuiltInTools/Watch/HotReload/IncrementalMSBuildWorkspace.cs
similarity index 98%
rename from src/BuiltInTools/dotnet-watch/HotReload/IncrementalMSBuildWorkspace.cs
rename to src/BuiltInTools/Watch/HotReload/IncrementalMSBuildWorkspace.cs
index 65ab6089466c..06b79772ddf6 100644
--- a/src/BuiltInTools/dotnet-watch/HotReload/IncrementalMSBuildWorkspace.cs
+++ b/src/BuiltInTools/Watch/HotReload/IncrementalMSBuildWorkspace.cs
@@ -4,7 +4,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.ExternalAccess.Watch.Api;
+using Microsoft.CodeAnalysis.ExternalAccess.HotReload.Api;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;
@@ -76,7 +76,7 @@ public async Task UpdateProjectConeAsync(string rootProjectPath, CancellationTok
continue;
}
- newSolution = WatchHotReloadService.WithProjectInfo(newSolution, ProjectInfo.Create(
+ newSolution = HotReloadService.WithProjectInfo(newSolution, ProjectInfo.Create(
oldProjectId,
newProjectInfo.Version,
newProjectInfo.Name,
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/ScopedCssFileHandler.cs b/src/BuiltInTools/Watch/HotReload/ScopedCssFileHandler.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/ScopedCssFileHandler.cs
rename to src/BuiltInTools/Watch/HotReload/ScopedCssFileHandler.cs
diff --git a/src/BuiltInTools/dotnet-watch/HotReload/StaticFileHandler.cs b/src/BuiltInTools/Watch/HotReload/StaticFileHandler.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/HotReload/StaticFileHandler.cs
rename to src/BuiltInTools/Watch/HotReload/StaticFileHandler.cs
diff --git a/src/BuiltInTools/Watch/Microsoft.DotNet.HotReload.Watch.csproj b/src/BuiltInTools/Watch/Microsoft.DotNet.HotReload.Watch.csproj
new file mode 100644
index 000000000000..48e96f316ba5
--- /dev/null
+++ b/src/BuiltInTools/Watch/Microsoft.DotNet.HotReload.Watch.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+ $(SdkTargetFramework)
+ Library
+ Hot Reload watch implementation
+ Microsoft.DotNet.Watch
+ MicrosoftAspNetCore
+
+
+ $(NoWarn);CS9057
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BuiltInTools/dotnet-watch/Process/IRuntimeProcessLauncher.cs b/src/BuiltInTools/Watch/Process/IRuntimeProcessLauncher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/IRuntimeProcessLauncher.cs
rename to src/BuiltInTools/Watch/Process/IRuntimeProcessLauncher.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/IRuntimeProcessLauncherFactory.cs b/src/BuiltInTools/Watch/Process/IRuntimeProcessLauncherFactory.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/IRuntimeProcessLauncherFactory.cs
rename to src/BuiltInTools/Watch/Process/IRuntimeProcessLauncherFactory.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/LaunchSettingsProfile.cs b/src/BuiltInTools/Watch/Process/LaunchSettingsProfile.cs
similarity index 85%
rename from src/BuiltInTools/dotnet-watch/Process/LaunchSettingsProfile.cs
rename to src/BuiltInTools/Watch/Process/LaunchSettingsProfile.cs
index a1c6397bbf6f..1ec08ab04ea2 100644
--- a/src/BuiltInTools/dotnet-watch/Process/LaunchSettingsProfile.cs
+++ b/src/BuiltInTools/Watch/Process/LaunchSettingsProfile.cs
@@ -5,8 +5,6 @@
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
-using Microsoft.DotNet.Cli.Commands;
-using Microsoft.DotNet.Cli.Commands.Run;
using Microsoft.Extensions.Logging;
namespace Microsoft.DotNet.Watch
@@ -31,18 +29,18 @@ internal sealed class LaunchSettingsProfile
var projectDirectory = Path.GetDirectoryName(projectPath);
Debug.Assert(projectDirectory != null);
- var launchSettingsPath = CommonRunHelpers.GetPropertiesLaunchSettingsPath(projectDirectory, "Properties");
+ var launchSettingsPath = GetPropertiesLaunchSettingsPath(projectDirectory, "Properties");
bool hasLaunchSettings = File.Exists(launchSettingsPath);
var projectNameWithoutExtension = Path.GetFileNameWithoutExtension(projectPath);
- var runJsonPath = CommonRunHelpers.GetFlatLaunchSettingsPath(projectDirectory, projectNameWithoutExtension);
+ var runJsonPath = GetFlatLaunchSettingsPath(projectDirectory, projectNameWithoutExtension);
bool hasRunJson = File.Exists(runJsonPath);
if (hasLaunchSettings)
{
if (hasRunJson)
{
- logger.LogWarning(CliCommandStrings.RunCommandWarningRunJsonNotUsed, runJsonPath, launchSettingsPath);
+ logger.LogWarning("Warning: Settings from '{JsonPath}' are not used because '{LaunchSettingsPath}' has precedence.", runJsonPath, launchSettingsPath);
}
}
else if (hasRunJson)
@@ -98,6 +96,12 @@ internal sealed class LaunchSettingsProfile
return namedProfile;
}
+ private static string GetPropertiesLaunchSettingsPath(string directoryPath, string propertiesDirectoryName)
+ => Path.Combine(directoryPath, propertiesDirectoryName, "launchSettings.json");
+
+ private static string GetFlatLaunchSettingsPath(string directoryPath, string projectNameWithoutExtension)
+ => Path.Join(directoryPath, $"{projectNameWithoutExtension}.run.json");
+
private static LaunchSettingsProfile? ReadDefaultLaunchProfile(LaunchSettingsJson? launchSettings, ILogger logger)
{
if (launchSettings is null || launchSettings.Profiles is null)
diff --git a/src/BuiltInTools/dotnet-watch/Process/ProcessLaunchResult.cs b/src/BuiltInTools/Watch/Process/ProcessLaunchResult.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/ProcessLaunchResult.cs
rename to src/BuiltInTools/Watch/Process/ProcessLaunchResult.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/ProcessRunner.cs b/src/BuiltInTools/Watch/Process/ProcessRunner.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/ProcessRunner.cs
rename to src/BuiltInTools/Watch/Process/ProcessRunner.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/ProcessSpec.cs b/src/BuiltInTools/Watch/Process/ProcessSpec.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/ProcessSpec.cs
rename to src/BuiltInTools/Watch/Process/ProcessSpec.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/ProjectLauncher.cs b/src/BuiltInTools/Watch/Process/ProjectLauncher.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/ProjectLauncher.cs
rename to src/BuiltInTools/Watch/Process/ProjectLauncher.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/RunningProject.cs b/src/BuiltInTools/Watch/Process/RunningProject.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/RunningProject.cs
rename to src/BuiltInTools/Watch/Process/RunningProject.cs
diff --git a/src/BuiltInTools/dotnet-watch/Process/WebServerProcessStateObserver.cs b/src/BuiltInTools/Watch/Process/WebServerProcessStateObserver.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Process/WebServerProcessStateObserver.cs
rename to src/BuiltInTools/Watch/Process/WebServerProcessStateObserver.cs
diff --git a/src/BuiltInTools/Watch/Properties/AssemblyInfo.cs b/src/BuiltInTools/Watch/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000000..b54564628dc0
--- /dev/null
+++ b/src/BuiltInTools/Watch/Properties/AssemblyInfo.cs
@@ -0,0 +1,11 @@
+// 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.CompilerServices;
+
+[assembly: InternalsVisibleTo("dotnet-watch, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("dotnet-watch.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Test.Utilities, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Watch.Aspire, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Watch.Aspire.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/src/BuiltInTools/Watch/RuntimeDependencies.props b/src/BuiltInTools/Watch/RuntimeDependencies.props
new file mode 100644
index 000000000000..7d4d40a9ab8d
--- /dev/null
+++ b/src/BuiltInTools/Watch/RuntimeDependencies.props
@@ -0,0 +1,38 @@
+
+
+
+ None
+ true
+ false
+ TargetFramework;TargetFrameworks
+ hotreload\net6.0\Microsoft.AspNetCore.Watch.BrowserRefresh.dll
+ PreserveNewest
+
+
+ false
+
+
+
+ None
+ true
+ false
+ TargetFramework=net10.0
+ hotreload\net10.0\Microsoft.Extensions.DotNetDeltaApplier.dll
+ PreserveNewest
+ false
+
+
+
+ None
+ true
+ false
+ TargetFramework=net6.0
+ hotreload\net6.0\Microsoft.Extensions.DotNetDeltaApplier.dll
+ PreserveNewest
+ false
+
+
+
diff --git a/src/BuiltInTools/dotnet-watch/UI/BuildOutput.cs b/src/BuiltInTools/Watch/UI/BuildOutput.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/UI/BuildOutput.cs
rename to src/BuiltInTools/Watch/UI/BuildOutput.cs
diff --git a/src/BuiltInTools/dotnet-watch/UI/ConsoleInputReader.cs b/src/BuiltInTools/Watch/UI/ConsoleInputReader.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/UI/ConsoleInputReader.cs
rename to src/BuiltInTools/Watch/UI/ConsoleInputReader.cs
diff --git a/src/BuiltInTools/dotnet-watch/UI/ConsoleReporter.cs b/src/BuiltInTools/Watch/UI/ConsoleReporter.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/UI/ConsoleReporter.cs
rename to src/BuiltInTools/Watch/UI/ConsoleReporter.cs
diff --git a/src/BuiltInTools/Watch/UI/IConsole.cs b/src/BuiltInTools/Watch/UI/IConsole.cs
new file mode 100644
index 000000000000..54b1d8cfec76
--- /dev/null
+++ b/src/BuiltInTools/Watch/UI/IConsole.cs
@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.Watch;
+
+///
+/// This API supports infrastructure and is not intended to be used
+/// directly from your code. This API may change or be removed in future releases.
+///
+internal interface IConsole
+{
+ event Action KeyPressed;
+ TextWriter Out { get; }
+ TextWriter Error { get; }
+ ConsoleColor ForegroundColor { get; set; }
+ void ResetColor();
+ void Clear();
+}
diff --git a/src/BuiltInTools/dotnet-watch/UI/IReporter.cs b/src/BuiltInTools/Watch/UI/IReporter.cs
similarity index 99%
rename from src/BuiltInTools/dotnet-watch/UI/IReporter.cs
rename to src/BuiltInTools/Watch/UI/IReporter.cs
index 4224aefb4855..2a118db336ee 100644
--- a/src/BuiltInTools/dotnet-watch/UI/IReporter.cs
+++ b/src/BuiltInTools/Watch/UI/IReporter.cs
@@ -169,7 +169,6 @@ public MessageDescriptor WithSeverityWhen(MessageSeverity severity, bool conditi
: this;
public static readonly ImmutableDictionary ComponentEmojis = ImmutableDictionary.Empty
- .Add(Program.LogComponentName, Emoji.Watch)
.Add(DotNetWatchContext.DefaultLogComponentName, Emoji.Watch)
.Add(DotNetWatchContext.BuildLogComponentName, Emoji.Build)
.Add(HotReloadDotNetWatcher.ClientLogComponentName, Emoji.HotReload)
diff --git a/src/BuiltInTools/dotnet-watch/UI/OutputLine.cs b/src/BuiltInTools/Watch/UI/OutputLine.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/UI/OutputLine.cs
rename to src/BuiltInTools/Watch/UI/OutputLine.cs
diff --git a/src/BuiltInTools/dotnet-watch/UI/PhysicalConsole.cs b/src/BuiltInTools/Watch/UI/PhysicalConsole.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/UI/PhysicalConsole.cs
rename to src/BuiltInTools/Watch/UI/PhysicalConsole.cs
diff --git a/src/BuiltInTools/dotnet-watch/UI/RestartPrompt.cs b/src/BuiltInTools/Watch/UI/RestartPrompt.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/UI/RestartPrompt.cs
rename to src/BuiltInTools/Watch/UI/RestartPrompt.cs
diff --git a/src/BuiltInTools/Watch/UI/ShutdownHandler.cs b/src/BuiltInTools/Watch/UI/ShutdownHandler.cs
new file mode 100644
index 000000000000..70cc2355fe43
--- /dev/null
+++ b/src/BuiltInTools/Watch/UI/ShutdownHandler.cs
@@ -0,0 +1,44 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.DotNet.Watch;
+
+internal sealed class ShutdownHandler : IDisposable
+{
+ private readonly CancellationTokenSource _cancellationSource = new();
+ public CancellationToken CancellationToken { get; }
+
+ private volatile bool _disposed;
+
+ public ShutdownHandler(IConsole console, ILogger logger)
+ {
+ CancellationToken = _cancellationSource.Token;
+
+ console.KeyPressed += key =>
+ {
+ if (!_disposed && key.Modifiers.HasFlag(ConsoleModifiers.Control) && key.Key == ConsoleKey.C)
+ {
+ // if we already canceled, we force immediate shutdown:
+ var forceShutdown = _cancellationSource.IsCancellationRequested;
+
+ if (!forceShutdown)
+ {
+ logger.Log(MessageDescriptor.ShutdownRequested);
+ _cancellationSource.Cancel();
+ }
+ else
+ {
+ Environment.Exit(0);
+ }
+ }
+ };
+ }
+
+ public void Dispose()
+ {
+ _disposed = true;
+ _cancellationSource.Dispose();
+ }
+}
diff --git a/src/BuiltInTools/dotnet-watch/Utilities/CommandLineUtilities.cs b/src/BuiltInTools/Watch/Utilities/CommandLineUtilities.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Utilities/CommandLineUtilities.cs
rename to src/BuiltInTools/Watch/Utilities/CommandLineUtilities.cs
diff --git a/src/BuiltInTools/dotnet-watch/Utilities/Disposables.cs b/src/BuiltInTools/Watch/Utilities/Disposables.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Utilities/Disposables.cs
rename to src/BuiltInTools/Watch/Utilities/Disposables.cs
diff --git a/src/BuiltInTools/dotnet-watch/Utilities/PathUtilities.cs b/src/BuiltInTools/Watch/Utilities/PathUtilities.cs
similarity index 93%
rename from src/BuiltInTools/dotnet-watch/Utilities/PathUtilities.cs
rename to src/BuiltInTools/Watch/Utilities/PathUtilities.cs
index b3a1349ae8ca..e7f21ea13ac6 100644
--- a/src/BuiltInTools/dotnet-watch/Utilities/PathUtilities.cs
+++ b/src/BuiltInTools/Watch/Utilities/PathUtilities.cs
@@ -8,6 +8,9 @@ internal static class PathUtilities
public static readonly IEqualityComparer OSSpecificPathComparer = Path.DirectorySeparatorChar == '\\' ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
public static readonly StringComparison OSSpecificPathComparison = Path.DirectorySeparatorChar == '\\' ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+ public static string ExecutableExtension
+ => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "";
+
public static string EnsureTrailingSlash(string path)
=> (path is [.., var last] && last != Path.DirectorySeparatorChar) ? path + Path.DirectorySeparatorChar : path;
diff --git a/src/BuiltInTools/dotnet-watch/Utilities/ProcessUtilities.cs b/src/BuiltInTools/Watch/Utilities/ProcessUtilities.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Utilities/ProcessUtilities.cs
rename to src/BuiltInTools/Watch/Utilities/ProcessUtilities.cs
diff --git a/src/BuiltInTools/dotnet-watch/Utilities/Versions.cs b/src/BuiltInTools/Watch/Utilities/Versions.cs
similarity index 100%
rename from src/BuiltInTools/dotnet-watch/Utilities/Versions.cs
rename to src/BuiltInTools/Watch/Utilities/Versions.cs
diff --git a/src/BuiltInTools/dotnet-watch.slnf b/src/BuiltInTools/dotnet-watch.slnf
index a3cc85fc0d92..8e454226e0d0 100644
--- a/src/BuiltInTools/dotnet-watch.slnf
+++ b/src/BuiltInTools/dotnet-watch.slnf
@@ -20,6 +20,8 @@
"src\\BuiltInTools\\HotReloadClient\\Microsoft.DotNet.HotReload.Client.shproj",
"src\\BuiltInTools\\Web.Middleware\\Microsoft.DotNet.HotReload.Web.Middleware.Package.csproj",
"src\\BuiltInTools\\Web.Middleware\\Microsoft.DotNet.HotReload.Web.Middleware.shproj",
+ "src\\BuiltInTools\\Watch.Aspire\\Microsoft.DotNet.HotReload.Watch.Aspire.csproj",
+ "src\\BuiltInTools\\Watch\\Microsoft.DotNet.HotReload.Watch.csproj",
"src\\BuiltInTools\\dotnet-watch\\dotnet-watch.csproj",
"test\\Microsoft.AspNetCore.Watch.BrowserRefresh.Tests\\Microsoft.AspNetCore.Watch.BrowserRefresh.Tests.csproj",
"test\\Microsoft.DotNet.HotReload.Client.Tests\\Microsoft.DotNet.HotReload.Client.Tests.csproj",
@@ -27,6 +29,9 @@
"test\\Microsoft.NET.TestFramework\\Microsoft.NET.TestFramework.csproj",
"test\\Microsoft.WebTools.AspireService.Tests\\Microsoft.WebTools.AspireService.Tests.csproj",
"test\\dotnet-watch-test-browser\\dotnet-watch-test-browser.csproj",
+ "test\\Microsoft.DotNet.HotReload.Test.Utilities\\Microsoft.DotNet.HotReload.Test.Utilities.csproj",
+ "test\\Microsoft.DotNet.HotReload.Watch.Aspire.Tests\\Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj",
+ "test\\Microsoft.Extensions.DotNetDeltaApplier.Tests\\Microsoft.Extensions.DotNetDeltaApplier.Tests.csproj",
"test\\dotnet-watch.Tests\\dotnet-watch.Tests.csproj"
]
}
diff --git a/src/BuiltInTools/dotnet-watch/CommandLine/CommandLineOptions.cs b/src/BuiltInTools/dotnet-watch/CommandLine/CommandLineOptions.cs
index 0679d27d6897..ba8e3317c62b 100644
--- a/src/BuiltInTools/dotnet-watch/CommandLine/CommandLineOptions.cs
+++ b/src/BuiltInTools/dotnet-watch/CommandLine/CommandLineOptions.cs
@@ -378,22 +378,4 @@ public ProjectOptions GetProjectOptions(string projectPath, string workingDirect
BuildArguments = BuildArguments,
TargetFramework = TargetFramework,
};
-
- // Parses name=value pairs passed to --property. Skips invalid input.
- public static IEnumerable<(string key, string value)> ParseBuildProperties(IEnumerable arguments)
- => from argument in arguments
- let colon = argument.IndexOf(':')
- where colon >= 0 && argument[0..colon] is "--property" or "-property" or "/property" or "/p" or "-p" or "--p"
- let eq = argument.IndexOf('=', colon)
- where eq >= 0
- let name = argument[(colon + 1)..eq].Trim()
- let value = argument[(eq + 1)..]
- where name is not []
- select (name, value);
-
- ///
- /// Returns true if the command executes the code of the target project.
- ///
- public static bool IsCodeExecutionCommand(string commandName)
- => commandName is "run" or "test";
}
diff --git a/src/BuiltInTools/dotnet-watch/Program.cs b/src/BuiltInTools/dotnet-watch/Program.cs
index f67a360a3a32..f4e531d02414 100644
--- a/src/BuiltInTools/dotnet-watch/Program.cs
+++ b/src/BuiltInTools/dotnet-watch/Program.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.Loader;
@@ -40,7 +41,10 @@ public static async Task Main(string[] args)
// Register listeners that load Roslyn-related assemblies from the `Roslyn/bincore` directory.
RegisterAssemblyResolutionEvents(sdkRootDirectory);
- var environmentOptions = EnvironmentOptions.FromEnvironment();
+ var processPath = Environment.ProcessPath;
+ Debug.Assert(processPath != null);
+
+ var environmentOptions = EnvironmentOptions.FromEnvironment(processPath);
var program = TryCreate(
args,
@@ -67,7 +71,7 @@ public static async Task Main(string[] args)
private static Program? TryCreate(IReadOnlyList args, IConsole console, EnvironmentOptions environmentOptions, bool verbose, out int errorCode)
{
var parsingLoggerFactory = new LoggerFactory(new ConsoleReporter(console, verbose, quiet: false, environmentOptions.SuppressEmojis));
- var options = CommandLineOptions.Parse(args, parsingLoggerFactory.CreateLogger(LogComponentName), console.Out, out errorCode);
+ var options = CommandLineOptions.Parse(args, parsingLoggerFactory.CreateLogger(DotNetWatchContext.DefaultLogComponentName), console.Out, out errorCode);
if (options == null)
{
// an error reported or help printed:
@@ -82,7 +86,7 @@ public static async Task Main(string[] args)
// internal for testing
internal static Program? TryCreate(CommandLineOptions options, IConsole console, EnvironmentOptions environmentOptions, LoggerFactory loggerFactory, IProcessOutputReporter processOutputReporter, out int errorCode)
{
- var logger = loggerFactory.CreateLogger(LogComponentName);
+ var logger = loggerFactory.CreateLogger(DotNetWatchContext.DefaultLogComponentName);
var workingDirectory = environmentOptions.WorkingDirectory;
logger.LogDebug("Working directory: '{Directory}'", workingDirectory);
@@ -151,41 +155,21 @@ private static bool TryFindProject(string searchBase, CommandLineOptions options
// internal for testing
internal async Task RunAsync()
{
- var shutdownCancellationSourceDisposed = false;
- var shutdownCancellationSource = new CancellationTokenSource();
- var shutdownCancellationToken = shutdownCancellationSource.Token;
var isHotReloadEnabled = IsHotReloadEnabled();
var processRunner = new ProcessRunner(environmentOptions.GetProcessCleanupTimeout(isHotReloadEnabled));
- console.KeyPressed += key =>
- {
- if (!shutdownCancellationSourceDisposed && key.Modifiers.HasFlag(ConsoleModifiers.Control) && key.Key == ConsoleKey.C)
- {
- // if we already canceled, we force immediate shutdown:
- var forceShutdown = shutdownCancellationSource.IsCancellationRequested;
-
- if (!forceShutdown)
- {
- logger.Log(MessageDescriptor.ShutdownRequested);
- shutdownCancellationSource.Cancel();
- }
- else
- {
- Environment.Exit(0);
- }
- }
- };
+ using var shutdownHandler = new ShutdownHandler(console, logger);
try
{
- if (shutdownCancellationToken.IsCancellationRequested)
+ if (shutdownHandler.CancellationToken.IsCancellationRequested)
{
return 1;
}
if (options.List)
{
- return await ListFilesAsync(processRunner, shutdownCancellationToken);
+ return await ListFilesAsync(processRunner, shutdownHandler.CancellationToken);
}
if (environmentOptions.IsPollingEnabled)
@@ -198,16 +182,16 @@ internal async Task RunAsync()
if (isHotReloadEnabled)
{
var watcher = new HotReloadDotNetWatcher(context, console, runtimeProcessLauncherFactory: null);
- await watcher.WatchAsync(shutdownCancellationToken);
+ await watcher.WatchAsync(shutdownHandler.CancellationToken);
}
else
{
- await DotNetWatcher.WatchAsync(context, shutdownCancellationToken);
+ await DotNetWatcher.WatchAsync(context, shutdownHandler.CancellationToken);
}
return 0;
}
- catch (OperationCanceledException) when (shutdownCancellationToken.IsCancellationRequested)
+ catch (OperationCanceledException) when (shutdownHandler.CancellationToken.IsCancellationRequested)
{
// Ctrl+C forced an exit
return 0;
@@ -217,11 +201,6 @@ internal async Task RunAsync()
logger.LogError("An unexpected error occurred: {Exception}", e.ToString());
return 1;
}
- finally
- {
- shutdownCancellationSourceDisposed = true;
- shutdownCancellationSource.Dispose();
- }
}
// internal for testing
diff --git a/src/BuiltInTools/dotnet-watch/UI/IConsole.cs b/src/BuiltInTools/dotnet-watch/UI/IConsole.cs
deleted file mode 100644
index 0860a30eeae6..000000000000
--- a/src/BuiltInTools/dotnet-watch/UI/IConsole.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.DotNet.Watch
-{
- ///
- /// This API supports infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- ///
- internal interface IConsole
- {
- event Action KeyPressed;
- TextWriter Out { get; }
- TextWriter Error { get; }
- ConsoleColor ForegroundColor { get; set; }
- void ResetColor();
- void Clear();
- }
-}
diff --git a/src/BuiltInTools/dotnet-watch/Watch/BuildEvaluator.cs b/src/BuiltInTools/dotnet-watch/Watch/BuildEvaluator.cs
index ec3b10c8b235..756abbda6bc4 100644
--- a/src/BuiltInTools/dotnet-watch/Watch/BuildEvaluator.cs
+++ b/src/BuiltInTools/dotnet-watch/Watch/BuildEvaluator.cs
@@ -46,7 +46,7 @@ public IReadOnlyList GetProcessArguments(int iteration)
{
if (!_context.EnvironmentOptions.SuppressMSBuildIncrementalism &&
iteration > 0 &&
- CommandLineOptions.IsCodeExecutionCommand(_context.RootProjectOptions.Command))
+ _context.RootProjectOptions.IsCodeExecutionCommand)
{
if (RequiresRevaluation)
{
diff --git a/src/BuiltInTools/dotnet-watch/Watch/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Watch/MsBuildFileSetFactory.cs
index 50ce65d4e9a1..32f8f2a0d58d 100644
--- a/src/BuiltInTools/dotnet-watch/Watch/MsBuildFileSetFactory.cs
+++ b/src/BuiltInTools/dotnet-watch/Watch/MsBuildFileSetFactory.cs
@@ -31,7 +31,7 @@ internal class MSBuildFileSetFactory(
private ILogger Logger => buildReporter.Logger;
private readonly ProjectGraphFactory _buildGraphFactory = new(
- globalOptions: CommandLineOptions.ParseBuildProperties(buildArguments).ToImmutableDictionary(keySelector: arg => arg.key, elementSelector: arg => arg.value));
+ globalOptions: BuildUtilities.ParseBuildProperties(buildArguments).ToImmutableDictionary(keySelector: arg => arg.key, elementSelector: arg => arg.value));
internal sealed class EvaluationResult(IReadOnlyDictionary files, ProjectGraph? projectGraph)
{
diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj
index 9d089001e2b2..6ee14bf8ee71 100644
--- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj
+++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj
@@ -1,10 +1,4 @@
-
-
-
-
-
-
$(SdkTargetFramework)
exe
@@ -34,18 +28,9 @@
-
-
-
-
-
-
-
-
-
@@ -60,37 +45,11 @@
PreserveNewest
-
- all
- Content
- true
- false
- TargetFramework;TargetFrameworks
- hotreload\net6.0\Microsoft.AspNetCore.Watch.BrowserRefresh.dll
- PreserveNewest
-
-
-
- all
- Content
- true
- false
- TargetFramework=net10.0
- hotreload\net10.0\Microsoft.Extensions.DotNetDeltaApplier.dll
- PreserveNewest
-
-
-
- all
- Content
- true
- false
- TargetFramework=net6.0
- hotreload\net6.0\Microsoft.Extensions.DotNetDeltaApplier.dll
- PreserveNewest
-
+
+
+
diff --git a/src/Cli/dotnet/Commands/CliCommandStrings.resx b/src/Cli/dotnet/Commands/CliCommandStrings.resx
index 960ea3ad5fa5..4b06293d9ddf 100644
--- a/src/Cli/dotnet/Commands/CliCommandStrings.resx
+++ b/src/Cli/dotnet/Commands/CliCommandStrings.resx
@@ -1540,7 +1540,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Convert a file-based program to a project-based program.
- Specify the output directory ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
index b1c7f3235b60..e4f4f6a8d747 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
@@ -2411,8 +2411,8 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
- Specify the output directory ({0}):
- Zadejte výstupní adresář ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Zadejte výstupní adresář ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
index 26cb7237cd8d..c53b0075fd80 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
@@ -2411,8 +2411,8 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
- Specify the output directory ({0}):
- Ausgabeverzeichnis ({0}) angeben:
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Ausgabeverzeichnis ({0}) angeben:
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
index eb169c0e8420..298395039948 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
@@ -2411,8 +2411,8 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
- Specify the output directory ({0}):
- Especifique el directorio de salida ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Especifique el directorio de salida ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
index 518ecd69771a..7b2aca3bc1ab 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
@@ -2411,8 +2411,8 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
- Specify the output directory ({0}):
- Spécifiez le répertoire de sortie ({0}) :
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Spécifiez le répertoire de sortie ({0}) :
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
index bfbe556b59d9..427066e14edf 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
@@ -2411,8 +2411,8 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
- Specify the output directory ({0}):
- Specifica la directory di output ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Specifica la directory di output ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
index 1086bf080558..32a40ec7348d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
@@ -2412,8 +2412,8 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
- Specify the output directory ({0}):
- 出力ディレクトリ ({0}) を指定します:
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ 出力ディレクトリ ({0}) を指定します:
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
index c9fda7b39e5c..bf19954d912d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
@@ -2411,8 +2411,8 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
- Specify the output directory ({0}):
- 출력 디렉터리 지정({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ 출력 디렉터리 지정({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
index b4e9066cd21c..76797ea9da20 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
@@ -2411,8 +2411,8 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
- Specify the output directory ({0}):
- Określ katalog wyjściowy ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Określ katalog wyjściowy ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
index e33759f1e692..18df14f4c207 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
@@ -2411,8 +2411,8 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
- Specify the output directory ({0}):
- Especificar o diretório de saída ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Especificar o diretório de saída ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
index 2b49c411b98c..93049cfd82ef 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
@@ -2411,8 +2411,8 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
- Specify the output directory ({0}):
- Укажите выходной каталог ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Укажите выходной каталог ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
index a2d3a75bed06..08e93de1798a 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
@@ -2411,8 +2411,8 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
- Specify the output directory ({0}):
- Çıkış dizinini belirtin ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ Çıkış dizinini belirtin ({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
index 7db512aed403..31265e359e66 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
@@ -2411,8 +2411,8 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
- Specify the output directory ({0}):
- 指定输出目录({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ 指定输出目录({0}):
{0} is the default value
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
index 13ecb29241c2..a2f79756eb21 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
@@ -2411,8 +2411,8 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
- Specify the output directory ({0}):
- 指定輸出目錄 ({0}):
+ Specify the output directory (press Enter for default: '{0}', directory must not exist):
+ 指定輸出目錄 ({0}):
{0} is the default value
diff --git a/src/RazorSdk/Tool/GenerateCommand.cs b/src/RazorSdk/Tool/GenerateCommand.cs
index 635eefd6be75..33176da4869e 100644
--- a/src/RazorSdk/Tool/GenerateCommand.cs
+++ b/src/RazorSdk/Tool/GenerateCommand.cs
@@ -4,6 +4,7 @@
#nullable disable
using System.Diagnostics;
+using System.Threading;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.NET.Sdk.Razor.Tool.CommandLineUtils;
diff --git a/test/Common/Program.cs b/test/Common/Program.cs
index 66044b224b5e..f2100b6811cf 100644
--- a/test/Common/Program.cs
+++ b/test/Common/Program.cs
@@ -1,9 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.NET.TestFramework;
using Microsoft.NET.TestFramework.Commands;
+namespace Microsoft.NET.TestFramework;
+
#pragma warning disable SA1205 // Partial elements should declare access
partial class Program
#pragma warning restore SA1205 // Partial elements should declare access
diff --git a/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj b/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj
index b81c300e8c5c..19c3be5116f6 100644
--- a/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj
+++ b/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/test/dotnet-watch.Tests/TestUtilities/AssertEx.cs b/test/Microsoft.DotNet.HotReload.Test.Utilities/AssertEx.cs
similarity index 100%
rename from test/dotnet-watch.Tests/TestUtilities/AssertEx.cs
rename to test/Microsoft.DotNet.HotReload.Test.Utilities/AssertEx.cs
diff --git a/test/dotnet-watch.Tests/TestUtilities/AwaitableProcess.cs b/test/Microsoft.DotNet.HotReload.Test.Utilities/AwaitableProcess.cs
similarity index 91%
rename from test/dotnet-watch.Tests/TestUtilities/AwaitableProcess.cs
rename to test/Microsoft.DotNet.HotReload.Test.Utilities/AwaitableProcess.cs
index fe40300cf7e4..d15b7ba6284c 100644
--- a/test/dotnet-watch.Tests/TestUtilities/AwaitableProcess.cs
+++ b/test/Microsoft.DotNet.HotReload.Test.Utilities/AwaitableProcess.cs
@@ -8,7 +8,7 @@
namespace Microsoft.DotNet.Watch.UnitTests
{
- internal class AwaitableProcess(DotnetCommand spec, ITestOutputHelper logger) : IDisposable
+ internal class AwaitableProcess(ITestOutputHelper logger) : IDisposable
{
// cancel just before we hit timeout used on CI (XUnitWorkItemTimeout value in sdk\test\UnitTests.proj)
private static readonly TimeSpan s_timeout = Environment.GetEnvironmentVariable("HELIX_WORK_ITEM_TIMEOUT") is { } value
@@ -16,7 +16,6 @@ internal class AwaitableProcess(DotnetCommand spec, ITestOutputHelper logger) :
private readonly object _testOutputLock = new();
- private readonly DotnetCommand _spec = spec;
private readonly List _lines = [];
private readonly BufferBlock _source = new();
private Process _process;
@@ -26,14 +25,22 @@ internal class AwaitableProcess(DotnetCommand spec, ITestOutputHelper logger) :
public int Id => _process.Id;
public Process Process => _process;
- public void Start()
+ public void Start(ProcessStartInfo processStartInfo)
{
if (_process != null)
{
throw new InvalidOperationException("Already started");
}
- var processStartInfo = _spec.GetProcessStartInfo();
+ if (!processStartInfo.UseShellExecute && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ var flags = File.GetUnixFileMode(processStartInfo.FileName);
+ if (!flags.HasFlag(UnixFileMode.UserExecute))
+ {
+ File.SetUnixFileMode(processStartInfo.FileName, flags | UnixFileMode.UserExecute);
+ }
+ }
+
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
diff --git a/test/dotnet-watch.Tests/TestUtilities/DebugTestOutputLogger.cs b/test/Microsoft.DotNet.HotReload.Test.Utilities/DebugTestOutputLogger.cs
similarity index 100%
rename from test/dotnet-watch.Tests/TestUtilities/DebugTestOutputLogger.cs
rename to test/Microsoft.DotNet.HotReload.Test.Utilities/DebugTestOutputLogger.cs
diff --git a/test/Microsoft.DotNet.HotReload.Test.Utilities/Microsoft.DotNet.HotReload.Test.Utilities.csproj b/test/Microsoft.DotNet.HotReload.Test.Utilities/Microsoft.DotNet.HotReload.Test.Utilities.csproj
new file mode 100644
index 000000000000..c27c0c1d9a25
--- /dev/null
+++ b/test/Microsoft.DotNet.HotReload.Test.Utilities/Microsoft.DotNet.HotReload.Test.Utilities.csproj
@@ -0,0 +1,19 @@
+
+
+
+ $(SdkTargetFramework)
+ Library
+ Microsoft.DotNet.Watch.UnitTests
+ MicrosoftAspNetCore
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.DotNet.HotReload.Test.Utilities/Properties/AssemblyInfo.cs b/test/Microsoft.DotNet.HotReload.Test.Utilities/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000000..5737afe4811d
--- /dev/null
+++ b/test/Microsoft.DotNet.HotReload.Test.Utilities/Properties/AssemblyInfo.cs
@@ -0,0 +1,9 @@
+// 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.CompilerServices;
+
+[assembly: InternalsVisibleTo("dotnet-watch.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Client.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Watch.Aspire.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/test/Microsoft.DotNet.HotReload.Test.Utilities/TestAssetExtensions.cs b/test/Microsoft.DotNet.HotReload.Test.Utilities/TestAssetExtensions.cs
new file mode 100644
index 000000000000..bba89f12618b
--- /dev/null
+++ b/test/Microsoft.DotNet.HotReload.Test.Utilities/TestAssetExtensions.cs
@@ -0,0 +1,12 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.Watch.UnitTests;
+
+internal static class TestAssetExtensions
+{
+ public static string GetWatchTestOutputPath(this TestAsset asset)
+ => Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot
+ ? Path.Combine(ciOutputRoot, ".hotreload", asset.Name)
+ : asset.Path + ".hotreload";
+}
diff --git a/test/dotnet-watch.Tests/TestUtilities/TestLogger.cs b/test/Microsoft.DotNet.HotReload.Test.Utilities/TestLogger.cs
similarity index 92%
rename from test/dotnet-watch.Tests/TestUtilities/TestLogger.cs
rename to test/Microsoft.DotNet.HotReload.Test.Utilities/TestLogger.cs
index 5ae8e7dcd811..562d9e67bd0a 100644
--- a/test/dotnet-watch.Tests/TestUtilities/TestLogger.cs
+++ b/test/Microsoft.DotNet.HotReload.Test.Utilities/TestLogger.cs
@@ -11,7 +11,7 @@ internal class TestLogger(ITestOutputHelper? output = null) : ILogger
public readonly Lock Guard = new();
private readonly List _messages = [];
- public Func? IsEnabledImpl;
+ public Func IsEnabledImpl = _ => true;
public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
{
@@ -38,5 +38,5 @@ public ImmutableArray GetAndClearMessages()
where TState : notnull => throw new NotImplementedException();
public bool IsEnabled(LogLevel logLevel)
- => IsEnabledImpl?.Invoke(logLevel) ?? true;
+ => IsEnabledImpl(logLevel);
}
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/DotNetWatchLauncherTests.cs b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/DotNetWatchLauncherTests.cs
new file mode 100644
index 000000000000..26e009bb1bae
--- /dev/null
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/DotNetWatchLauncherTests.cs
@@ -0,0 +1,37 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+
+namespace Microsoft.DotNet.Watch.UnitTests;
+
+public class DotNetWatchLauncherTests(ITestOutputHelper logger)
+{
+ private TestAssetsManager TestAssets { get; } = new(logger);
+
+ [Fact]
+ public async Task AspireWatchLaunch()
+ {
+ var testAsset = TestAssets.CopyTestAsset("WatchAppWithProjectDeps")
+ .WithSource();
+
+ var path = Path.ChangeExtension(typeof(DotNetWatchLauncher).Assembly.Location, PathUtilities.ExecutableExtension).TrimEnd('.');
+ var sdkRootDirectory = TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest;
+ var projectDir = Path.Combine(testAsset.Path, "AppWithDeps");
+ var projectPath = Path.Combine(projectDir, "App.WithDeps.csproj");
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = path,
+ Arguments = $@"--sdk ""{sdkRootDirectory}"" --project ""{projectPath}"" --verbose",
+ UseShellExecute = false,
+ RedirectStandardInput = true,
+ WorkingDirectory = projectDir,
+ };
+
+ using var process = new AwaitableProcess(logger);
+ process.Start(startInfo);
+
+ await process.GetOutputLineAsync(success: line => line.Contains("dotnet watch ⌚ Waiting for changes"), failure: _ => false);
+ }
+}
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/DotNetWatchOptionsTests.cs b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/DotNetWatchOptionsTests.cs
new file mode 100644
index 000000000000..6f7d317fdc54
--- /dev/null
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/DotNetWatchOptionsTests.cs
@@ -0,0 +1,117 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.Watch.UnitTests;
+
+public class DotNetWatchOptionsTests
+{
+ [Fact]
+ public void TryParse_RequiredProjectOption()
+ {
+ // Project option is missing
+ var args = new[] { "--verbose", "a", "b" };
+ Assert.False(DotNetWatchOptions.TryParse(args, out var options));
+ Assert.Null(options);
+ }
+
+ [Fact]
+ public void TryParse_RequiredSdkOption()
+ {
+ // Project option is missing
+ var args = new[] { "--project", "proj", "a", "b" };
+ Assert.False(DotNetWatchOptions.TryParse(args, out var options));
+ Assert.Null(options);
+ }
+
+ [Fact]
+ public void TryParse_ProjectAndSdkPaths()
+ {
+ var args = new[] { "--sdk", "sdk", "--project", "myproject.csproj" };
+ Assert.True(DotNetWatchOptions.TryParse(args, out var options));
+ Assert.Equal("sdk", options.SdkDirectory);
+ Assert.Equal("myproject.csproj", options.ProjectPath);
+ Assert.Empty(options.ApplicationArguments);
+ }
+
+ [Fact]
+ public void TryParse_ApplicationArguments()
+ {
+ var args = new[] { "--sdk", "sdk", "--project", "proj", "--verbose", "a", "b" };
+ Assert.True(DotNetWatchOptions.TryParse(args, out var options));
+ AssertEx.SequenceEqual(["a", "b"], options.ApplicationArguments);
+ }
+
+ [Fact]
+ public void TryParse_VerboseOption()
+ {
+ // With verbose flag
+ var argsVerbose = new[] { "--sdk", "sdk", "--project", "proj", "--verbose" };
+ Assert.True(DotNetWatchOptions.TryParse(argsVerbose, out var optionsVerbose));
+ Assert.True(optionsVerbose.IsVerbose);
+
+ // Without verbose flag
+ var argsNotVerbose = new[] { "--sdk", "sdk", "--project", "proj" };
+ Assert.True(DotNetWatchOptions.TryParse(argsNotVerbose, out var optionsNotVerbose));
+ Assert.False(optionsNotVerbose.IsVerbose);
+ }
+
+ [Fact]
+ public void TryParse_QuietOption()
+ {
+ // With quiet flag
+ var argsQuiet = new[] { "--sdk", "sdk", "--project", "proj", "--quiet" };
+ Assert.True(DotNetWatchOptions.TryParse(argsQuiet, out var optionsQuiet));
+ Assert.True(optionsQuiet.IsQuiet);
+
+ // Without quiet flag
+ var argsNotQuiet = new[] { "--sdk", "sdk", "--project", "proj" };
+ Assert.True(DotNetWatchOptions.TryParse(argsNotQuiet, out var optionsNotQuiet));
+ Assert.False(optionsNotQuiet.IsQuiet);
+ }
+
+ [Fact]
+ public void TryParse_NoLaunchProfileOption()
+ {
+ // With no-launch-profile flag
+ var argsNoProfile = new[] { "--sdk", "sdk", "--project", "proj", "--no-launch-profile" };
+ Assert.True(DotNetWatchOptions.TryParse(argsNoProfile, out var optionsNoProfile));
+ Assert.True(optionsNoProfile.NoLaunchProfile);
+
+ // Without no-launch-profile flag
+ var argsWithProfile = new[] { "--sdk", "sdk", "--project", "proj" };
+ Assert.True(DotNetWatchOptions.TryParse(argsWithProfile, out var optionsWithProfile));
+ Assert.False(optionsWithProfile.NoLaunchProfile);
+ }
+
+ [Fact]
+ public void TryParse_ConflictingOptions()
+ {
+ // Cannot specify both --quiet and --verbose
+ var args = new[] { "--sdk", "sdk", "--project", "proj", "--quiet", "--verbose" };
+ Assert.False(DotNetWatchOptions.TryParse(args, out var options));
+ Assert.Null(options);
+ }
+
+ [Fact]
+ public void TryParse_MultipleOptionValues()
+ {
+ // Project option should only accept one value
+ var args = new[] { "--sdk", "sdk", "--project", "proj1", "proj2" };
+ Assert.True(DotNetWatchOptions.TryParse(args, out var options));
+ Assert.Equal("proj1", options.ProjectPath);
+ AssertEx.SequenceEqual(["proj2"], options.ApplicationArguments);
+ }
+
+ [Fact]
+ public void TryParse_AllOptionsSet()
+ {
+ var args = new[] { "--sdk", "sdk", "--project", "myapp.csproj", "--verbose", "--no-launch-profile", "arg1", "arg2", "arg3" };
+ Assert.True(DotNetWatchOptions.TryParse(args, out var options));
+
+ Assert.Equal("myapp.csproj", options.ProjectPath);
+ Assert.True(options.IsVerbose);
+ Assert.False(options.IsQuiet);
+ Assert.True(options.NoLaunchProfile);
+ AssertEx.SequenceEqual(["arg1", "arg2", "arg3"], options.ApplicationArguments);
+ }
+}
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj
new file mode 100644
index 000000000000..a2e1cf8bf60a
--- /dev/null
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+
+ $(SdkTargetFramework)
+ Exe
+ Microsoft.DotNet.Watch.Aspire.UnitTests
+ MicrosoftAspNetCore
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.Extensions.DotNetDeltaApplier.Tests/Microsoft.Extensions.DotNetDeltaApplier.Tests.csproj b/test/Microsoft.Extensions.DotNetDeltaApplier.Tests/Microsoft.Extensions.DotNetDeltaApplier.Tests.csproj
index 6ab22f97a92d..c86f821366d9 100644
--- a/test/Microsoft.Extensions.DotNetDeltaApplier.Tests/Microsoft.Extensions.DotNetDeltaApplier.Tests.csproj
+++ b/test/Microsoft.Extensions.DotNetDeltaApplier.Tests/Microsoft.Extensions.DotNetDeltaApplier.Tests.csproj
@@ -8,8 +8,8 @@
-
-
+
+
diff --git a/test/Microsoft.WebTools.AspireService.Tests/Microsoft.WebTools.AspireService.Tests.csproj b/test/Microsoft.WebTools.AspireService.Tests/Microsoft.WebTools.AspireService.Tests.csproj
index 914af7b1e68d..3effab61b6ce 100644
--- a/test/Microsoft.WebTools.AspireService.Tests/Microsoft.WebTools.AspireService.Tests.csproj
+++ b/test/Microsoft.WebTools.AspireService.Tests/Microsoft.WebTools.AspireService.Tests.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/test/TestAssets/TestProjects/ClassLibraryWithIsTestProjectAndOtherTestProjects/OtherTestProject/Program.cs b/test/TestAssets/TestProjects/ClassLibraryWithIsTestProjectAndOtherTestProjects/OtherTestProject/Program.cs
index 1b9b5e92af36..fc9f8d4bb07f 100644
--- a/test/TestAssets/TestProjects/ClassLibraryWithIsTestProjectAndOtherTestProjects/OtherTestProject/Program.cs
+++ b/test/TestAssets/TestProjects/ClassLibraryWithIsTestProjectAndOtherTestProjects/OtherTestProject/Program.cs
@@ -84,7 +84,9 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
{
Uid = "Test5",
DisplayName = "Test5",
+#pragma warning disable CS0618 // Type or member is obsolete
Properties = new PropertyBag(new CancelledTestNodeStateProperty(new Exception("this is a cancelled exception"), "not OK")),
+#pragma warning restore CS0618 // Type or member is obsolete
}));
await context.MessageBus.PublishAsync(this, new FileArtifact(new FileInfo("file.txt"), "file", "file description"));
diff --git a/test/TestAssets/TestProjects/HybridTestRunnerTestProjects/OtherTestProject/Program.cs b/test/TestAssets/TestProjects/HybridTestRunnerTestProjects/OtherTestProject/Program.cs
index 1b9b5e92af36..fc9f8d4bb07f 100644
--- a/test/TestAssets/TestProjects/HybridTestRunnerTestProjects/OtherTestProject/Program.cs
+++ b/test/TestAssets/TestProjects/HybridTestRunnerTestProjects/OtherTestProject/Program.cs
@@ -84,7 +84,9 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
{
Uid = "Test5",
DisplayName = "Test5",
+#pragma warning disable CS0618 // Type or member is obsolete
Properties = new PropertyBag(new CancelledTestNodeStateProperty(new Exception("this is a cancelled exception"), "not OK")),
+#pragma warning restore CS0618 // Type or member is obsolete
}));
await context.MessageBus.PublishAsync(this, new FileArtifact(new FileInfo("file.txt"), "file", "file description"));
diff --git a/test/TestAssets/TestProjects/TestProjectSolutionWithTestsAndArtifacts/TestProject/Program.cs b/test/TestAssets/TestProjects/TestProjectSolutionWithTestsAndArtifacts/TestProject/Program.cs
index 8191677e5472..9fc0d44ada52 100644
--- a/test/TestAssets/TestProjects/TestProjectSolutionWithTestsAndArtifacts/TestProject/Program.cs
+++ b/test/TestAssets/TestProjects/TestProjectSolutionWithTestsAndArtifacts/TestProject/Program.cs
@@ -81,7 +81,9 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
{
Uid = "Test5",
DisplayName = "Test5",
+#pragma warning disable CS0618 // Type or member is obsolete
Properties = new PropertyBag(new CancelledTestNodeStateProperty(new Exception("this is a cancelled exception"), "not OK")),
+#pragma warning restore CS0618 // Type or member is obsolete
}));
await context.MessageBus.PublishAsync(this, new FileArtifact(new FileInfo("file.txt"), "file", "file description"));
diff --git a/test/TestAssets/TestProjects/TestProjectWithMultipleTFMsSolution/TestProject/Program.cs b/test/TestAssets/TestProjects/TestProjectWithMultipleTFMsSolution/TestProject/Program.cs
index 99cfc02234a4..f8b19141f356 100644
--- a/test/TestAssets/TestProjects/TestProjectWithMultipleTFMsSolution/TestProject/Program.cs
+++ b/test/TestAssets/TestProjects/TestProjectWithMultipleTFMsSolution/TestProject/Program.cs
@@ -81,7 +81,9 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context)
{
Uid = "Test5",
DisplayName = "Test5",
+#pragma warning disable CS0618 // Type or member is obsolete
Properties = new PropertyBag(new CancelledTestNodeStateProperty(new Exception("this is a cancelled exception"), "")),
+#pragma warning restore CS0618 // Type or member is obsolete
}));
context.Complete();
diff --git a/test/dotnet-watch.Tests/Build/BuildUtilitiesTests.cs b/test/dotnet-watch.Tests/Build/BuildUtilitiesTests.cs
new file mode 100644
index 000000000000..03161ae09339
--- /dev/null
+++ b/test/dotnet-watch.Tests/Build/BuildUtilitiesTests.cs
@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.Watch.UnitTests.Build;
+
+public class BuildUtilitiesTests
+{
+ [Theory]
+ [InlineData("-p:P=V", "P", "V")]
+ [InlineData("-p:P==", "P", "=")]
+ [InlineData("-p:P=A=B", "P", "A=B")]
+ [InlineData("-p: P\t = V ", "P", " V ")]
+ [InlineData("-p:P=", "P", "")]
+ public void BuildProperties_Valid(string argValue, string name, string value)
+ {
+ var properties = BuildUtilities.ParseBuildProperties([argValue]);
+ AssertEx.SequenceEqual([(name, value)], properties);
+ }
+
+ [Theory]
+ [InlineData("P")]
+ [InlineData("=P3")]
+ [InlineData("=")]
+ [InlineData("==")]
+ public void BuildProperties_Invalid(string argValue)
+ {
+ var properties = BuildUtilities.ParseBuildProperties([argValue]);
+ AssertEx.SequenceEqual([], properties);
+ }
+}
diff --git a/test/dotnet-watch.Tests/CommandLine/CommandLineOptionsTests.cs b/test/dotnet-watch.Tests/CommandLine/CommandLineOptionsTests.cs
index d98140e48889..431736a83fe8 100644
--- a/test/dotnet-watch.Tests/CommandLine/CommandLineOptionsTests.cs
+++ b/test/dotnet-watch.Tests/CommandLine/CommandLineOptionsTests.cs
@@ -53,29 +53,6 @@ public void HelpArgs(string[] args)
Assert.Contains("Usage:", output.ToString());
}
- [Theory]
- [InlineData("-p:P=V", "P", "V")]
- [InlineData("-p:P==", "P", "=")]
- [InlineData("-p:P=A=B", "P", "A=B")]
- [InlineData("-p: P\t = V ", "P", " V ")]
- [InlineData("-p:P=", "P", "")]
- public void BuildProperties_Valid(string argValue, string name, string value)
- {
- var properties = CommandLineOptions.ParseBuildProperties([argValue]);
- AssertEx.SequenceEqual([(name, value)], properties);
- }
-
- [Theory]
- [InlineData("P")]
- [InlineData("=P3")]
- [InlineData("=")]
- [InlineData("==")]
- public void BuildProperties_Invalid(string argValue)
- {
- var properties = CommandLineOptions.ParseBuildProperties([argValue]);
- AssertEx.SequenceEqual([], properties);
- }
-
[Fact]
public void ImplicitCommand()
{
diff --git a/test/dotnet-watch.Tests/TestUtilities/TestOptions.cs b/test/dotnet-watch.Tests/TestUtilities/TestOptions.cs
index 8b7ca9e70add..fd846476e25b 100644
--- a/test/dotnet-watch.Tests/TestUtilities/TestOptions.cs
+++ b/test/dotnet-watch.Tests/TestUtilities/TestOptions.cs
@@ -15,7 +15,7 @@ public static int GetTestPort()
public static readonly ProjectOptions ProjectOptions = GetProjectOptions([]);
public static EnvironmentOptions GetEnvironmentOptions(string workingDirectory = "", string muxerPath = "", TestAsset? asset = null)
- => new(workingDirectory, muxerPath, TimeSpan.Zero, IsPollingEnabled: true, TestFlags: TestFlags.RunningAsTest, TestOutput: asset != null ? GetWatchTestOutputPath(asset) : "");
+ => new(workingDirectory, muxerPath, TimeSpan.Zero, IsPollingEnabled: true, TestFlags: TestFlags.RunningAsTest, TestOutput: asset != null ? asset.GetWatchTestOutputPath() : "");
public static CommandLineOptions GetCommandLineOptions(string[] args)
=> CommandLineOptions.Parse(args, NullLogger.Instance, TextWriter.Null, out _) ?? throw new InvalidOperationException();
@@ -25,9 +25,4 @@ public static ProjectOptions GetProjectOptions(string[]? args = null)
var options = GetCommandLineOptions(args ?? []);
return options.GetProjectOptions(options.ProjectPath ?? "test.csproj", workingDirectory: "");
}
-
- public static string GetWatchTestOutputPath(this TestAsset asset)
- => Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot
- ? Path.Combine(ciOutputRoot, ".hotreload", asset.Name)
- : asset.Path + ".hotreload";
}
diff --git a/test/dotnet-watch.Tests/TestUtilities/WatchableApp.cs b/test/dotnet-watch.Tests/TestUtilities/WatchableApp.cs
index 81bfd17aae20..fcdaad958607 100644
--- a/test/dotnet-watch.Tests/TestUtilities/WatchableApp.cs
+++ b/test/dotnet-watch.Tests/TestUtilities/WatchableApp.cs
@@ -185,8 +185,9 @@ public void Start(TestAsset asset, IEnumerable arguments, string relativ
commandSpec.WithEnvironmentVariable(env.Key, env.Value);
}
- Process = new AwaitableProcess(commandSpec, Logger);
- Process.Start();
+ var processStartInfo = commandSpec.GetProcessStartInfo();
+ Process = new AwaitableProcess(Logger);
+ Process.Start(processStartInfo);
TestFlags = testFlags;
}
diff --git a/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj b/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
index 772d35b80517..9b1afe3702b4 100644
--- a/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
+++ b/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
@@ -17,11 +17,12 @@
+
-
+
@@ -31,8 +32,10 @@
<_FileItem Include="$(_Files)" />
-
+
+
+