Skip to content

Commit e5281cf

Browse files
committed
Address adversarial review findings (#5100)
1 parent 95d0f72 commit e5281cf

9 files changed

Lines changed: 58 additions & 9 deletions

changelog.d/unreleased/5100.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ issues:
55
affected:
66
- src/CodeIndex/Cli/ConsoleUi.cs
77
- src/CodeIndex/Cli/IndexCommandRunner.FullScan.Output.cs
8+
- src/CodeIndex/Cli/IndexCommandRunner.FullScan.SnapshotFailure.cs
89
- src/CodeIndex/Cli/IndexCommandRunner.DryRun.cs
910
- src/CodeIndex/Database/UnknownExtensionClassifier.cs
1011
- src/CodeIndex/Models/QueryResults.cs

src/CodeIndex/Cli/ExportImportCommandRunner.ArchiveScope.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,11 @@ OR key IN (
329329
'unknown_extension_file_path_limit',
330330
'unknown_extension_extension_counts_json',
331331
'unknown_extension_category_counts_json',
332-
'unknown_extension_groups_json');
332+
'unknown_extension_groups_json',
333+
'unknown_extension_group_count',
334+
'unknown_extension_groups_truncated',
335+
'unknown_extension_group_limit',
336+
'unknown_extension_group_omitted_count');
333337
334338
INSERT INTO codeindex_meta(key, value)
335339
VALUES (@indexCompletenessKey, 'incomplete')

