Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: bin/format.dart

Issue 968053004: Allow command-line API to pass in selection to preserve. Fix #194. (Closed) Base URL: https://github.com/dart-lang/dart_style.git@master
Patch Set: Update version Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « CHANGELOG.md ('k') | lib/src/formatter_options.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:convert'; 5 import 'dart:convert';
6 import 'dart:io'; 6 import 'dart:io';
7 7
8 import 'package:args/args.dart'; 8 import 'package:args/args.dart';
9 import 'package:dart_style/src/dart_formatter.dart'; 9 import 'package:dart_style/src/dart_formatter.dart';
10 import 'package:dart_style/src/formatter_exception.dart'; 10 import 'package:dart_style/src/formatter_exception.dart';
11 import 'package:dart_style/src/formatter_options.dart'; 11 import 'package:dart_style/src/formatter_options.dart';
12 import 'package:dart_style/src/io.dart'; 12 import 'package:dart_style/src/io.dart';
13 import 'package:dart_style/src/source_code.dart';
13 14
14 void main(List<String> args) { 15 void main(List<String> args) {
15 var parser = new ArgParser(allowTrailingOptions: true); 16 var parser = new ArgParser(allowTrailingOptions: true);
16 17
17 parser.addFlag("help", abbr: "h", negatable: false, 18 parser.addFlag("help", abbr: "h", negatable: false,
18 help: "Shows usage information."); 19 help: "Shows usage information.");
19 parser.addOption("line-length", abbr: "l", 20 parser.addOption("line-length", abbr: "l",
20 help: "Wrap lines longer than this.", 21 help: "Wrap lines longer than this.",
21 defaultsTo: "80"); 22 defaultsTo: "80");
23 parser.addOption("preserve",
24 help: 'Selection to preserve, formatted as "start:length".');
22 parser.addFlag("dry-run", abbr: "n", negatable: false, 25 parser.addFlag("dry-run", abbr: "n", negatable: false,
23 help: "Show which files would be modified but make no changes."); 26 help: "Show which files would be modified but make no changes.");
24 parser.addFlag("overwrite", abbr: "w", negatable: false, 27 parser.addFlag("overwrite", abbr: "w", negatable: false,
25 help: "Overwrite input files with formatted output."); 28 help: "Overwrite input files with formatted output.");
26 parser.addFlag("machine", abbr: "m", negatable: false, 29 parser.addFlag("machine", abbr: "m", negatable: false,
27 help: "Produce machine-readable JSON output."); 30 help: "Produce machine-readable JSON output.");
28 parser.addFlag("follow-links", negatable: false, 31 parser.addFlag("follow-links", negatable: false,
29 help: "Follow links to files and directories.\n" 32 help: "Follow links to files and directories.\n"
30 "If unset, links will be ignored."); 33 "If unset, links will be ignored.");
31 parser.addFlag("transform", abbr: "t", negatable: false, 34 parser.addFlag("transform", abbr: "t", negatable: false,
32 help: "Unused flag for compability with the old formatter."); 35 help: "Unused flag for compability with the old formatter.");
33 36
34 var argResults; 37 var argResults;
35 try { 38 try {
36 argResults = parser.parse(args); 39 argResults = parser.parse(args);
37 } on FormatException catch (err) { 40 } on FormatException catch (err) {
38 printUsage(parser, err.message); 41 usageError(parser, err.message);
39 exitCode = 64;
40 return;
41 } 42 }
42 43
43 if (argResults["help"]) { 44 if (argResults["help"]) {
44 printUsage(parser); 45 printUsage(parser);
45 return; 46 return;
46 } 47 }
47 48
49 // Can only preserve a selection when parsing from stdin.
50 var selection;
51
52 if (argResults["preserve"] != null && argResults.rest.isNotEmpty) {
53 usageError(parser, "Can only use --preserve when reading from stdin.");
54 }
55
56 try {
57 selection = parseSelection(argResults["preserve"]);
58 } on FormatException catch (_) {
59 usageError(parser,
60 '--preserve must be a colon-separated pair of integers, was '
61 '"${argResults['preserve']}".');
62 }
63
48 if (argResults["dry-run"] && argResults["overwrite"]) { 64 if (argResults["dry-run"] && argResults["overwrite"]) {
49 printUsage(parser, 65 usageError(parser,
50 "Cannot use --dry-run and --overwrite at the same time."); 66 "Cannot use --dry-run and --overwrite at the same time.");
51 exitCode = 64;
52 return;
53 } 67 }
54 68
55 checkForReporterCollision(String chosen, String other) { 69 checkForReporterCollision(String chosen, String other) {
56 if (!argResults[other]) return false; 70 if (!argResults[other]) return;
57 71
58 printUsage(parser, 72 usageError(parser,
59 "Cannot use --$chosen and --$other at the same time."); 73 "Cannot use --$chosen and --$other at the same time.");
60 exitCode = 64;
61 return true;
62 } 74 }
63 75
64 var reporter = OutputReporter.print; 76 var reporter = OutputReporter.print;
65 if (argResults["dry-run"]) { 77 if (argResults["dry-run"]) {
66 if (checkForReporterCollision("dry-run", "overwrite")) return; 78 checkForReporterCollision("dry-run", "overwrite");
67 if (checkForReporterCollision("dry-run", "machine")) return; 79 checkForReporterCollision("dry-run", "machine");
68 80
69 reporter = OutputReporter.dryRun; 81 reporter = OutputReporter.dryRun;
70 } else if (argResults["overwrite"]) { 82 } else if (argResults["overwrite"]) {
71 if (checkForReporterCollision("overwrite", "machine")) return; 83 checkForReporterCollision("overwrite", "machine");
72 84
73 if (argResults.rest.isEmpty) { 85 if (argResults.rest.isEmpty) {
74 printUsage(parser, 86 usageError(parser,
75 "Cannot use --overwrite without providing any paths to format."); 87 "Cannot use --overwrite without providing any paths to format.");
76 exitCode = 64;
77 return;
78 } 88 }
79 89
80 reporter = OutputReporter.overwrite; 90 reporter = OutputReporter.overwrite;
81 } else if (argResults["machine"]) { 91 } else if (argResults["machine"]) {
82 reporter = OutputReporter.printJson; 92 reporter = OutputReporter.printJson;
83 } 93 }
84 94
85 var pageWidth; 95 var pageWidth;
86 96
87 try { 97 try {
88 pageWidth = int.parse(argResults["line-length"]); 98 pageWidth = int.parse(argResults["line-length"]);
89 } on FormatException catch (_) { 99 } on FormatException catch (_) {
90 printUsage(parser, '--line-length must be an integer, was ' 100 usageError(parser, '--line-length must be an integer, was '
91 '"${argResults['line-length']}".'); 101 '"${argResults['line-length']}".');
92 exitCode = 64;
93 return;
94 } 102 }
95 103
96 var followLinks = argResults["follow-links"]; 104 var followLinks = argResults["follow-links"];
97 105
98 var options = new FormatterOptions(reporter, 106 var options = new FormatterOptions(reporter,
99 pageWidth: pageWidth, followLinks: followLinks); 107 pageWidth: pageWidth, followLinks: followLinks);
100 108
101 if (argResults.rest.isEmpty) { 109 if (argResults.rest.isEmpty) {
102 formatStdin(options); 110 formatStdin(options, selection);
103 } else { 111 } else {
104 formatPaths(options, argResults.rest); 112 formatPaths(options, argResults.rest);
105 } 113 }
106 } 114 }
107 115
116 List<int> parseSelection(String selection) {
117 if (selection == null) return null;
118
119 var coordinates = selection.split(":");
120 if (coordinates.length != 2) {
121 throw new FormatException(
122 'Selection should be a colon-separated pair of integers, "123:45".');
123 }
124
125 return coordinates.map((coord) => coord.trim()).map(int.parse).toList();
126 }
127
108 /// Reads input from stdin until it's closed, and the formats it. 128 /// Reads input from stdin until it's closed, and the formats it.
109 void formatStdin(FormatterOptions options) { 129 void formatStdin(FormatterOptions options, List<int> selection) {
130 var selectionStart = 0;
131 var selectionLength = 0;
132
133 if (selection != null) {
134 selectionStart = selection[0];
135 selectionLength = selection[1];
136 }
137
110 var input = new StringBuffer(); 138 var input = new StringBuffer();
111 stdin.transform(new Utf8Decoder()).listen(input.write, onDone: () { 139 stdin.transform(new Utf8Decoder()).listen(input.write, onDone: () {
112 var formatter = new DartFormatter(pageWidth: options.pageWidth); 140 var formatter = new DartFormatter(pageWidth: options.pageWidth);
113 try { 141 try {
114 var source = input.toString(); 142 var source = new SourceCode(input.toString(),
115 var output = formatter.format(source, uri: "stdin"); 143 uri: "stdin",
144 selectionStart: selectionStart,
145 selectionLength: selectionLength);
146 var output = formatter.formatSource(source);
116 options.reporter.showFile(null, "<stdin>", output, 147 options.reporter.showFile(null, "<stdin>", output,
117 changed: source != output); 148 changed: source != output);
118 return true; 149 return true;
119 } on FormatterException catch (err) { 150 } on FormatterException catch (err) {
120 stderr.writeln(err.message()); 151 stderr.writeln(err.message());
121 } catch (err, stack) { 152 } catch (err, stack) {
122 stderr.writeln('''Hit a bug in the formatter when formatting stdin. 153 stderr.writeln('''Hit a bug in the formatter when formatting stdin.
123 Please report at: github.com/dart-lang/dart_style/issues 154 Please report at: github.com/dart-lang/dart_style/issues
124 $err 155 $err
125 $stack'''); 156 $stack''');
(...skipping 16 matching lines...) Expand all
142 if (file.existsSync()) { 173 if (file.existsSync()) {
143 if (!processFile(options, file)) { 174 if (!processFile(options, file)) {
144 exitCode = 65; 175 exitCode = 65;
145 } 176 }
146 } else { 177 } else {
147 stderr.writeln('No file or directory found at "$path".'); 178 stderr.writeln('No file or directory found at "$path".');
148 } 179 }
149 } 180 }
150 } 181 }
151 182
183 /// Prints [error] and usage help then exits with exit code 64.
184 void usageError(ArgParser parser, String error) {
185 printUsage(parser, error);
186 exit(64);
187 }
188
152 void printUsage(ArgParser parser, [String error]) { 189 void printUsage(ArgParser parser, [String error]) {
153 var output = stdout; 190 var output = stdout;
154 191
155 var message = "Reformats whitespace in Dart source files."; 192 var message = "Reformats whitespace in Dart source files.";
156 if (error != null) { 193 if (error != null) {
157 message = error; 194 message = error;
158 output = stdout; 195 output = stdout;
159 } 196 }
160 197
161 output.write("""$message 198 output.write("""$message
162 199
163 Usage: dartfmt [-n|-w] [files or directories...] 200 Usage: dartfmt [-n|-w] [files or directories...]
164 201
165 ${parser.usage} 202 ${parser.usage}
166 """); 203 """);
167 } 204 }
OLDNEW
« no previous file with comments | « CHANGELOG.md ('k') | lib/src/formatter_options.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698