Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Add --ignore-files option to exclude files from code coverage using p…
Browse files Browse the repository at this point in the history
…ath patterns (#496)

* Add --ignore-files option, update tests

* Simplify checking if any glob matches the source

* Move logic to _getPathFilter

* Remove unused variable, avoid excessive calls to canonicalize

* Flatten ifs

* Avoid exceeding line length limit

* Add missing expects

* Remove junk
  • Loading branch information
gogolon committed Aug 1, 2024
1 parent 5ccac01 commit 43ac0e3
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 65 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Require Dart ^3.4
- Fix bug where some ranges were able to bypass the `--scope-output` filters.
- Add --ignore-files option allowing to exclude files from coverage reports using glob patterns

## 1.8.0

Expand Down
102 changes: 58 additions & 44 deletions bin/format_coverage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'dart:io';

import 'package:args/args.dart';
import 'package:coverage/coverage.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;

/// [Environment] stores gathered arguments information.
Expand All @@ -24,6 +25,7 @@ class Environment {
required this.prettyPrintFunc,
required this.prettyPrintBranch,
required this.reportOn,
required this.ignoreFiles,
required this.sdkRoot,
required this.verbose,
required this.workers,
Expand All @@ -42,6 +44,7 @@ class Environment {
bool prettyPrintFunc;
bool prettyPrintBranch;
List<String>? reportOn;
List<String>? ignoreFiles;
String? sdkRoot;
bool verbose;
int workers;
Expand Down Expand Up @@ -76,6 +79,8 @@ Future<void> main(List<String> arguments) async {
print('Done creating global hitmap. Took ${clock.elapsedMilliseconds} ms.');
}

final ignoreGlobs = env.ignoreFiles?.map(Glob.new).toSet();

String output;
final resolver = env.bazel
? BazelResolver(workspacePath: env.bazelWorkspace)
Expand All @@ -88,12 +93,15 @@ Future<void> main(List<String> arguments) async {
if (env.prettyPrint) {
output = await hitmap.prettyPrint(resolver, loader,
reportOn: env.reportOn,
ignoreGlobs: ignoreGlobs,
reportFuncs: env.prettyPrintFunc,
reportBranches: env.prettyPrintBranch);
} else {
assert(env.lcov);
output = hitmap.formatLcov(resolver,
reportOn: env.reportOn, basePath: env.baseDirectory);
reportOn: env.reportOn,
ignoreGlobs: ignoreGlobs,
basePath: env.baseDirectory);
}

env.output.write(output);
Expand Down Expand Up @@ -124,50 +132,54 @@ Future<void> main(List<String> arguments) async {
Environment parseArgs(List<String> arguments) {
final parser = ArgParser();

parser.addOption('sdk-root', abbr: 's', help: 'path to the SDK root');
parser.addOption('packages',
help: '[DEPRECATED] path to the package spec file');
parser.addOption('package',
help: 'root directory of the package', defaultsTo: '.');
parser.addOption('in', abbr: 'i', help: 'input(s): may be file or directory');
parser.addOption('out',
abbr: 'o', defaultsTo: 'stdout', help: 'output: may be file or stdout');
parser.addMultiOption('report-on',
help: 'which directories or files to report coverage on');
parser.addOption('workers',
abbr: 'j', defaultsTo: '1', help: 'number of workers');
parser.addOption('bazel-workspace',
defaultsTo: '', help: 'Bazel workspace directory');
parser.addOption('base-directory',
abbr: 'b',
help: 'the base directory relative to which source paths are output');
parser.addFlag('bazel',
defaultsTo: false, help: 'use Bazel-style path resolution');
parser.addFlag('pretty-print',
abbr: 'r',
negatable: false,
help: 'convert line coverage data to pretty print format');
parser.addFlag('pretty-print-func',
abbr: 'f',
parser
..addOption('sdk-root', abbr: 's', help: 'path to the SDK root')
..addOption('packages', help: '[DEPRECATED] path to the package spec file')
..addOption('package',
help: 'root directory of the package', defaultsTo: '.')
..addOption('in', abbr: 'i', help: 'input(s): may be file or directory')
..addOption('out',
abbr: 'o', defaultsTo: 'stdout', help: 'output: may be file or stdout')
..addMultiOption('report-on',
help: 'which directories or files to report coverage on')
..addOption('workers',
abbr: 'j', defaultsTo: '1', help: 'number of workers')
..addOption('bazel-workspace',
defaultsTo: '', help: 'Bazel workspace directory')
..addOption('base-directory',
abbr: 'b',
help: 'the base directory relative to which source paths are output')
..addFlag('bazel',
defaultsTo: false, help: 'use Bazel-style path resolution')
..addFlag('pretty-print',
abbr: 'r',
negatable: false,
help: 'convert line coverage data to pretty print format')
..addFlag('pretty-print-func',
abbr: 'f',
negatable: false,
help: 'convert function coverage data to pretty print format')
..addFlag('pretty-print-branch',
negatable: false,
help: 'convert branch coverage data to pretty print format')
..addFlag('lcov',
abbr: 'l',
negatable: false,
help: 'convert coverage data to lcov format')
..addFlag('verbose', abbr: 'v', negatable: false, help: 'verbose output')
..addFlag(
'check-ignore',
abbr: 'c',
negatable: false,
help: 'convert function coverage data to pretty print format');
parser.addFlag('pretty-print-branch',
negatable: false,
help: 'convert branch coverage data to pretty print format');
parser.addFlag('lcov',
abbr: 'l',
negatable: false,
help: 'convert coverage data to lcov format');
parser.addFlag('verbose',
abbr: 'v', negatable: false, help: 'verbose output');
parser.addFlag(
'check-ignore',
abbr: 'c',
negatable: false,
help: 'check for coverage ignore comments.'
' Not supported in web coverage.',
);
parser.addFlag('help', abbr: 'h', negatable: false, help: 'show this help');
help: 'check for coverage ignore comments.'
' Not supported in web coverage.',
)
..addMultiOption(
'ignore-files',
defaultsTo: [],
help: 'Ignore files by glob patterns',
)
..addFlag('help', abbr: 'h', negatable: false, help: 'show this help');

final args = parser.parse(arguments);

Expand Down Expand Up @@ -261,6 +273,7 @@ Environment parseArgs(List<String> arguments) {
}

final checkIgnore = args['check-ignore'] as bool;
final ignoredGlobs = args['ignore-files'] as List<String>;
final verbose = args['verbose'] as bool;
return Environment(
baseDirectory: baseDirectory,
Expand All @@ -276,6 +289,7 @@ Environment parseArgs(List<String> arguments) {
prettyPrintFunc: prettyPrintFunc,
prettyPrintBranch: prettyPrintBranch,
reportOn: reportOn,
ignoreFiles: ignoredGlobs,
sdkRoot: sdkRoot,
verbose: verbose,
workers: workers);
Expand Down
36 changes: 29 additions & 7 deletions lib/src/formatter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;

import 'hitmap.dart';
Expand Down Expand Up @@ -76,8 +77,12 @@ extension FileHitMapsFormatter on Map<String, HitMap> {
Resolver resolver, {
String? basePath,
List<String>? reportOn,
Set<Glob>? ignoreGlobs,
}) {
final pathFilter = _getPathFilter(reportOn);
final pathFilter = _getPathFilter(
reportOn: reportOn,
ignoreGlobs: ignoreGlobs,
);
final buf = StringBuffer();
for (final entry in entries) {
final v = entry.value;
Expand Down Expand Up @@ -136,10 +141,14 @@ extension FileHitMapsFormatter on Map<String, HitMap> {
Resolver resolver,
Loader loader, {
List<String>? reportOn,
Set<Glob>? ignoreGlobs,
bool reportFuncs = false,
bool reportBranches = false,
}) async {
final pathFilter = _getPathFilter(reportOn);
final pathFilter = _getPathFilter(
reportOn: reportOn,
ignoreGlobs: ignoreGlobs,
);
final buf = StringBuffer();
for (final entry in entries) {
final v = entry.value;
Expand Down Expand Up @@ -192,10 +201,23 @@ const _prefix = ' ';

typedef _PathFilter = bool Function(String path);

_PathFilter _getPathFilter(List<String>? reportOn) {
if (reportOn == null) return (String path) => true;
_PathFilter _getPathFilter({List<String>? reportOn, Set<Glob>? ignoreGlobs}) {
if (reportOn == null && ignoreGlobs == null) return (String path) => true;

final absolutePaths = reportOn.map(p.canonicalize).toList();
return (String path) =>
absolutePaths.any((item) => p.canonicalize(path).startsWith(item));
final absolutePaths = reportOn?.map(p.canonicalize).toList();

return (String path) {
final canonicalizedPath = p.canonicalize(path);

if (absolutePaths != null &&
!absolutePaths.any(canonicalizedPath.startsWith)) {
return false;
}
if (ignoreGlobs != null &&
ignoreGlobs.any((glob) => glob.matches(canonicalizedPath))) {
return false;
}

return true;
};
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ environment:

dependencies:
args: ^2.0.0
glob: ^2.1.2
logging: ^1.0.0
package_config: ^2.0.0
path: ^1.8.0
Expand Down
Loading

0 comments on commit 43ac0e3

Please sign in to comment.