src/CodeIndex/Cli/IndexCommandRunner.DryRun.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ void RecordDryRunScanErrors(IEnumerable<FileIndexer.ScanError> scanErrors)
512512
var unknownExtensionGroupOmittedCount = Math.Max(
513513
0,
514514
unknownExtensionClassification.GroupCount - unknownExtensionGroups.Count);
515+
var unknownExtensionFileCountLowerBound = candidatePathsTruncated
516+
|| (authoritativeFullScan && dryScanMetadata.HadErrors);
515517
var unknownExtensionWarning = unknownExtensionClassification.ActionableFileCount > 0
516518
? $"{unknownExtensionClassification.ActionableFileCount} file(s) were excluded because no language mapping or extractor was available. {UnknownExtensionClassifier.Guidance}"
517519
: null;
@@ -553,7 +555,7 @@ void RecordDryRunScanErrors(IEnumerable<FileIndexer.ScanError> scanErrors)
553555
UnknownExtensionGroupLimit = UnknownExtensionClassifier.MaxCompletionGroups,
554556
UnknownExtensionGroupOmittedCount = unknownExtensionGroupOmittedCount,
555557
UnknownExtensionDiagnosticsScope = authoritativeFullScan ? "workspace" : "candidate_scope",
556-
UnknownExtensionFileCountLowerBound = candidatePathsTruncated,
558+
UnknownExtensionFileCountLowerBound = unknownExtensionFileCountLowerBound,
557559
UnknownExtensionGuidance = unknownExtensionTotal > 0
558560
? UnknownExtensionClassifier.Guidance
559561
: null,
@@ -593,7 +595,7 @@ void RecordDryRunScanErrors(IEnumerable<FileIndexer.ScanError> scanErrors)
593595
CommandOutputWriter.WriteLine($"Dry run: {dryFileCount} indexable files inspected{lowerBound}");
594596
if (unknownExtensionTotal > 0)
595597
{
596-
CommandOutputWriter.WriteLine($" unknown extensions {unknownExtensionTotal,6}{(candidatePathsTruncated ? " (lower bound)" : string.Empty)}");
598+
CommandOutputWriter.WriteLine($" unknown extensions {unknownExtensionTotal,6}{(unknownExtensionFileCountLowerBound ? " (lower bound)" : string.Empty)}");
597599
foreach (var group in unknownExtensionGroups)
598600
CommandOutputWriter.WriteLine($" {group.Extension}: {ConsoleUi.FormatNumber(group.Count)} ({group.RecommendedAction})");
599601
if (unknownExtensionGroupOmittedCount > 0)

src/CodeIndex/Cli/IndexCommandRunner.FullScan.Output.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ private static int WriteFullScanFinalOutput(FullScanFinalOutputContext output)
155155
UnknownExtensionGroupLimit = UnknownExtensionClassifier.MaxCompletionGroups,
156156
UnknownExtensionGroupOmittedCount = unknownExtensionGroupOmittedCount,
157157
UnknownExtensionDiagnosticsScope = "workspace",
158-
UnknownExtensionFileCountLowerBound = false,
158+
UnknownExtensionFileCountLowerBound = output.ScanHadErrors,
159159
UnknownExtensionGuidance = output.ScanResult.UnknownExtensionFiles.Count > 0
160160
? UnknownExtensionClassifier.Guidance
161161
: null,
@@ -242,7 +242,8 @@ private static int WriteFullScanFinalOutput(FullScanFinalOutputContext output)
242242
{
243243
CommandOutputWriter.WriteLine(ConsoleUi.FormatSummaryLine(
244244
"Unknown extensions",
245-
ConsoleUi.FormatNumber(output.ScanResult.UnknownExtensionFiles.Count),
245+
ConsoleUi.FormatNumber(output.ScanResult.UnknownExtensionFiles.Count)
246+
+ (output.ScanHadErrors ? " (lower bound)" : string.Empty),
246247
indent: " "));
247248
foreach (var group in unknownExtensionGroups)
248249
{

src/CodeIndex/Cli/IndexCommandRunner.FullScan.SnapshotFailure.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ private sealed class FullScanSnapshotFailureContext
2121
internal string? PriorFoldFingerprint { get; init; }
2222
internal required List<IndexMemorySampleJsonResult> MemorySamples { get; init; }
2323
internal required IReadOnlyDictionary<string, int> LanguageCounts { get; init; }
24+
internal required IReadOnlyList<string> UnknownExtensionFiles { get; init; }
2425
internal int FilesCount { get; init; }
2526
internal int Skipped { get; init; }
2627
internal int DanglingSymlinkCount { get; init; }
@@ -83,13 +84,39 @@ private static int WriteFullScanSnapshotFailure(
8384
|| (persistedCSharpFiles && failure.PriorMetadataTargetCsharpMatchesCurrent);
8485
var foldReady = (failure.PriorReadiness & DbContext.FoldReadyFlag) != 0;
8586
var memoryTimeline = BuildMemoryTimeline(failure.MemorySamples);
87+
var unknownExtensionClassification = UnknownExtensionClassifier.Classify(
88+
failure.UnknownExtensionFiles);
89+
var unknownExtensionGroups = unknownExtensionClassification.Groups
90+
.Take(UnknownExtensionClassifier.MaxCompletionGroups)
91+
.ToList();
92+
var unknownExtensionGroupOmittedCount = Math.Max(
93+
0,
94+
unknownExtensionClassification.GroupCount - unknownExtensionGroups.Count);
95+
var warningCount = failure.Warnings;
96+
if (unknownExtensionClassification.ActionableFileCount > 0)
97+
{
98+
var warning = $"{unknownExtensionClassification.ActionableFileCount} file(s) were excluded because no language mapping or extractor was available. {UnknownExtensionClassifier.Guidance}";
99+
failure.WarningList.Add(new CliJsonMessage("<unknown_extensions>", warning));
100+
warningCount++;
101+
}
86102

87103
if (failure.Options.Json)
88104
{
89105
CommandOutputWriter.WriteLine(JsonSerializer.Serialize(new IndexFullScanJsonResult
90106
{
91107
Status = "partial",
92108
Mode = failure.Options.Rebuild ? "rebuild" : "incremental",
109+
UnknownExtensionFileCount = failure.UnknownExtensionFiles.Count,
110+
UnknownExtensionGroups = unknownExtensionGroups.Count > 0 ? unknownExtensionGroups : null,
111+
UnknownExtensionGroupCount = unknownExtensionClassification.GroupCount,
112+
UnknownExtensionGroupsTruncated = unknownExtensionGroupOmittedCount > 0,
113+
UnknownExtensionGroupLimit = UnknownExtensionClassifier.MaxCompletionGroups,
114+
UnknownExtensionGroupOmittedCount = unknownExtensionGroupOmittedCount,
115+
UnknownExtensionDiagnosticsScope = "workspace",
116+
UnknownExtensionFileCountLowerBound = true,
117+
UnknownExtensionGuidance = failure.UnknownExtensionFiles.Count > 0
118+
? UnknownExtensionClassifier.Guidance
119+
: null,
93120
Summary = new IndexFullScanSummaryJsonResult
94121
{
95122
FilesTotal = totalFiles,
@@ -100,7 +127,7 @@ private static int WriteFullScanSnapshotFailure(
100127
FilesSkipped = failure.Skipped,
101128
FilesPurged = 0,
102129
DanglingSymlinksSkipped = failure.DanglingSymlinkCount,
103-
Warnings = failure.Warnings,
130+
Warnings = warningCount,
104131
Errors = failure.Errors,
105132
SymbolsDroppedByKindFilter = failure.SymbolsDroppedByKindFilter,
106133
},

src/CodeIndex/Cli/IndexCommandRunner.FullScan.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ bool FullScanJavaScriptTypeScriptConfigChanged()
456456
PriorFoldFingerprint = priorFoldFingerprint,
457457
MemorySamples = memorySamples,
458458
LanguageCounts = languageCounts,
459+
UnknownExtensionFiles = scanResult.UnknownExtensionFiles,
459460
FilesCount = files.Count,
460461
Skipped = preWriteSelection.Skipped,
461462
DanglingSymlinkCount = scanResult.DanglingSymlinks.Count,

tests/CodeIndex.Tests/ExportImportCommandRunnerTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,6 +2461,10 @@ private static void AssertPartialArchiveStatus(string dbPath)
24612461
!status.RootElement.TryGetProperty("head_freshness", out var headFreshness)
24622462
|| headFreshness.GetProperty("state").GetString() != "head_current");
24632463
Assert.False(status.RootElement.TryGetProperty("unknown_extension_file_count", out _));
2464+
Assert.False(status.RootElement.TryGetProperty("unknown_extension_group_count", out _));
2465+
Assert.False(status.RootElement.TryGetProperty("unknown_extension_groups_truncated", out _));
2466+
Assert.False(status.RootElement.TryGetProperty("unknown_extension_group_limit", out _));
2467+
Assert.False(status.RootElement.TryGetProperty("unknown_extension_group_omitted_count", out _));
24642468
Assert.True(
24652469
!status.RootElement.TryGetProperty("last_index_run", out var lastIndexRun)
24662470
|| lastIndexRun.ValueKind == JsonValueKind.Null);

tests/CodeIndex.Tests/IndexCommandRunnerDryRunTests.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,7 @@ public void Run_DryRun_FullScan_ReportsProjectedPurgesAndUnknownExtensionsWithou
14591459
}
14601460

14611461
[Fact]
1462-
public void Run_DryRun_FullScan_ReportsUnreadableDirectory()
1462+
public void Run_DryRun_FullScan_ReportsUnreadableDirectory_Issue5100()
14631463
{
14641464
if (OperatingSystem.IsWindows())
14651465
return;
@@ -1470,18 +1470,23 @@ public void Run_DryRun_FullScan_ReportsUnreadableDirectory()
14701470
{
14711471
Directory.CreateDirectory(secretDir);
14721472
File.WriteAllText(Path.Combine(secretDir, "a.cs"), "public class A { }\n");
1473+
File.WriteAllText(Path.Combine(projectRoot, "notes.unknownext"), "unknown language\n");
14731474
SetUnixPermissions(secretDir, UnixFileMode.None);
14741475

14751476
var (exitCode, json) = RunAndCaptureJson([projectRoot, "--dry-run", "--json"]);
14761477

14771478
Assert.Equal(CommandExitCodes.Success, exitCode);
14781479
Assert.Equal("dry_run", json.GetProperty("status").GetString());
14791480
Assert.Equal(0, json.GetProperty("files_total").GetInt32());
1481+
Assert.Equal(1, json.GetProperty("unknown_extension_file_count").GetInt32());
1482+
Assert.True(json.GetProperty("unknown_extension_file_count_lower_bound").GetBoolean());
14801483
Assert.Equal("secret", json.GetProperty("errors")[0].GetProperty("file").GetString());
14811484
Assert.Equal("Could not scan directory due to permissions.", json.GetProperty("errors")[0].GetProperty("message").GetString());
14821485

1483-
var (humanExitCode, _, stderr) = RunAndCaptureStreams([projectRoot, "--dry-run"]);
1486+
var (humanExitCode, stdout, stderr) = RunAndCaptureStreams([projectRoot, "--dry-run"]);
14841487
Assert.Equal(CommandExitCodes.Success, humanExitCode);
1488+
Assert.Contains("unknown extensions", stdout);
1489+
Assert.Contains("(lower bound)", stdout);
14851490
Assert.Contains("secret", stderr);
14861491
Assert.Contains("Could not scan directory due to permissions.", stderr);
14871492
}

tests/CodeIndex.Tests/IndexCommandRunnerFullScanTests.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3120,7 +3120,7 @@ public void Run_FullScan_RebuildFailureRetainsPersistedReadinessForReclassifiedL
31203120
}
31213121

31223122
[Fact]
3123-
public void Run_FullScan_PartialDiscoveryRetainsKnownLanguageReadinessFailures()
3123+
public void Run_FullScan_PartialDiscoveryRetainsKnownLanguageReadinessFailures_Issue5100()
31243124
{
31253125
if (OperatingSystem.IsWindows())
31263126
return;
@@ -3137,6 +3137,7 @@ public void Run_FullScan_PartialDiscoveryRetainsKnownLanguageReadinessFailures()
31373137
File.WriteAllText(
31383138
Path.Combine(projectRoot, "Contract.cs"),
31393139
"public interface IContract { }\n");
3140+
File.WriteAllText(Path.Combine(projectRoot, "notes.unknownext"), "unknown language\n");
31403141
Directory.CreateDirectory(unreadableDirectory);
31413142
File.WriteAllText(Path.Combine(unreadableDirectory, "blocked.py"), "print('blocked')\n");
31423143
originalMode = File.GetUnixFileMode(unreadableDirectory);
@@ -3152,6 +3153,9 @@ public void Run_FullScan_PartialDiscoveryRetainsKnownLanguageReadinessFailures()
31523153

31533154
Assert.Equal(CommandExitCodes.PartialResult, exitCode);
31543155
Assert.True(json.GetProperty("summary").GetProperty("errors").GetInt32() >= 2);
3156+
Assert.True(
3157+
json.GetProperty("unknown_extension_file_count_lower_bound").GetBoolean(),
3158+
json.GetRawText());
31553159
Assert.False(
31563160
json.GetProperty("sql_graph_contract_ready").GetBoolean(),
31573161
json.GetRawText());

0 commit comments

Comments
 (0)