Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3631.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3631
affected:
- tools/CodeIndex.PackageNormalize/PackageNormalizeCli.cs
- tests/CodeIndex.Tests/ReleaseWorkflowTests.cs
---

## English

- **Package normalize dry-run tests no longer capture unrelated stderr (#3631)** — release workflow tests now invoke the package normalizer with dedicated output writers so MCP telemetry from other test activity cannot make dry-run stderr assertions flaky.

## 日本語

- **Package normalize の dry-run テストが無関係な stderr を捕捉しないようになりました (#3631)** — release workflow テストは package normalizer を専用の出力 writer で実行するため、他のテスト活動からの MCP telemetry が dry-run の stderr アサーションを不安定にしなくなりました。
22 changes: 13 additions & 9 deletions tests/CodeIndex.Tests/ReleaseWorkflowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,7 @@ public void PackageNormalizeCli_DryRunDoesNotRewritePackage()
CreateMinimalNuGetPackage(packagePath, "random.psmdcp");
var beforeHash = Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(packagePath)));

var (exitCode, stdout, stderr) = ConsoleCapture.Capture(() =>
PackageNormalizeCli.Run(["--dry-run", "--summary", packagePath]));
var (exitCode, stdout, stderr) = RunPackageNormalizeCli(["--dry-run", "--summary", packagePath]);

var afterHash = Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(packagePath)));
Assert.Equal(0, exitCode);
Expand Down Expand Up @@ -268,8 +267,7 @@ public void PackageNormalizeCli_JsonContinueOnErrorReportsAggregateSummary()
var missingPackagePath = Path.Combine(projectRoot, "missing.nupkg");
CreateMinimalNuGetPackage(packagePath, "random.psmdcp");

var (exitCode, stdout, stderr) = ConsoleCapture.Capture(() =>
PackageNormalizeCli.Run(["--dry-run", "--json", "--continue-on-error", missingPackagePath, packagePath]));
var (exitCode, stdout, stderr) = RunPackageNormalizeCli(["--dry-run", "--json", "--continue-on-error", missingPackagePath, packagePath]);

Assert.Equal(1, exitCode);
Assert.Empty(stderr);
Expand Down Expand Up @@ -303,7 +301,7 @@ public void PackageNormalizeCli_RejectsTooManyPackageArguments()
.Select(index => $"package-{index}.nupkg")
.ToArray();

var (exitCode, stdout, stderr) = ConsoleCapture.Capture(() => PackageNormalizeCli.Run(args));
var (exitCode, stdout, stderr) = RunPackageNormalizeCli(args);

Assert.Equal(1, exitCode);
Assert.Empty(stdout);
Expand All @@ -318,8 +316,7 @@ public void PackageNormalizeCli_JsonReportsBoundedFriendlyFailure()
{
var missingPackagePath = Path.Combine(projectRoot, "missing.nupkg");

var (exitCode, stdout, stderr) = ConsoleCapture.Capture(() =>
PackageNormalizeCli.Run(["--json", missingPackagePath]));
var (exitCode, stdout, stderr) = RunPackageNormalizeCli(["--json", missingPackagePath]);

Assert.Equal(1, exitCode);
Assert.Empty(stderr);
Expand Down Expand Up @@ -350,8 +347,7 @@ public void PackageNormalizeCli_JsonBoundsZipEntryDiagnostics()
("package/services/metadata/core-properties/random.psmdcp", ""),
(longEntryName, "payload"));

var (exitCode, stdout, stderr) = ConsoleCapture.Capture(() =>
PackageNormalizeCli.Run(["--json", packagePath]));
var (exitCode, stdout, stderr) = RunPackageNormalizeCli(["--json", packagePath]);

Assert.Equal(1, exitCode);
Assert.Empty(stderr);
Expand Down Expand Up @@ -738,6 +734,14 @@ private static string GetRepositoryRoot()
throw new InvalidOperationException("Could not locate repository root / リポジトリルートを特定できませんでした");
}

private static (int ExitCode, string Stdout, string Stderr) RunPackageNormalizeCli(string[] args)
{
using var stdout = new StringWriter();
using var stderr = new StringWriter();
var exitCode = PackageNormalizeCli.Run(args, stdout, stderr);
return (exitCode, stdout.ToString(), stderr.ToString());
}

