blob: 7703107779f6056c1c8c1e62d87514984f8eb6e6 [file] [log] [blame]
// Copyright (c) 2015, 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:convert';
import 'dart:io';
import 'package:args/args.dart';
import 'package:dart_style/src/dart_formatter.dart';
import 'package:dart_style/src/formatter_exception.dart';
import 'package:dart_style/src/formatter_options.dart';
import 'package:dart_style/src/io.dart';
void main(List<String> args) {
var parser = new ArgParser(allowTrailingOptions: true);
parser.addFlag("help", abbr: "h", negatable: false,
help: "Shows usage information.");
parser.addOption("line-length", abbr: "l",
help: "Wrap lines longer than this.",
defaultsTo: "80");
parser.addFlag("dry-run", abbr: "n", negatable: false,
help: "Show which files would be modified but make no changes.");
parser.addFlag("overwrite", abbr: "w", negatable: false,
help: "Overwrite input files with formatted output.");
parser.addFlag("machine", abbr: "m", negatable: false,
help: "Produce machine-readable JSON output.");
parser.addFlag("follow-links", negatable: false,
help: "Follow links to files and directories.\n"
"If unset, links will be ignored.");
parser.addFlag("transform", abbr: "t", negatable: false,
help: "Unused flag for compability with the old formatter.");
var argResults;
try {
argResults = parser.parse(args);
} on FormatException catch (err) {
printUsage(parser, err.message);
exitCode = 64;
return;
}
if (argResults["help"]) {
printUsage(parser);
return;
}
if (argResults["dry-run"] && argResults["overwrite"]) {
printUsage(parser,
"Cannot use --dry-run and --overwrite at the same time.");
exitCode = 64;
return;
}
checkForReporterCollision(String chosen, String other) {
if (!argResults[other]) return false;
printUsage(parser,
"Cannot use --$chosen and --$other at the same time.");
exitCode = 64;
return true;
}
var reporter = OutputReporter.print;
if (argResults["dry-run"]) {
if (checkForReporterCollision("dry-run", "overwrite")) return;
if (checkForReporterCollision("dry-run", "machine")) return;
reporter = OutputReporter.dryRun;
} else if (argResults["overwrite"]) {
if (checkForReporterCollision("overwrite", "machine")) return;
if (argResults.rest.isEmpty) {
printUsage(parser,
"Cannot use --overwrite without providing any paths to format.");
exitCode = 64;
return;
}
reporter = OutputReporter.overwrite;
} else if (argResults["machine"]) {
reporter = OutputReporter.printJson;
}
var pageWidth;
try {
pageWidth = int.parse(argResults["line-length"]);
} on FormatException catch (_) {
printUsage(parser, '--line-length must be an integer, was '
'"${argResults['line-length']}".');
exitCode = 64;
return;
}
var followLinks = argResults["follow-links"];
var options = new FormatterOptions(reporter,
pageWidth: pageWidth, followLinks: followLinks);
if (argResults.rest.isEmpty) {
formatStdin(options);
} else {
formatPaths(options, argResults.rest);
}
}
/// Reads input from stdin until it's closed, and the formats it.
void formatStdin(FormatterOptions options) {
var input = new StringBuffer();
stdin.transform(new Utf8Decoder()).listen(input.write, onDone: () {
var formatter = new DartFormatter(pageWidth: options.pageWidth);
try {
var source = input.toString();
var output = formatter.format(source, uri: "stdin");
options.reporter.showFile(null, "<stdin>", output,
changed: source != output);
return true;
} on FormatterException catch (err) {
stderr.writeln(err.message());
} catch (err, stack) {
stderr.writeln('''Hit a bug in the formatter when formatting stdin.
Please report at: github.com/dart-lang/dart_style/issues
$err
$stack''');
}
});
}
/// Formats all of the files and directories given by [paths].
void formatPaths(FormatterOptions options, List<String> paths) {
for (var path in paths) {
var directory = new Directory(path);
if (directory.existsSync()) {
if (!processDirectory(options, directory)) {
exitCode = 65;
}
continue;
}
var file = new File(path);
if (file.existsSync()) {
if (!processFile(options, file)) {
exitCode = 65;
}
} else {
stderr.writeln('No file or directory found at "$path".');
}
}
}
void printUsage(ArgParser parser, [String error]) {
var output = stdout;
var message = "Reformats whitespace in Dart source files.";
if (error != null) {
message = error;
output = stdout;
}
output.write("""$message
Usage: dartfmt [-n|-w] [files or directories...]
${parser.usage}
""");
}