From a6a831c26bfaeef384b49b7ddf1ec7f163b25993 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 00:23:55 +0000 Subject: [PATCH 1/8] Initial plan From 5d4b871e162d3bf071390fa5b82f3b0a4c780489 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 00:32:40 +0000 Subject: [PATCH 2/8] Update replace-text.cs to use System.CommandLine and .rsp file support - Added System.CommandLine package directive to replace-text.cs - Rewrote the script to use System.CommandLine's Option and RootCommand APIs - System.CommandLine automatically supports .rsp files via @ prefix - Updated Aspire.ProjectTemplates.csproj to generate .rsp file with arguments - Changed script invocation to pass .rsp file instead of command-line arguments - This prevents command line length issues when building templates on Windows Co-authored-by: DamianEdwards <249088+DamianEdwards@users.noreply.github.com> --- .../Aspire.ProjectTemplates.csproj | 30 +- tools/scripts/replace-text.cs | 290 ++++++++---------- 2 files changed, 143 insertions(+), 177 deletions(-) diff --git a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj index 8e8798f1f2f..02633e42d4d 100644 --- a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj +++ b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj @@ -82,6 +82,7 @@ $(_VersionBase.Split('.')[0]) $(_VersionBase.Split('.')[1]) $(VersionMajor).$(VersionMinor) + <_RspFilePath>$(IntermediateOutputPath)replace-text-args.rsp @@ -121,22 +122,25 @@ - - "@(SourceFiles, '" "')" - "@(Replacements, '" "')" - - + - - - - - - - + <_RspLines Include="--files" /> + <_RspLines Include="@(SourceFiles)" /> + <_RspLines Include="--replacements" /> + <_RspLines Include="@(Replacements)" /> - + + + + + diff --git a/tools/scripts/replace-text.cs b/tools/scripts/replace-text.cs index 205b5f36aec..b5f10fa625e 100644 --- a/tools/scripts/replace-text.cs +++ b/tools/scripts/replace-text.cs @@ -1,211 +1,173 @@ #:package Microsoft.Extensions.FileSystemGlobbing +#:package System.CommandLine using System.Collections.Concurrent; +using System.CommandLine; using Microsoft.Extensions.FileSystemGlobbing; using Microsoft.Extensions.FileSystemGlobbing.Abstractions; -if (args.Length == 0 || args.Contains("--help") || args.Contains("-h")) +var filesOption = new Option("--files") { - PrintUsage(); - return args.Length == 0 ? 1 : 0; -} + Description = "One or more file paths, directory paths, or glob patterns", + AllowMultipleArgumentsPerToken = true, + Required = true +}; -// Parse arguments -var paths = new List(); -var replacements = new List<(string Find, string Replace)>(); -var currentMode = (string?)null; -var replacementBuffer = new List(); +var replacementsOption = new Option("--replacements") +{ + Description = "Pairs of find/replace text values", + AllowMultipleArgumentsPerToken = true, + Required = true +}; + +var rootCommand = new RootCommand +{ + filesOption, + replacementsOption +}; -for (var i = 0; i < args.Length; i++) +rootCommand.SetAction(result => { - var arg = args[i]; + var paths = result.GetValue(filesOption) ?? Array.Empty(); + var replacementArgs = result.GetValue(replacementsOption) ?? Array.Empty(); - if (arg == "--files") + // Validate and parse replacements + if (replacementArgs.Length == 0) { - currentMode = "files"; - continue; + Console.Error.WriteLine("Error: No replacements provided. Use --replacements to specify find/replace pairs."); + Environment.Exit(1); } - else if (arg == "--replacements") + + if (replacementArgs.Length % 2 != 0) { - currentMode = "replacements"; - continue; + Console.Error.WriteLine($"Error: Replacement arguments must be provided in pairs (find, replace)."); + Console.Error.WriteLine($" Received {replacementArgs.Length} arguments after --replacements."); + Environment.Exit(1); } - if (currentMode == "files") + var replacements = new List<(string Find, string Replace)>(); + for (var i = 0; i < replacementArgs.Length; i += 2) { - paths.Add(arg); + var find = replacementArgs[i]; + var replace = replacementArgs[i + 1]; + + if (string.IsNullOrEmpty(find)) + { + Console.Error.WriteLine($"Error: Find text at position {i + 1} in --replacements cannot be empty."); + Environment.Exit(1); + } + + replacements.Add((find, replace)); } - else if (currentMode == "replacements") + + Console.WriteLine($"Paths: {paths.Length}"); + foreach (var path in paths) { - replacementBuffer.Add(arg); + Console.WriteLine($" '{path}'"); } - else + Console.WriteLine($"Replacements: {replacements.Count}"); + foreach (var (find, replace) in replacements) { - Console.Error.WriteLine($"Error: Unexpected argument '{arg}'. Use --files or --replacements to specify argument type."); - return 1; + Console.WriteLine($" '{find}' -> '{replace}'"); } -} - -// Validate paths -if (paths.Count == 0) -{ - Console.Error.WriteLine("Error: No file paths provided. Use --files to specify paths."); - PrintUsage(); - return 1; -} - -// Validate and parse replacements -if (replacementBuffer.Count == 0) -{ - Console.Error.WriteLine("Error: No replacements provided. Use --replacements to specify find/replace pairs."); - PrintUsage(); - return 1; -} + Console.WriteLine(); -if (replacementBuffer.Count % 2 != 0) -{ - Console.Error.WriteLine($"Error: Replacement arguments must be provided in pairs (find, replace)."); - Console.Error.WriteLine($" Received {replacementBuffer.Count} arguments after --replacements."); - return 1; -} + var filesToProcess = new HashSet(StringComparer.OrdinalIgnoreCase); -for (var i = 0; i < replacementBuffer.Count; i += 2) -{ - var find = replacementBuffer[i]; - var replace = replacementBuffer[i + 1]; + var matcher = new Matcher(); + var hasGlobPatterns = false; - if (string.IsNullOrEmpty(find)) + foreach (var pathValue in paths) { - Console.Error.WriteLine($"Error: Find text at position {i + 1} in --replacements cannot be empty."); - return 1; + if (File.Exists(pathValue)) + { + // If it's a direct file path add it as is + filesToProcess.Add(Path.GetFullPath(pathValue)); + } + else if (Directory.Exists(pathValue)) + { + // If it's a directory, include all files within it + matcher.AddInclude(Path.Combine(pathValue, "**/*")); + hasGlobPatterns = true; + } + else if (pathValue.Contains('*') || pathValue.Contains('?')) + { + matcher.AddInclude(pathValue); + hasGlobPatterns = true; + } } - replacements.Add((find, replace)); -} + var currentDirectory = Directory.GetCurrentDirectory(); -Console.WriteLine($"Paths: {paths.Count}"); -foreach (var path in paths) -{ - Console.WriteLine($" '{path}'"); -} -Console.WriteLine($"Replacements: {replacements.Count}"); -foreach (var (find, replace) in replacements) -{ - Console.WriteLine($" '{find}' -> '{replace}'"); -} -Console.WriteLine(); - -var filesToProcess = new HashSet(StringComparer.OrdinalIgnoreCase); - -var matcher = new Matcher(); -var hasGlobPatterns = false; - -foreach (var pathValue in paths) -{ - if (File.Exists(pathValue)) - { - // If it's a direct file path add it as is - filesToProcess.Add(Path.GetFullPath(pathValue)); - } - else if (Directory.Exists(pathValue)) + if (hasGlobPatterns) { - // If it's a directory, include all files within it - matcher.AddInclude(Path.Combine(pathValue, "**/*")); - hasGlobPatterns = true; - } - else if (pathValue.Contains('*') || pathValue.Contains('?')) - { - matcher.AddInclude(pathValue); - hasGlobPatterns = true; - } -} - -var currentDirectory = Directory.GetCurrentDirectory(); + // Collect files from glob matching + var directoryInfo = new DirectoryInfoWrapper(new DirectoryInfo(currentDirectory)); + var matchResult = matcher.Execute(directoryInfo); -if (hasGlobPatterns) -{ - // Collect files from glob matching - var directoryInfo = new DirectoryInfoWrapper(new DirectoryInfo(currentDirectory)); - var matchResult = matcher.Execute(directoryInfo); + foreach (var file in matchResult.Files) + { + filesToProcess.Add(Path.GetFullPath(Path.Combine(currentDirectory, file.Path))); + } + } - foreach (var file in matchResult.Files) + if (filesToProcess.Count == 0) { - filesToProcess.Add(Path.GetFullPath(Path.Combine(currentDirectory, file.Path))); + Console.WriteLine("No files matched the provided paths."); + Environment.Exit(0); } -} -if (filesToProcess.Count == 0) -{ - Console.WriteLine("No files matched the provided paths."); - return 0; -} - -Console.WriteLine($"Found {filesToProcess.Count} file(s) matching the provided paths."); -Console.WriteLine(); + Console.WriteLine($"Found {filesToProcess.Count} file(s) matching the provided paths."); + Console.WriteLine(); -var processedCount = 0; -var modifiedCount = 0; -var errorCount = 0; -var errors = new ConcurrentBag<(string File, string Error)>(); + var processedCount = 0; + var modifiedCount = 0; + var errorCount = 0; + var errors = new ConcurrentBag<(string File, string Error)>(); -Parallel.ForEach(filesToProcess, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, filePath => -{ - try + Parallel.ForEach(filesToProcess, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, filePath => { - var content = File.ReadAllText(filePath); - var originalContent = content; - - foreach (var (find, replace) in replacements) + try { - content = content.Replace(find, replace, StringComparison.Ordinal); + var content = File.ReadAllText(filePath); + var originalContent = content; + + foreach (var (find, replace) in replacements) + { + content = content.Replace(find, replace, StringComparison.Ordinal); + } + + if (!string.Equals(content, originalContent, StringComparison.Ordinal)) + { + File.WriteAllText(filePath, content); + Interlocked.Increment(ref modifiedCount); + Console.WriteLine($"Modified: {Path.GetRelativePath(currentDirectory, filePath)}"); + } + + Interlocked.Increment(ref processedCount); } - - if (!string.Equals(content, originalContent, StringComparison.Ordinal)) + catch (Exception ex) { - File.WriteAllText(filePath, content); - Interlocked.Increment(ref modifiedCount); - Console.WriteLine($"Modified: {Path.GetRelativePath(currentDirectory, filePath)}"); + Interlocked.Increment(ref errorCount); + errors.Add((filePath, ex.Message)); } + }); - Interlocked.Increment(ref processedCount); - } - catch (Exception ex) - { - Interlocked.Increment(ref errorCount); - errors.Add((filePath, ex.Message)); - } -}); - -Console.WriteLine(); -Console.WriteLine($"Processed: {processedCount} file(s)"); -Console.WriteLine($"Modified: {modifiedCount} file(s)"); - -if (errorCount > 0) -{ - Console.WriteLine($"Errors: {errorCount} file(s)"); Console.WriteLine(); - Console.Error.WriteLine("Errors encountered:"); - foreach (var (file, error) in errors) + Console.WriteLine($"Processed: {processedCount} file(s)"); + Console.WriteLine($"Modified: {modifiedCount} file(s)"); + + if (errorCount > 0) { - Console.Error.WriteLine($" {Path.GetRelativePath(currentDirectory, file)}: {error}"); + Console.WriteLine($"Errors: {errorCount} file(s)"); + Console.WriteLine(); + Console.Error.WriteLine("Errors encountered:"); + foreach (var (file, error) in errors) + { + Console.Error.WriteLine($" {Path.GetRelativePath(currentDirectory, file)}: {error}"); + } + Environment.Exit(1); } - return 1; -} - -return 0; - -static void PrintUsage() -{ - Console.Error.WriteLine(""" - Usage: dotnet replace-text.cs --files [path2] ... --replacements [ ...] - - Arguments: - --files One or more file paths, directory paths, or glob patterns - --replacements Pairs of find/replace text values - - Examples: - dotnet replace-text.cs --files "./src/**/*.cs" "./src/**/*.csproj" --replacements "!!VERSION!!" "7.0.5" "!!MAJOR_MINOR!!" "7.0" - dotnet replace-text.cs --files ./path/to/file.cs --replacements "oldText" "newText" - """); -} +}); +return rootCommand.Parse(args).Invoke(); From 3905e1ffca62f39be2d3cb02c209bae0a4e94ce0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 00:35:26 +0000 Subject: [PATCH 3/8] Improve error handling in replace-text.cs script - Replace Environment.Exit() calls with proper return statements - Add try-catch block around the entire action handler - Return exit codes from the action handler instead of calling Environment.Exit() - This allows proper cleanup and makes the script more testable Co-authored-by: DamianEdwards <249088+DamianEdwards@users.noreply.github.com> --- tools/scripts/replace-text.cs | 146 ++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 68 deletions(-) diff --git a/tools/scripts/replace-text.cs b/tools/scripts/replace-text.cs index b5f10fa625e..79d893e71cc 100644 --- a/tools/scripts/replace-text.cs +++ b/tools/scripts/replace-text.cs @@ -28,37 +28,39 @@ rootCommand.SetAction(result => { - var paths = result.GetValue(filesOption) ?? Array.Empty(); - var replacementArgs = result.GetValue(replacementsOption) ?? Array.Empty(); - - // Validate and parse replacements - if (replacementArgs.Length == 0) + try { - Console.Error.WriteLine("Error: No replacements provided. Use --replacements to specify find/replace pairs."); - Environment.Exit(1); - } - - if (replacementArgs.Length % 2 != 0) - { - Console.Error.WriteLine($"Error: Replacement arguments must be provided in pairs (find, replace)."); - Console.Error.WriteLine($" Received {replacementArgs.Length} arguments after --replacements."); - Environment.Exit(1); - } + var paths = result.GetValue(filesOption) ?? Array.Empty(); + var replacementArgs = result.GetValue(replacementsOption) ?? Array.Empty(); - var replacements = new List<(string Find, string Replace)>(); - for (var i = 0; i < replacementArgs.Length; i += 2) - { - var find = replacementArgs[i]; - var replace = replacementArgs[i + 1]; + // Validate and parse replacements + if (replacementArgs.Length == 0) + { + Console.Error.WriteLine("Error: No replacements provided. Use --replacements to specify find/replace pairs."); + return 1; + } - if (string.IsNullOrEmpty(find)) + if (replacementArgs.Length % 2 != 0) { - Console.Error.WriteLine($"Error: Find text at position {i + 1} in --replacements cannot be empty."); - Environment.Exit(1); + Console.Error.WriteLine($"Error: Replacement arguments must be provided in pairs (find, replace)."); + Console.Error.WriteLine($" Received {replacementArgs.Length} arguments after --replacements."); + return 1; } - replacements.Add((find, replace)); - } + var replacements = new List<(string Find, string Replace)>(); + for (var i = 0; i < replacementArgs.Length; i += 2) + { + var find = replacementArgs[i]; + var replace = replacementArgs[i + 1]; + + if (string.IsNullOrEmpty(find)) + { + Console.Error.WriteLine($"Error: Find text at position {i + 1} in --replacements cannot be empty."); + return 1; + } + + replacements.Add((find, replace)); + } Console.WriteLine($"Paths: {paths.Length}"); foreach (var path in paths) @@ -111,62 +113,70 @@ } } - if (filesToProcess.Count == 0) - { - Console.WriteLine("No files matched the provided paths."); - Environment.Exit(0); - } + if (filesToProcess.Count == 0) + { + Console.WriteLine("No files matched the provided paths."); + return 0; + } - Console.WriteLine($"Found {filesToProcess.Count} file(s) matching the provided paths."); - Console.WriteLine(); + Console.WriteLine($"Found {filesToProcess.Count} file(s) matching the provided paths."); + Console.WriteLine(); - var processedCount = 0; - var modifiedCount = 0; - var errorCount = 0; - var errors = new ConcurrentBag<(string File, string Error)>(); + var processedCount = 0; + var modifiedCount = 0; + var errorCount = 0; + var errors = new ConcurrentBag<(string File, string Error)>(); - Parallel.ForEach(filesToProcess, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, filePath => - { - try + Parallel.ForEach(filesToProcess, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, filePath => { - var content = File.ReadAllText(filePath); - var originalContent = content; - - foreach (var (find, replace) in replacements) + try { - content = content.Replace(find, replace, StringComparison.Ordinal); + var content = File.ReadAllText(filePath); + var originalContent = content; + + foreach (var (find, replace) in replacements) + { + content = content.Replace(find, replace, StringComparison.Ordinal); + } + + if (!string.Equals(content, originalContent, StringComparison.Ordinal)) + { + File.WriteAllText(filePath, content); + Interlocked.Increment(ref modifiedCount); + Console.WriteLine($"Modified: {Path.GetRelativePath(currentDirectory, filePath)}"); + } + + Interlocked.Increment(ref processedCount); } - - if (!string.Equals(content, originalContent, StringComparison.Ordinal)) + catch (Exception ex) { - File.WriteAllText(filePath, content); - Interlocked.Increment(ref modifiedCount); - Console.WriteLine($"Modified: {Path.GetRelativePath(currentDirectory, filePath)}"); + Interlocked.Increment(ref errorCount); + errors.Add((filePath, ex.Message)); } + }); - Interlocked.Increment(ref processedCount); - } - catch (Exception ex) + Console.WriteLine(); + Console.WriteLine($"Processed: {processedCount} file(s)"); + Console.WriteLine($"Modified: {modifiedCount} file(s)"); + + if (errorCount > 0) { - Interlocked.Increment(ref errorCount); - errors.Add((filePath, ex.Message)); + Console.WriteLine($"Errors: {errorCount} file(s)"); + Console.WriteLine(); + Console.Error.WriteLine("Errors encountered:"); + foreach (var (file, error) in errors) + { + Console.Error.WriteLine($" {Path.GetRelativePath(currentDirectory, file)}: {error}"); + } + return 1; } - }); - - Console.WriteLine(); - Console.WriteLine($"Processed: {processedCount} file(s)"); - Console.WriteLine($"Modified: {modifiedCount} file(s)"); - if (errorCount > 0) + return 0; + } + catch (Exception ex) { - Console.WriteLine($"Errors: {errorCount} file(s)"); - Console.WriteLine(); - Console.Error.WriteLine("Errors encountered:"); - foreach (var (file, error) in errors) - { - Console.Error.WriteLine($" {Path.GetRelativePath(currentDirectory, file)}: {error}"); - } - Environment.Exit(1); + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); + return 1; } }); From be3501bb81da2bb9945e9806bed63a9d967b0030 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 02:08:09 +0000 Subject: [PATCH 4/8] Build replace-text.cs to executable before running to avoid dotnet CLI expanding .rsp The dotnet CLI itself uses System.CommandLine and expands .rsp files before passing arguments, which means we still hit the command line limit when using 'dotnet script.cs'. Now the build process: 1. Builds the script to an executable using 'dotnet build' 2. Runs the compiled executable directly with '@response.rsp' 3. This avoids the dotnet CLI intermediary and prevents .rsp expansion The compiled executable is placed in artifacts/bin/replace-text/Debug/ Co-authored-by: DamianEdwards <249088+DamianEdwards@users.noreply.github.com> --- args.rsp | 6 ++++++ .../Aspire.ProjectTemplates.csproj | 13 +++++++++++-- test2.txt | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 args.rsp create mode 100644 test2.txt diff --git a/args.rsp b/args.rsp new file mode 100644 index 00000000000..e4834568ef2 --- /dev/null +++ b/args.rsp @@ -0,0 +1,6 @@ +--files +/tmp/test-replace/test1.txt +/tmp/test-replace/test2.txt +--replacements +!!VERSION!! +4.0.0 diff --git a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj index 02633e42d4d..4191e154a9d 100644 --- a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj +++ b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj @@ -83,6 +83,9 @@ $(_VersionBase.Split('.')[1]) $(VersionMajor).$(VersionMinor) <_RspFilePath>$(IntermediateOutputPath)replace-text-args.rsp + <_ReplaceTextScriptPath>$(RepoRoot)tools/scripts/replace-text.cs + <_ReplaceTextExePath>$(RepoRoot)artifacts/bin/replace-text/Debug/replace-text + <_ReplaceTextExePath Condition="'$(OS)' == 'Windows_NT'">$(_ReplaceTextExePath).exe @@ -136,8 +139,14 @@ Overwrite="true" WriteOnlyWhenDifferent="true" /> - - + + + + diff --git a/test2.txt b/test2.txt new file mode 100644 index 00000000000..d05f456af0e --- /dev/null +++ b/test2.txt @@ -0,0 +1 @@ +Version: !!VERSION!! From 3f57d1ab0799f426e3a3707c65d17be5377d201e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 02:08:51 +0000 Subject: [PATCH 5/8] Remove accidentally committed test files Co-authored-by: DamianEdwards <249088+DamianEdwards@users.noreply.github.com> --- args.rsp | 6 ------ test2.txt | 1 - 2 files changed, 7 deletions(-) delete mode 100644 args.rsp delete mode 100644 test2.txt diff --git a/args.rsp b/args.rsp deleted file mode 100644 index e4834568ef2..00000000000 --- a/args.rsp +++ /dev/null @@ -1,6 +0,0 @@ ---files -/tmp/test-replace/test1.txt -/tmp/test-replace/test2.txt ---replacements -!!VERSION!! -4.0.0 diff --git a/test2.txt b/test2.txt deleted file mode 100644 index d05f456af0e..00000000000 --- a/test2.txt +++ /dev/null @@ -1 +0,0 @@ -Version: !!VERSION!! From 1ea1e0aaf7ea504de14cad91d37b8570cc84c22d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 05:52:22 +0000 Subject: [PATCH 6/8] Use dotnet script.cs with -- to avoid CLI expanding .rsp file Per feedback, the simpler approach is to use 'dotnet script.cs -- @response.rsp' where the '--' tells dotnet CLI to pass arguments directly to the script without interpretation. This avoids the CLI expanding the .rsp file and hitting command line limits. The script still needs to be built once (dotnet does this automatically when running .cs files), so we keep the build step to ensure it's compiled before use. Co-authored-by: DamianEdwards <249088+DamianEdwards@users.noreply.github.com> --- .../Aspire.ProjectTemplates.csproj | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj index 4191e154a9d..b73f8e25fe4 100644 --- a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj +++ b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj @@ -84,8 +84,6 @@ $(VersionMajor).$(VersionMinor) <_RspFilePath>$(IntermediateOutputPath)replace-text-args.rsp <_ReplaceTextScriptPath>$(RepoRoot)tools/scripts/replace-text.cs - <_ReplaceTextExePath>$(RepoRoot)artifacts/bin/replace-text/Debug/replace-text - <_ReplaceTextExePath Condition="'$(OS)' == 'Windows_NT'">$(_ReplaceTextExePath).exe @@ -139,14 +137,14 @@ Overwrite="true" WriteOnlyWhenDifferent="true" /> - + - - + From 7d5a2e8f0e86262037d21a1f691a49399c7fa5e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 05:59:47 +0000 Subject: [PATCH 7/8] Remove explicit build step for replace-text script The build step is not needed. When using 'dotnet script.cs -- @response.rsp', dotnet automatically compiles and caches the script as needed. The explicit build step was redundant. Co-authored-by: DamianEdwards <249088+DamianEdwards@users.noreply.github.com> --- src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj index b73f8e25fe4..5428797b2cf 100644 --- a/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj +++ b/src/Aspire.ProjectTemplates/Aspire.ProjectTemplates.csproj @@ -137,12 +137,6 @@ Overwrite="true" WriteOnlyWhenDifferent="true" /> - - - Date: Tue, 16 Dec 2025 10:28:06 -0800 Subject: [PATCH 8/8] Fix formatting --- tools/scripts/replace-text.cs | 80 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/tools/scripts/replace-text.cs b/tools/scripts/replace-text.cs index 79d893e71cc..dcfc1222c13 100644 --- a/tools/scripts/replace-text.cs +++ b/tools/scripts/replace-text.cs @@ -62,56 +62,56 @@ replacements.Add((find, replace)); } - Console.WriteLine($"Paths: {paths.Length}"); - foreach (var path in paths) - { - Console.WriteLine($" '{path}'"); - } - Console.WriteLine($"Replacements: {replacements.Count}"); - foreach (var (find, replace) in replacements) - { - Console.WriteLine($" '{find}' -> '{replace}'"); - } - Console.WriteLine(); - - var filesToProcess = new HashSet(StringComparer.OrdinalIgnoreCase); - - var matcher = new Matcher(); - var hasGlobPatterns = false; - - foreach (var pathValue in paths) - { - if (File.Exists(pathValue)) + Console.WriteLine($"Paths: {paths.Length}"); + foreach (var path in paths) { - // If it's a direct file path add it as is - filesToProcess.Add(Path.GetFullPath(pathValue)); + Console.WriteLine($" '{path}'"); } - else if (Directory.Exists(pathValue)) + Console.WriteLine($"Replacements: {replacements.Count}"); + foreach (var (find, replace) in replacements) { - // If it's a directory, include all files within it - matcher.AddInclude(Path.Combine(pathValue, "**/*")); - hasGlobPatterns = true; + Console.WriteLine($" '{find}' -> '{replace}'"); } - else if (pathValue.Contains('*') || pathValue.Contains('?')) + Console.WriteLine(); + + var filesToProcess = new HashSet(StringComparer.OrdinalIgnoreCase); + + var matcher = new Matcher(); + var hasGlobPatterns = false; + + foreach (var pathValue in paths) { - matcher.AddInclude(pathValue); - hasGlobPatterns = true; + if (File.Exists(pathValue)) + { + // If it's a direct file path add it as is + filesToProcess.Add(Path.GetFullPath(pathValue)); + } + else if (Directory.Exists(pathValue)) + { + // If it's a directory, include all files within it + matcher.AddInclude(Path.Combine(pathValue, "**/*")); + hasGlobPatterns = true; + } + else if (pathValue.Contains('*') || pathValue.Contains('?')) + { + matcher.AddInclude(pathValue); + hasGlobPatterns = true; + } } - } - var currentDirectory = Directory.GetCurrentDirectory(); + var currentDirectory = Directory.GetCurrentDirectory(); - if (hasGlobPatterns) - { - // Collect files from glob matching - var directoryInfo = new DirectoryInfoWrapper(new DirectoryInfo(currentDirectory)); - var matchResult = matcher.Execute(directoryInfo); - - foreach (var file in matchResult.Files) + if (hasGlobPatterns) { - filesToProcess.Add(Path.GetFullPath(Path.Combine(currentDirectory, file.Path))); + // Collect files from glob matching + var directoryInfo = new DirectoryInfoWrapper(new DirectoryInfo(currentDirectory)); + var matchResult = matcher.Execute(directoryInfo); + + foreach (var file in matchResult.Files) + { + filesToProcess.Add(Path.GetFullPath(Path.Combine(currentDirectory, file.Path))); + } } - } if (filesToProcess.Count == 0) {