blob: aea33edc83e41d652c713f6f2172dc493c099734 [file] [log] [blame]
// Copyright (c) 2020, 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 'package:args/args.dart';
import '../style_fix.dart';
void defineOptions(ArgParser parser,
{bool oldCli = false, bool verbose = false}) {
if (oldCli) {
// The Command class implicitly adds "--help", so we only need to manually
// add it for the old CLI.
abbr: 'h',
negatable: false,
help: 'Show this usage information.\n'
'(pass "--verbose" or "-v" to see all options)');
// Always make verbose hidden since the help text for --help explains it.
parser.addFlag('verbose', abbr: 'v', negatable: false, hide: true);
} else {
abbr: 'v',
negatable: false,
help: 'Show all options and flags with --help.');
if (verbose) parser.addSeparator('Output options:');
if (oldCli) {
abbr: 'w',
negatable: false,
help: 'Overwrite input files with formatted output.');
abbr: 'n',
negatable: false,
help: 'Show which files would be modified but make no changes.');
} else {
abbr: 'o',
help: 'Set where to write formatted output.',
allowed: ['write', 'show', 'json', 'none'],
allowedHelp: {
'write': 'Overwrite formatted files on disk.',
'show': 'Print code to terminal.',
'json': 'Print code and selection as JSON.',
'none': 'Discard output.'
defaultsTo: 'write');
help: 'Set which filenames to print.',
allowed: ['all', 'changed', 'none'],
allowedHelp: {
'all': 'All visited files and directories.',
'changed': 'Only the names of files whose formatting is changed.',
'none': 'No file names or directories.',
defaultsTo: 'changed',
hide: !verbose);
help: 'Show the specified summary after formatting.',
allowed: ['line', 'profile', 'none'],
allowedHelp: {
'line': 'Single-line summary.',
'profile': 'How long it took for format each file.',
'none': 'No summary.'
defaultsTo: 'line',
hide: !verbose);
negatable: false,
help: 'Return exit code 1 if there are any formatting changes.');
if (verbose) parser.addSeparator('Non-whitespace fixes (off by default):');
parser.addFlag('fix', negatable: false, help: 'Apply all style fixes.');
for (var fix in StyleFix.all) {
// TODO(rnystrom): Allow negating this if used in concert with "--fix"?
negatable: false, help: fix.description, hide: !verbose);
if (verbose) parser.addSeparator('Other options:');
abbr: 'l', help: 'Wrap lines longer than this.', defaultsTo: '80');
abbr: 'i',
help: 'Add this many spaces of leading indentation.',
defaultsTo: '0',
hide: !verbose);
if (oldCli) {
abbr: 'm',
negatable: false,
help: 'Produce machine-readable JSON output.',
hide: !verbose);
negatable: false,
help: 'Follow links to files and directories.\n'
'If unset, links will be ignored.',
hide: !verbose);
negatable: false, help: 'Show dart_style version.', hide: !verbose);
if (verbose) parser.addSeparator('Options when formatting from stdin:');
parser.addOption(oldCli ? 'preserve' : 'selection',
help: 'Track selection (given as "start:length") through formatting.',
hide: !verbose);
help: 'Use this path in error messages when input is read from stdin.',
defaultsTo: 'stdin',
hide: !verbose);
if (oldCli) {
parser.addFlag('profile', negatable: false, hide: true);
// Ancient no longer used flag.
parser.addFlag('transform', abbr: 't', negatable: false, hide: true);
List<int>? parseSelection(ArgResults argResults, String optionName) {
var option = argResults[optionName] as String?;
if (option == null) return null;
// Can only preserve a selection when parsing from stdin.
if ( {
throw FormatException(
'Can only use --$optionName when reading from stdin.');
try {
var coordinates = option.split(':');
if (coordinates.length != 2) {
throw FormatException(
'Selection should be a colon-separated pair of integers, "123:45".');
return<int>((coord) => int.parse(coord.trim())).toList();
} on FormatException catch (_) {
throw FormatException(
'--$optionName must be a colon-separated pair of integers, was '