apply include/exclude globs in search.replace (T-364)
computeReplacements accepted the query's glob filters and silently dropped them — replace could rewrite files the equivalent search would never have matched. The grep engine's glob helpers are now public and shared, so search and replace can't disagree on scope; both the preview and the apply path go through the filtered list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import 'dart:io';
|
||||
|
||||
import '../files/ignore.dart';
|
||||
import '../files/listing.dart';
|
||||
import 'grep_engine.dart' show acceptGlobs, globToRegExp;
|
||||
import 'match.dart';
|
||||
|
||||
/// One changed line within a file.
|
||||
@@ -133,9 +134,14 @@ Future<List<FileReplacement>> computeReplacements({
|
||||
|
||||
final walk = await walkFiles(root: root, ignore: ignore);
|
||||
final rootPath = root.absolute.path;
|
||||
// Same compiled glob filters as the grep engine — replace must never
|
||||
// touch a file the equivalent search wouldn't have matched (T-364).
|
||||
final includes = [for (final g in query.include) globToRegExp(g)];
|
||||
final excludes = [for (final g in query.exclude) globToRegExp(g)];
|
||||
final out = <FileReplacement>[];
|
||||
for (final entry in walk.files) {
|
||||
if (out.length >= maxFiles) break;
|
||||
if (!acceptGlobs(entry.path, includes, excludes)) continue;
|
||||
final fr = _replaceInFile(rootPath, entry.path, query, replacement);
|
||||
if (fr != null) out.add(fr);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user