Skip to content

Commit 6345d18

Browse files
authored
Merge pull request #13 from bawahakim/feat-allow-excluded-files
feat: exclude files pattern
2 parents 838abd1 + 0ff9250 commit 6345d18

File tree

5 files changed

+67
-14
lines changed

5 files changed

+67
-14
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ Parentheses are reserved in case this package adds support for Bash extended
152152
globbing in the future. For the time being, using them will throw an error
153153
unless they're escaped.
154154

155+
### Exclude pattern: `!`
156+
157+
For any files you wish to exclude, use the same glob pattern but prepend it with `!`
158+
159+
```
160+
lint_staged:
161+
'lib/**.dart': your-cmd
162+
'!lib/**.g.dart': your-cmd
163+
```
164+
165+
This would include all .dart files, but exclude .g.dart files.
166+
167+
155168
## What commands are supported?
156169

157170
Supported are any executables installed locally or globally via `pub` as well as any executable from your \$PATH.

lib/src/group.dart

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,33 @@ Map<String, Group> groupFilesByConfig(
1414
{required Map<String, List<String>> config, required List<String> files}) {
1515
final fileSet = files.toSet();
1616
final groups = <String, Group>{};
17-
for (var entry in config.entries) {
17+
18+
// Separate config into inclusion and exclusion patterns
19+
final includeConfig = config.entries.where((e) => !e.key.startsWith('!'));
20+
final excludeConfig = config.entries.where((e) => e.key.startsWith('!'));
21+
22+
// First, include files based on inclusion patterns
23+
for (var entry in includeConfig) {
1824
final glob = Glob(entry.key);
19-
final files = <String>[];
20-
for (var file in fileSet) {
21-
if (glob.matches(file)) {
22-
files.add(file);
23-
}
24-
}
25+
final matchedFiles = fileSet.where((file) => glob.matches(file)).toList();
2526

26-
/// Files should only match a single entry
27-
for (var file in files) {
28-
fileSet.remove(file);
27+
if (matchedFiles.isNotEmpty) {
28+
_verbose('$glob matched files: $matchedFiles');
29+
groups[entry.key] = Group(scripts: entry.value, files: matchedFiles);
2930
}
30-
if (files.isNotEmpty) {
31-
_verbose('$glob matched files: $files');
32-
groups[entry.key] = Group(scripts: entry.value, files: files);
31+
}
32+
33+
// Next, exclude files based on exclusion patterns
34+
for (var entry in excludeConfig) {
35+
final glob = Glob(entry.key.substring(1)); // Remove the '!' prefix
36+
final excludedFiles = fileSet.where((file) => glob.matches(file)).toSet();
37+
38+
// Remove excluded files from each group
39+
for (var group in groups.values) {
40+
_verbose('$glob excluded files: $excludedFiles');
41+
group.files.removeWhere((file) => excludedFiles.contains(file));
3342
}
3443
}
44+
3545
return groups;
3646
}

test/integration/__fixtures__/config.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ const kConfigFormatFix = '''lint_staged:
22
'lib/**.dart': dart format --fix
33
''';
44

5+
const kConfigFormatFixWithIgnore = '''lint_staged:
6+
'lib/**.dart': dart format --fix
7+
'!lib/**.g.dart': dart format --fix
8+
''';
9+
510
const kConfigFormatExit = '''lint_staged:
611
'lib/**.dart': dart format --set-exit-if-changed
712
''';

test/integration/basic_functionality_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,29 @@ void main() {
198198
expect(await project.git.lastCommit, contains('test'));
199199
expect(await project.fs.read('lib/main.dart'), equals(kFormattedDart));
200200
});
201+
202+
test('ignores files given in pubspec.yaml', () async {
203+
final project = IntegrationProject();
204+
print('dir: ${project.path}');
205+
await project.setup();
206+
207+
await project.fs.write('pubspec.yaml', kConfigFormatFixWithIgnore);
208+
209+
// Stage multi unformatted files
210+
await project.fs.write('lib/main.dart', kUnFormattedDart);
211+
await project.git.run(['add', 'lib/main.dart']);
212+
213+
await project.fs.write('lib/foo.g.dart', kUnFormattedDart);
214+
await project.git.run(['add', 'lib/foo.g.dart']);
215+
216+
// Run lint_staged to automatically format the file and commit formatted files
217+
await project.gitCommit();
218+
219+
// main.dart should be formatted, while foo.g.dart should not
220+
expect(await project.git.commitCount, equals(2));
221+
expect(await project.git.lastCommit, contains('test'));
222+
expect(await project.fs.read('lib/main.dart'), equals(kFormattedDart));
223+
expect(await project.fs.read('lib/foo.g.dart'), equals(kUnFormattedDart));
224+
});
201225
});
202226
}

test/integration/utils.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class IntegrationProject {
1717
Future<void> setup({bool initialCommit = true}) async {
1818
/// Git init
1919
await Process.run('git', ['init', path]);
20+
await fs.write('.gitattributes', '*.dart text eol=lf');
2021

2122
/// Git config
2223
await config();
@@ -35,7 +36,7 @@ class IntegrationProject {
3536

3637
Future<void> _initialCommit() async {
3738
await fs.append('README.md', '# Test\n');
38-
await git.run(['add', 'README.md']);
39+
await git.run(['add', 'README.md', '.gitattributes']);
3940
await git.run(['commit', '-m initial commit']);
4041
}
4142

0 commit comments

Comments
 (0)