-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[tool] Add initial file-based command skipping #8928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
2d70133
09ab2da
72248b0
3ba35e0
ed206c8
dfab5c2
f62c278
b1b16ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ import 'dart:io' as io; | |
|
|
||
| import 'package:file/file.dart'; | ||
|
|
||
| import 'common/core.dart'; | ||
| import 'common/output_utils.dart'; | ||
| import 'common/package_looping_command.dart'; | ||
| import 'common/repository_package.dart'; | ||
|
|
@@ -92,6 +93,24 @@ class AnalyzeCommand extends PackageLoopingCommand { | |
| return false; | ||
| } | ||
|
|
||
| @override | ||
| bool shouldIgnoreFile(String path) { | ||
| return repoLevelNonCodeImpactingFiles.contains(path) || | ||
| // Native code, which is not part of Dart analysis. | ||
| path.endsWith('.c') || | ||
| path.endsWith('.cc') || | ||
| path.endsWith('.cpp') || | ||
| path.endsWith('.h') || | ||
| path.endsWith('.m') || | ||
| path.endsWith('.swift') || | ||
| path.endsWith('.java') || | ||
| path.endsWith('.kt') || | ||
| // Package metadata that doesn't impact analysis. | ||
| path.endsWith('/AUTHORS') || | ||
|
||
| path.endsWith('/CHANGELOG.md') || | ||
| path.endsWith('/README.md'); | ||
| } | ||
|
|
||
| @override | ||
| Future<void> initializeRun() async { | ||
| _allowedCustomAnalysisDirectories = getYamlListArg(_customAnalysisFlag); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,12 +16,13 @@ void main() { | |
| late MockPlatform mockPlatform; | ||
| late Directory packagesDir; | ||
| late RecordingProcessRunner processRunner; | ||
| late RecordingProcessRunner gitProcessRunner; | ||
| late CommandRunner<void> runner; | ||
|
|
||
| setUp(() { | ||
| mockPlatform = MockPlatform(); | ||
| final GitDir gitDir; | ||
| (:packagesDir, :processRunner, gitProcessRunner: _, :gitDir) = | ||
| (:packagesDir, :processRunner, :gitProcessRunner, :gitDir) = | ||
| configureBaseCommandMocks(platform: mockPlatform); | ||
| final AnalyzeCommand analyzeCommand = AnalyzeCommand( | ||
| packagesDir, | ||
|
|
@@ -470,4 +471,90 @@ void main() { | |
| ]), | ||
| ); | ||
| }); | ||
|
|
||
| group('file filtering', () { | ||
| test('runs command for changes to Dart source', () async { | ||
| createFakePackage('package_a', packagesDir); | ||
|
|
||
| gitProcessRunner.mockProcessesForExecutable['git-diff'] = | ||
| <FakeProcessInfo>[ | ||
| FakeProcessInfo(MockProcess(stdout: ''' | ||
| packages/package_a/foo.dart | ||
| ''')), | ||
| ]; | ||
|
|
||
| final List<String> output = | ||
| await runCapturingPrint(runner, <String>['analyze']); | ||
|
|
||
| expect( | ||
| output, | ||
| containsAllInOrder(<Matcher>[ | ||
| contains('Running for package_a'), | ||
| ])); | ||
| }); | ||
|
|
||
| const List<String> files = <String>[ | ||
| 'foo.java', | ||
| 'foo.kt', | ||
| 'foo.m', | ||
| 'foo.swift', | ||
| 'foo.c', | ||
| 'foo.cc', | ||
| 'foo.cpp', | ||
| 'foo.h', | ||
| ]; | ||
| for (final String file in files) { | ||
| test('skips command for changes to non-Dart source $file', () async { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't seen running Also, this include the Same for the command tests below.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure we do it in a few other places already. VS Code supports it well; it looks like this before you run it:
Re-running individual entries from the IDE works. (IIRC, the way Dart
The problem we had was with |
||
| createFakePackage('package_a', packagesDir); | ||
|
|
||
| gitProcessRunner.mockProcessesForExecutable['git-diff'] = | ||
| <FakeProcessInfo>[ | ||
| FakeProcessInfo(MockProcess(stdout: ''' | ||
| packages/package_a/$file | ||
| ''')), | ||
| ]; | ||
|
|
||
| final List<String> output = | ||
| await runCapturingPrint(runner, <String>['analyze']); | ||
|
|
||
| expect( | ||
| output, | ||
| isNot(containsAllInOrder(<Matcher>[ | ||
| contains('Running for package_a'), | ||
| ]))); | ||
| expect( | ||
| output, | ||
| containsAllInOrder(<Matcher>[ | ||
| contains('SKIPPING ALL PACKAGES'), | ||
| ])); | ||
| }); | ||
| } | ||
|
|
||
| test('skips commands if all files should be ignored', () async { | ||
| createFakePackage('package_a', packagesDir); | ||
|
|
||
| gitProcessRunner.mockProcessesForExecutable['git-diff'] = | ||
| <FakeProcessInfo>[ | ||
| FakeProcessInfo(MockProcess(stdout: ''' | ||
| README.md | ||
| CODEOWNERS | ||
| packages/package_a/CHANGELOG.md | ||
| ''')), | ||
| ]; | ||
|
|
||
| final List<String> output = | ||
| await runCapturingPrint(runner, <String>['analyze']); | ||
|
|
||
| expect( | ||
| output, | ||
| isNot(containsAllInOrder(<Matcher>[ | ||
| contains('Running for package_a'), | ||
| ]))); | ||
| expect( | ||
| output, | ||
| containsAllInOrder(<Matcher>[ | ||
| contains('SKIPPING ALL PACKAGES'), | ||
| ])); | ||
| }); | ||
| }); | ||
| } | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think this could also be a list named something like
sourceFileExtensions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea; extracted into a helper called
isNativeCodeFile. I also changed therepoLevelNonCodeImpactingFileslist into a helper method for consistency, so everything can just call a set of helpers without it mattering whether it's an exact-match list or a more complicated pattern.