in lib/src/cli.dart [49:178]
Future runLinter(List<String> args, LinterOptions initialLintOptions) async {
// Force the rule registry to be populated.
registerLintRules();
var parser = ArgParser();
parser
..addFlag('help',
abbr: 'h', negatable: false, help: 'Show usage information.')
..addFlag('stats',
abbr: 's', negatable: false, help: 'Show lint statistics.')
..addFlag('benchmark', negatable: false, help: 'Show lint benchmarks.')
..addFlag('visit-transitive-closure',
help: 'Visit the transitive closure of imported/exported libraries.')
..addFlag('quiet', abbr: 'q', help: "Don't show individual lint errors.")
..addFlag('machine',
help: 'Print results in a format suitable for parsing.',
negatable: false)
..addOption('config', abbr: 'c', help: 'Use configuration from this file.')
..addOption('dart-sdk', help: 'Custom path to a Dart SDK.')
..addMultiOption('rules',
help: 'A list of lint rules to run. For example: '
'avoid_as,annotate_overrides')
..addOption('packages',
help: 'Path to the package resolution configuration file, which\n'
'supplies a mapping of package names to paths.');
ArgResults options;
try {
options = parser.parse(args);
} on FormatException catch (err) {
printUsage(parser, errorSink, err.message);
exitCode = unableToProcessExitCode;
return;
}
if (options['help'] as bool) {
printUsage(parser, outSink);
return;
}
if (options.rest.isEmpty) {
printUsage(parser, errorSink,
'Please provide at least one file or directory to lint.');
exitCode = unableToProcessExitCode;
return;
}
var lintOptions = initialLintOptions;
var configFile = options['config'];
if (configFile is String) {
var config = LintConfig.parse(readFile(configFile));
lintOptions.configure(config);
}
var lints = options['rules'];
if (lints is Iterable<String> && lints.isNotEmpty) {
var rules = <LintRule>[];
for (var lint in lints) {
var rule = Registry.ruleRegistry[lint];
if (rule == null) {
errorSink.write('Unrecognized lint rule: $lint');
exit(unableToProcessExitCode);
}
rules.add(rule);
}
lintOptions.enabledLints = rules;
}
var customSdk = options['dart-sdk'];
if (customSdk is String) {
lintOptions.dartSdkPath = customSdk;
}
var packageConfigFile = options['packages'] as String?;
packageConfigFile = packageConfigFile != null
? _absoluteNormalizedPath(packageConfigFile)
: null;
var stats = options['stats'] as bool;
var benchmark = options['benchmark'] as bool;
if (stats || benchmark) {
lintOptions.enableTiming = true;
}
lintOptions
..packageConfigPath = packageConfigFile
..resourceProvider = PhysicalResourceProvider.INSTANCE;
var filesToLint = <File>[];
for (var path in options.rest) {
filesToLint.addAll(
collectFiles(path)
.map((file) => _absoluteNormalizedPath(file.path))
.map((path) => File(path)),
);
}
if (benchmark) {
await writeBenchmarks(outSink, filesToLint, lintOptions);
return;
}
var linter = DartLinter(lintOptions);
try {
var timer = Stopwatch()..start();
var errors = await lintFiles(linter, filesToLint);
timer.stop();
var commonRoot = getRoot(options.rest);
var machine = options['machine'] ?? false;
var quiet = options['quiet'] ?? false;
ReportFormatter(errors, lintOptions.filter, outSink,
elapsedMs: timer.elapsedMilliseconds,
fileCount: linter.numSourcesAnalyzed,
fileRoot: commonRoot,
showStatistics: stats,
machineOutput: machine as bool,
quiet: quiet as bool)
.write();
// ignore: avoid_catches_without_on_clauses
} catch (err, stack) {
errorSink.writeln('''An error occurred while linting
Please report it at: github.com/dart-lang/linter/issues
$err
$stack''');
}
}