This repository was archived by the owner on Nov 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 166
move cli main into lib/
#1114
Merged
Merged
move cli main into lib/
#1114
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | ||
// 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 'dart:async'; | ||
import 'dart:io'; | ||
|
||
import 'package:analyzer/file_system/physical_file_system.dart'; | ||
import 'package:analyzer/src/generated/engine.dart'; | ||
import 'package:analyzer/src/lint/config.dart'; | ||
import 'package:analyzer/src/lint/io.dart'; | ||
import 'package:analyzer/src/lint/linter.dart'; | ||
import 'package:analyzer/src/lint/registry.dart'; | ||
import 'package:args/args.dart'; | ||
import 'package:linter/src/analyzer.dart'; | ||
import 'package:linter/src/formatter.dart'; | ||
import 'package:linter/src/rules.dart'; | ||
|
||
/// Start linting from the command-line. | ||
Future run(List<String> args) async { | ||
await runLinter(args, new LinterOptions()..previewDart2 = true); | ||
} | ||
|
||
const processFileFailedExitCode = 65; | ||
const unableToProcessExitCode = 64; | ||
|
||
String getRoot(List<String> paths) => | ||
paths.length == 1 && new Directory(paths[0]).existsSync() ? paths[0] : null; | ||
|
||
bool isLinterErrorCode(int code) => | ||
code == unableToProcessExitCode || code == processFileFailedExitCode; | ||
|
||
void printUsage(ArgParser parser, IOSink out, [String error]) { | ||
var message = 'Lints Dart source files and pubspecs.'; | ||
if (error != null) { | ||
message = error; | ||
} | ||
|
||
out.writeln('''$message | ||
Usage: linter <file> | ||
${parser.usage} | ||
|
||
For more information, see https://github.com/dart-lang/linter | ||
'''); | ||
} | ||
|
||
Future runLinter(List<String> args, LinterOptions initialLintOptions) async { | ||
// Force the rule registry to be populated. | ||
registerLintRules(); | ||
|
||
var parser = new ArgParser(allowTrailingOptions: true); | ||
|
||
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.', | ||
defaultsTo: false, | ||
negatable: false) | ||
..addFlag('strong', help: 'Use strong-mode analyzer.') | ||
..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. This option\n' | ||
'cannot be used with --package-root.') | ||
..addOption('package-root', | ||
abbr: 'p', help: 'Custom package root. (Discouraged.)'); | ||
|
||
ArgResults options; | ||
try { | ||
options = parser.parse(args); | ||
} on FormatException catch (err) { | ||
printUsage(parser, errorSink, err.message); | ||
exitCode = unableToProcessExitCode; | ||
return; | ||
} | ||
|
||
if (options['help']) { | ||
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 != null) { | ||
var config = new LintConfig.parse(readFile(configFile)); | ||
lintOptions.configure(config); | ||
} | ||
|
||
var lints = options['rules']; | ||
if (lints != null && !lints.isEmpty) { | ||
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 != null) { | ||
lintOptions.dartSdkPath = customSdk; | ||
} | ||
|
||
var strongMode = options['strong']; | ||
if (strongMode != null) lintOptions.strongMode = strongMode; | ||
|
||
var customPackageRoot = options['package-root']; | ||
if (customPackageRoot != null) { | ||
lintOptions.packageRootPath = customPackageRoot; | ||
} | ||
|
||
var packageConfigFile = options['packages']; | ||
|
||
if (customPackageRoot != null && packageConfigFile != null) { | ||
errorSink.write("Cannot specify both '--package-root' and '--packages'."); | ||
exitCode = unableToProcessExitCode; | ||
return; | ||
} | ||
|
||
var stats = options['stats']; | ||
var benchmark = options['benchmark']; | ||
if (stats || benchmark) { | ||
lintOptions.enableTiming = true; | ||
} | ||
|
||
lintOptions | ||
..packageConfigPath = packageConfigFile | ||
..resourceProvider = PhysicalResourceProvider.INSTANCE; | ||
|
||
List<File> filesToLint = []; | ||
for (var path in options.rest) { | ||
filesToLint.addAll(collectFiles(path)); | ||
} | ||
|
||
if (benchmark) { | ||
await writeBenchmarks(outSink, filesToLint, lintOptions); | ||
return; | ||
} | ||
|
||
final linter = new DartLinter(lintOptions); | ||
|
||
try { | ||
final timer = new Stopwatch()..start(); | ||
List<AnalysisErrorInfo> errors = await lintFiles(linter, filesToLint); | ||
timer.stop(); | ||
|
||
var commonRoot = getRoot(options.rest); | ||
new ReportFormatter(errors, lintOptions.filter, outSink, | ||
elapsedMs: timer.elapsedMilliseconds, | ||
fileCount: linter.numSourcesAnalyzed, | ||
fileRoot: commonRoot, | ||
showStatistics: stats, | ||
machineOutput: options['machine'], | ||
quiet: options['quiet']) | ||
..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 | ||
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. Move this catch to 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. ...make sure to set the exit code to an error! |
||
$err | ||
$stack'''); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
pro tip: return the exit code from this method – set it in
bin
. Makes testing MUCH easier.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.
Great point. That said, I think these cases are pretty well covered in our integration tests. Are you making a general point or do you see cases we're missing?