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)
{