private static void CreateMinimalNuGetPackage(string packagePath, string corePropertiesFileName)
{
var corePropertiesPath = $"package/services/metadata/core-properties/{corePropertiesFileName}";
Expand Down
34 changes: 18 additions & 16 deletions tools/CodeIndex.PackageNormalize/PackageNormalizeCli.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ namespace CodeIndex.PackageNormalize;

public static class PackageNormalizeCli
{
public static int Run(string[] args)
public static int Run(string[] args) => Run(args, Console.Out, Console.Error);

internal static int Run(string[] args, TextWriter stdout, TextWriter stderr)
{
if (args.Any(arg => arg is "-h" or "--help"))
{
WriteUsage();
WriteUsage(stderr);
return 0;
}

if (!PackageNormalizeOptions.TryParse(args, out var options, out var parseError))
{
Console.Error.WriteLine($"Error: {parseError}");
WriteUsage();
stderr.WriteLine($"Error: {parseError}");
WriteUsage(stderr);
return 1;
}

Expand All @@ -38,14 +40,14 @@ public static int Run(string[] args)
summary.Skipped++;
results.Add(new PackageNormalizePackageResult(packagePath, "would_normalize", null, warnings));
if (!options.Json)
Console.WriteLine($"Would normalize {packagePath}");
stdout.WriteLine($"Would normalize {packagePath}");
}
else
{
summary.Unchanged++;
results.Add(new PackageNormalizePackageResult(packagePath, "unchanged", null, warnings));
if (!options.Json)
Console.WriteLine($"Unchanged {packagePath}");
stdout.WriteLine($"Unchanged {packagePath}");
}
}
else
Expand All @@ -55,8 +57,8 @@ public static int Run(string[] args)
results.Add(new PackageNormalizePackageResult(packagePath, "normalized", null, warnings));
if (!options.Json)
{
Console.WriteLine($"Normalized {packagePath}");
WriteWarnings(warnings);
stdout.WriteLine($"Normalized {packagePath}");
WriteWarnings(stderr, warnings);
}
}
}
Expand All @@ -67,8 +69,8 @@ public static int Run(string[] args)
results.Add(new PackageNormalizePackageResult(packagePath, "failed", error, warnings));
if (!options.Json)
{
Console.Error.WriteLine($"Failed {PackageNormalizeDiagnostics.FormatPath(packagePath)}: {error}");
WriteWarnings(warnings);
stderr.WriteLine($"Failed {PackageNormalizeDiagnostics.FormatPath(packagePath)}: {error}");
WriteWarnings(stderr, warnings);
}

if (!options.ContinueOnError)
Expand All @@ -78,7 +80,7 @@ public static int Run(string[] args)

if (options.Json)
{
Console.WriteLine(JsonSerializer.Serialize(
stdout.WriteLine(JsonSerializer.Serialize(
new PackageNormalizeJsonResult(
options.DryRun,
options.ContinueOnError,
Expand All @@ -92,22 +94,22 @@ public static int Run(string[] args)
}
else if (options.Summary)
{
Console.WriteLine(
stdout.WriteLine(
$"Summary: inspected={summary.Inspected} normalized={summary.Normalized} unchanged={summary.Unchanged} failed={summary.Failed} skipped={summary.Skipped}");
}

return summary.Failed == 0 ? 0 : 1;
}

private static void WriteUsage()
private static void WriteUsage(TextWriter error)
{
Console.Error.WriteLine("Usage: dotnet run --project tools/CodeIndex.PackageNormalize -- [--dry-run|--check] [--summary] [--json] [--continue-on-error] <package.nupkg|package.snupkg> [...]");
error.WriteLine("Usage: dotnet run --project tools/CodeIndex.PackageNormalize -- [--dry-run|--check] [--summary] [--json] [--continue-on-error] <package.nupkg|package.snupkg> [...]");
}

private static void WriteWarnings(IReadOnlyList<string> warnings)
private static void WriteWarnings(TextWriter error, IReadOnlyList<string> warnings)
{
foreach (var warning in warnings)
Console.Error.WriteLine($"Warning: {warning}");
error.WriteLine($"Warning: {warning}");
}
}

Expand Down
Loading