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
15 changes: 15 additions & 0 deletions changelog.d/unreleased/2987.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
category: fixed
issues:
- 2987
affected:
- tests/CodeIndex.Tests/IndexCommandRunnerTests.cs
---

## English

- **Changed-between deletion purges stay covered (#2987)** — Added regression coverage that `cdidx index --changed-between` removes indexed rows for files deleted between refs, including changelog fragments whose paths begin with `+`.

## 日本語

- **changed-between の削除 purge を回帰テストで固定しました (#2987)** — `cdidx index --changed-between` が ref 間で削除されたファイルの indexed row を削除することを、`+` で始まる changelog fragment の path も含めて回帰テストで確認するようにしました。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3046.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3046
affected:
- src/CodeIndex/Cli/IndexCommandRunner.DryRun.cs
- tests/CodeIndex.Tests/IndexCommandRunnerTests.cs
---

## English

- **Dry-run changed-between now reports git range failures (#3046)** — `cdidx index --dry-run --changed-between` returns a usage error when git cannot resolve the requested refs, instead of silently reporting an empty candidate set.

## 日本語

- **dry-run の changed-between が git range 失敗を報告するようになりました (#3046)** — `cdidx index --dry-run --changed-between` は指定 ref を git が解決できない場合、空の candidate set を黙って返すのではなく usage error を返すようになりました。
12 changes: 11 additions & 1 deletion src/CodeIndex/Cli/IndexCommandRunner.DryRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,17 @@ private static bool TryResolveDryRunCandidates(
exitCode = WriteDryRunInterrupted(options, jsonOptions);
return false;
}
catch { /* ignore git errors in dry-run */ }
catch (Exception ex)
{
exitCode = WriteCommandError(
options.Json,
jsonOptions,
$"failed to resolve changed files between git refs: {ex.Message}",
CommandExitCodes.UsageError,
"Check the refs and rerun `cdidx index <projectPath> --changed-between <old-ref> <new-ref>`.",
CommandErrorCodes.UsageError);
return false;
}
}

if (relevantIgnoreFileChanged || ContainsIgnoreFilePath(changedFiles))
Expand Down
4 changes: 2 additions & 2 deletions tests/CodeIndex.Tests/CodeIndexExceptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ public void OpenSqliteConnectionWithRetry_CancelDuringRetrySleep_ThrowsOperation

stopwatch.Stop();
Assert.Equal(cts.Token, ex.CancellationToken);
Assert.Equal(1, attempts);
Assert.InRange(attempts, 1, 2);
Assert.True(stopwatch.Elapsed < TimeSpan.FromSeconds(1), $"Cancellation took {stopwatch.Elapsed}.");
}

Expand All @@ -255,7 +255,7 @@ public void RegisterConnectionFunctionsWithRetry_CancelDuringRetrySleep_ThrowsOp

stopwatch.Stop();
Assert.Equal(cts.Token, ex.CancellationToken);
Assert.Equal(1, attempts);
Assert.InRange(attempts, 1, 2);
Assert.True(stopwatch.Elapsed < TimeSpan.FromSeconds(1), $"Cancellation took {stopwatch.Elapsed}.");
}

Expand Down
82 changes: 82 additions & 0 deletions tests/CodeIndex.Tests/IndexCommandRunnerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6232,6 +6232,64 @@ public void Run_UpdateMode_WithChangedBetween_UpdatesNewPathAndRemovesRenamedOld
}
}

[Fact]
public void Run_UpdateMode_WithChangedBetween_RemovesDeletedPath_2987()
{
var projectRoot = CreateTempProject();
try
{
RunGit(projectRoot, "init");
var changelogDir = Path.Combine(projectRoot, "changelog.d", "unreleased");
Directory.CreateDirectory(changelogDir);
var deletedPath = Path.Combine(changelogDir, "+trimmed-release-json.fixed.md");

File.WriteAllText(
deletedPath,
"""
---
category: fixed
---

## English

- Placeholder.

## 日本語

- プレースホルダー。
""");
RunGit(projectRoot, "add", ".");
RunGit(projectRoot, "commit", "-m", "initial");
RunGit(projectRoot, "branch", "before-delete");

var initialExitCode = IndexCommandRunner.Run([projectRoot, "--json"], _jsonOptions);
Assert.Equal(CommandExitCodes.Success, initialExitCode);

File.Delete(deletedPath);
RunGit(projectRoot, "add", "-A");
RunGit(projectRoot, "commit", "-m", "delete fragment");
RunGit(projectRoot, "branch", "after-delete");

var (exitCode, json) = RunAndCaptureJson([projectRoot, "--changed-between", "before-delete", "after-delete", "--json"]);

Assert.Equal(CommandExitCodes.Success, exitCode);
Assert.Equal("success", json.GetProperty("status").GetString());
Assert.Equal(0, json.GetProperty("summary").GetProperty("updated").GetInt32());
Assert.Equal(1, json.GetProperty("summary").GetProperty("removed").GetInt32());

var indexedPaths = ReadIndexedPaths(Path.Combine(projectRoot, ".cdidx", "codeindex.db"));
Assert.DoesNotContain("changelog.d/unreleased/+trimmed-release-json.fixed.md", indexedPaths);

var (statusExitCode, statusJson) = RunStatusAndCaptureJson(["--db", Path.Combine(projectRoot, ".cdidx", "codeindex.db"), "--check", "--json"]);
Assert.Equal(CommandExitCodes.Success, statusExitCode);
Assert.True(statusJson.GetProperty("workspace_check").GetProperty("matches_workspace").GetBoolean());
}
finally
{
DeleteDirectory(projectRoot);
}
}

[Fact]
public void Run_UpdateMode_WithChangedBetween_FallsBackToFullScanWhenIgnoreFilesChange()
{
Expand Down Expand Up @@ -6309,6 +6367,30 @@ public void Run_DryRun_WithChangedBetweenMissingRef_ReturnsUsageError()
}
}

[Fact]
public void Run_DryRun_WithChangedBetweenInvalidRef_ReturnsUsageError_3046()
{
var projectRoot = CreateTempProject();
try
{
RunGit(projectRoot, "init");
File.WriteAllText(Path.Combine(projectRoot, "app.cs"), "public class App { }\n");
RunGit(projectRoot, "add", ".");
RunGit(projectRoot, "commit", "-m", "initial");

var (exitCode, json) = RunAndCaptureJson([projectRoot, "--changed-between", "HEAD", "missing-ref", "--dry-run", "--json"]);

Assert.Equal(CommandExitCodes.UsageError, exitCode);
Assert.Equal("error", json.GetProperty("status").GetString());
Assert.Contains("failed to resolve changed files between git refs", json.GetProperty("message").GetString());
Assert.Contains("cdidx index <projectPath> --changed-between <old-ref> <new-ref>", json.GetProperty("hint").GetString());
}
finally
{
DeleteDirectory(projectRoot);
}
}

[Fact]
public void Run_UpdateMode_WithFiles_RemovesIndexedScriptThatLosesShebang()
{
Expand Down
Loading