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/3125.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3125
affected:
- src/CodeIndex/Cli/ExportImportCommandRunner.cs
- tests/CodeIndex.Tests/ExportImportCommandRunnerTests.cs
---

## English

- **`import` no longer reports failure after successful DB replacement solely because sidecar cleanup failed (#3125)** — destination WAL/SHM cleanup after the main database move is now best-effort.

## 日本語

- **DB 本体の置換成功後に sidecar cleanup だけで `import` が失敗扱いにならなくなりました (#3125)** — main database move 後の destination WAL/SHM cleanup は best-effort として扱われます。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3138.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3138
affected:
- src/CodeIndex/Cli/ExportImportCommandRunner.cs
- tests/CodeIndex.Tests/ExportImportCommandRunnerTests.cs
---

## English

- **`export` archive and ctags output now use the absolutized output path (#3138)** — export validation, directory creation, atomic writes, and final reporting now share the same resolved destination path.

## 日本語

- **`export` の archive / ctags 出力が absolute output path を使うようになりました (#3138)** — export の検証、ディレクトリ作成、atomic write、最終報告が同じ解決済み出力先を共有します。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3147.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3147
affected:
- src/CodeIndex/Cli/ReportCommandRunner.cs
- tests/CodeIndex.Tests/ReportCommandRunnerTests.cs
---

## English

- **`report` now writes bundles through the same absolutized output path it reports (#3147)** — relative report bundle paths are fixed before bundle writing so current-directory drift cannot split summary metadata from the actual write target.

## 日本語

- **`report` が表示する absolute output path と同じパスで bundle を書き込むようになりました (#3147)** — report bundle の相対パスは書き込み前に固定されるため、カレントディレクトリの変化で summary metadata と実際の書き込み先がずれなくなりました。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3148.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3148
affected:
- src/CodeIndex/Cli/ReportCommandRunner.cs
- tests/CodeIndex.Tests/ReportCommandRunnerTests.cs
---

## English

- **`report --db file:...` now reads existing SQLite file URI databases (#3148)** — report schema collection normalizes SQLite file URI inputs before filesystem checks and read-only SQLite opens.

## 日本語

- **`report --db file:...` が既存の SQLite file URI DB を読めるようになりました (#3148)** — report の schema 収集は filesystem check と read-only SQLite open の前に SQLite file URI 入力を正規化します。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3175.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3175
affected:
- src/CodeIndex/Cli/DbPathResolver.cs
- tests/CodeIndex.Tests/DbPathResolverTests.cs
---

## English

- **DB path metadata probes now stay best-effort on filesystem errors (#3175)** — resolver metadata reads now suppress expected filesystem and path exceptions in addition to SQLite exceptions.

## 日本語

- **DB path metadata probe が filesystem error でも best-effort のままになりました (#3175)** — resolver の metadata read は SQLite 例外に加えて、想定される filesystem / path 例外も握って上位の解決処理を落とさなくなりました。
19 changes: 19 additions & 0 deletions changelog.d/unreleased/3221.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
category: fixed
issues:
- 3221
affected:
- src/CodeIndex/Cli/DbCommandRunner.cs
- src/CodeIndex/Cli/DiffCommandRunner.cs
- src/CodeIndex/Cli/DbPathResolver.cs
- tests/CodeIndex.Tests/DbCommandRunnerTests.cs
- tests/CodeIndex.Tests/DiffCommandRunnerTests.cs
---

## English

- **DB and diff commands now preserve SQLite file URI display values (#3221)** — `cdidx db` and `cdidx diff` no longer pass `file:` URI inputs through filesystem path normalization when reporting human or JSON database paths.

## 日本語

- **DB / diff コマンドが SQLite file URI の表示値を保持するようになりました (#3221)** — `cdidx db` と `cdidx diff` は human / JSON の database path 表示時に `file:` URI 入力を filesystem path 正規化へ渡さなくなりました。
9 changes: 5 additions & 4 deletions src/CodeIndex/Cli/DbCommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,13 @@ private static int RunIntegrityCheck(DbCommandOptions options, JsonSerializerOpt
var issues = result.Rows;
var ok = issues.Count == 1 && string.Equals(issues[0], "ok", StringComparison.Ordinal);
var jsonContext = CliJsonSerializerContextFactory.Create(jsonOptions);
var displayDbPath = DbPathResolver.FormatDbPathForDisplay(dbPath);

if (options.Json)
{
Console.WriteLine(JsonSerializer.Serialize(
new DbIntegrityCheckJsonResult(
Path.GetFullPath(isUri ? dbPath : dbPath),
displayDbPath,
ok,
ok ? new List<string>() : issues,
result.Truncated,
Expand All @@ -137,7 +138,7 @@ private static int RunIntegrityCheck(DbCommandOptions options, JsonSerializerOpt
else
{
Console.WriteLine("Integrity check");
Console.WriteLine($" database: {Path.GetFullPath(isUri ? dbPath : dbPath)}");
Console.WriteLine($" database: {displayDbPath}");
Console.WriteLine($" result : {(ok ? "ok" : "corrupted")}");
if (!ok)
{
Expand Down Expand Up @@ -174,7 +175,7 @@ private static int RunSchema(DbCommandOptions options, JsonSerializerOptions jso
try
{
var schema = ReadSchema(dbPath);
var fullPath = Path.GetFullPath(isUri ? dbPath : dbPath);
var fullPath = DbPathResolver.FormatDbPathForDisplay(dbPath);
if (options.Json)
{
var jsonContext = CliJsonSerializerContextFactory.Create(jsonOptions);
Expand Down Expand Up @@ -255,7 +256,7 @@ private static int RunPrune(DbCommandOptions options, JsonSerializerOptions json
try
{
var result = PruneOrphans(dbPath, apply: options.PruneApply);
var fullPath = Path.GetFullPath(isUri ? dbPath : dbPath);
var fullPath = DbPathResolver.FormatDbPathForDisplay(dbPath);
if (options.Json)
{
var jsonContext = CliJsonSerializerContextFactory.Create(jsonOptions);
Expand Down
22 changes: 19 additions & 3 deletions src/CodeIndex/Cli/DbPathResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ public static bool TryHasIndexedHeadCommitBranchStamp(string dbPath)
var raw = cmd.ExecuteScalar();
return raw is string value && !string.IsNullOrWhiteSpace(value) ? value : null;
}
catch (SqliteException)
catch (Exception ex) when (IsMetadataProbeException(ex))
{
return null;
}
Expand All @@ -357,7 +357,7 @@ private static bool TryMetaKeyExists(string dbPath, string key)
cmd.Parameters.AddWithValue("@key", key);
return cmd.ExecuteScalar() != null;
}
catch (SqliteException)
catch (Exception ex) when (IsMetadataProbeException(ex))
{
return false;
}
Expand Down Expand Up @@ -425,12 +425,20 @@ private static bool SiblingRootMatchesIndexedContents(string dbPath, string full

private static SqliteConnection OpenMetadataConnection(string dbPath)
{
if (OpenMetadataConnectionForTesting != null)
return OpenMetadataConnectionForTesting(dbPath);

return new SqliteConnection(BuildSqliteConnectionString(dbPath, SqliteOpenMode.ReadOnly));
}

internal static Func<string, SqliteConnection>? OpenMetadataConnectionForTesting { get; set; }

public static bool UriRequestsReadOnly(string uriText)
=> SqliteFileUri.RequestsReadOnly(uriText);

internal static string FormatDbPathForDisplay(string dbPath)
=> SqliteFileUri.StartsWithFileScheme(dbPath) ? dbPath : Path.GetFullPath(dbPath);

private static bool PathsEqual(string left, string right)
=> PathCasing.PathsEqual(left, right);

Expand Down Expand Up @@ -492,13 +500,21 @@ LIMIT 5

return samples;
}
catch (SqliteException)
catch (Exception ex) when (IsMetadataProbeException(ex))
{
// Fall back to persisted metadata / 永続化 metadata 側へフォールバック
return [];
}
}

private static bool IsMetadataProbeException(Exception ex)
=> ex is SqliteException
or IOException
or UnauthorizedAccessException
or ArgumentException
or NotSupportedException
or PathTooLongException;

private static SampleMatchResult CountMatchingSamples(string candidateRoot, IReadOnlyList<IndexedFileSample> samples)
{
var checksumMatches = 0;
Expand Down
3 changes: 1 addition & 2 deletions src/CodeIndex/Cli/DiffCommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -667,11 +667,10 @@ private static long ExecuteLong(SqliteConnection connection, string sql)

private static DiffDbHeader ReadHeader(string dbPath)
{
var isUri = dbPath.StartsWith("file:", StringComparison.OrdinalIgnoreCase);
using var connection = OpenReadOnlyConnection(dbPath);

return new DiffDbHeader(
Path.GetFullPath(isUri ? dbPath : dbPath),
DbPathResolver.FormatDbPathForDisplay(dbPath),
ExecuteLong(connection, "PRAGMA user_version"),
ExecuteCountIfTableExists(connection, "files"),
ExecuteCountIfTableExists(connection, "symbols"),
Expand Down
37 changes: 26 additions & 11 deletions src/CodeIndex/Cli/ExportImportCommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private static int RunExportArchive(string[] args, JsonSerializerOptions jsonOpt
var snapshotPath = Path.Combine(Path.GetTempPath(), $"codeindex-export-{Guid.NewGuid():N}.db");
try
{
var outputDirectory = Path.GetDirectoryName(Path.GetFullPath(outputPath));
var outputDirectory = Path.GetDirectoryName(fullOutputPath);
if (!string.IsNullOrWhiteSpace(outputDirectory))
Directory.CreateDirectory(outputDirectory);

Expand All @@ -192,12 +192,12 @@ private static int RunExportArchive(string[] args, JsonSerializerOptions jsonOpt
}
SqliteConnection.ClearAllPools();
manifest = manifest with { DatabaseSha256 = ComputeSha256(snapshotPath) };
WriteExportArchiveFile(outputPath, snapshotPath, manifest, jsonOptions);
WriteExportArchiveFile(fullOutputPath, snapshotPath, manifest, jsonOptions);

if (wantsJson)
Console.WriteLine(JsonSerializer.Serialize(new ExportArchiveResult("1", Path.GetFullPath(outputPath), fullSourceDbPath), jsonOptions));
Console.WriteLine(JsonSerializer.Serialize(new ExportArchiveResult("1", fullOutputPath, fullSourceDbPath), jsonOptions));
else
Console.WriteLine($"Exported CodeIndex archive to {outputPath}");
Console.WriteLine($"Exported CodeIndex archive to {fullOutputPath}");
return CommandExitCodes.Success;
}
catch (Exception ex)
Expand Down Expand Up @@ -254,11 +254,11 @@ private static int RunExportCtags(string[] args)
{
using var db = new DbContext(normalizedDbPath);
db.TryMigrateForRead();
var outputDirectory = Path.GetDirectoryName(Path.GetFullPath(outputPath));
var outputDirectory = Path.GetDirectoryName(fullOutputPath);
if (!string.IsNullOrWhiteSpace(outputDirectory))
Directory.CreateDirectory(outputDirectory);

WriteCtagsFile(outputPath, writer =>
WriteCtagsFile(fullOutputPath, writer =>
{
writer.WriteLine("!_TAG_FILE_FORMAT\t2\t/extended format/");
writer.WriteLine("!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/");
Expand All @@ -281,7 +281,7 @@ FROM symbols s
}
});

Console.WriteLine($"Exported ctags to {outputPath}");
Console.WriteLine($"Exported ctags to {fullOutputPath}");
return CommandExitCodes.Success;
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or SqliteException)
Expand Down Expand Up @@ -312,8 +312,9 @@ private static void AddTextEntry(ZipArchive archive, string name, string content

internal static void WriteExportArchiveFile(string outputPath, string snapshotPath, ExportManifest manifest, JsonSerializerOptions jsonOptions)
{
var fullOutputPath = Path.GetFullPath(outputPath);
AtomicFileWriter.Write(
outputPath,
fullOutputPath,
stream =>
{
using var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true);
Expand All @@ -330,8 +331,9 @@ internal static void WriteCtagsFile(string outputPath, Action<TextWriter> writeC
{
ArgumentNullException.ThrowIfNull(writeContents);

var fullOutputPath = Path.GetFullPath(outputPath);
AtomicFileWriter.Write(
outputPath,
fullOutputPath,
stream =>
{
using var writer = new StreamWriter(
Expand Down Expand Up @@ -587,10 +589,23 @@ private static void DeleteSqliteSidecars(string dbPath)

private static void TryDeleteFile(string path)
{
if (File.Exists(path))
File.Delete(path);
try
{
if (!File.Exists(path))
return;

if (DeleteSqliteSidecarForTesting != null)
DeleteSqliteSidecarForTesting(path);
else
File.Delete(path);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or ArgumentException or NotSupportedException or PathTooLongException)
{
}
}

internal static Action<string>? DeleteSqliteSidecarForTesting { get; set; }

private static bool IsSamePath(string left, string right)
=> string.Equals(
Path.GetFullPath(left).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
Expand Down
19 changes: 11 additions & 8 deletions src/CodeIndex/Cli/ReportCommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ public static int Run(string[] cmdArgs, JsonSerializerOptions jsonOptions, strin

try
{
var fullOutputPath = Path.GetFullPath(options.OutputPath!);
var resolvedVersion = appVersion ?? ConsoleUi.LoadVersion();
var bundle = BuildBundle(options, resolvedVersion);
WriteBundle(options.OutputPath!, bundle);
WriteBundle(fullOutputPath, bundle);

var summary = new ReportBundleSummary(
Path.GetFullPath(options.OutputPath!),
fullOutputPath,
resolvedVersion,
bundle.Files.Count,
bundle.SchemaTables.Count,
Expand Down Expand Up @@ -194,16 +195,17 @@ internal static string BuildReadme(string version, bool includeLog, bool include

internal static (string Text, List<ReportSchemaTable> Tables, string? DbPath, bool DbIncluded) BuildSchemaSummary(string dbPath)
{
if (!File.Exists(LongPath.EnsureWindowsPrefix(dbPath)))
var normalizedDbPath = DbPathResolver.NormalizeDbPath(dbPath);
if (!File.Exists(LongPath.EnsureWindowsPrefix(normalizedDbPath)))
{
var missingText = $"no SQLite index found at: {RedactedPlaceholder}\nRun `cdidx index <projectPath>` first if you want schema details attached.\n";
return (missingText, new List<ReportSchemaTable>(), dbPath, false);
return (missingText, new List<ReportSchemaTable>(), normalizedDbPath, false);
}

var tables = new List<ReportSchemaTable>();
var connectionString = new SqliteConnectionStringBuilder
{
DataSource = dbPath,
DataSource = normalizedDbPath,
Mode = SqliteOpenMode.ReadOnly,
}.ConnectionString;

Expand Down Expand Up @@ -254,7 +256,7 @@ internal static (string Text, List<ReportSchemaTable> Tables, string? DbPath, bo
foreach (var t in tables)
sb.AppendLine($"{t.Name} | {FormatSchemaRowCount(t)}");

return (sb.ToString(), tables, dbPath, true);
return (sb.ToString(), tables, normalizedDbPath, true);
}

private static string FormatSchemaTableName(string name)
Expand Down Expand Up @@ -392,12 +394,13 @@ private static string RedactKeyValue(string line, string key)

internal static void WriteBundle(string outputPath, ReportBundle bundle, Action? beforeWriteEntries = null)
{
var dir = Path.GetDirectoryName(outputPath);
var fullOutputPath = Path.GetFullPath(outputPath);
var dir = Path.GetDirectoryName(fullOutputPath);
if (!string.IsNullOrEmpty(dir))
Directory.CreateDirectory(dir);

AtomicFileWriter.Write(
outputPath,
fullOutputPath,
stream =>
{
using var gz = new GZipStream(stream, CompressionLevel.Optimal, leaveOpen: true);
Expand Down
Loading
Loading