OLD | NEW |
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 |
9 import 'package:dart_style/src/dart_formatter.dart'; | 10 import 'package:dart_style/src/dart_formatter.dart'; |
10 import 'package:dart_style/src/formatter_exception.dart'; | 11 import 'package:dart_style/src/formatter_exception.dart'; |
11 import 'package:dart_style/src/formatter_options.dart'; | 12 import 'package:dart_style/src/formatter_options.dart'; |
12 import 'package:dart_style/src/io.dart'; | 13 import 'package:dart_style/src/io.dart'; |
13 import 'package:dart_style/src/source_code.dart'; | 14 import 'package:dart_style/src/source_code.dart'; |
14 | 15 |
| 16 // Note: The following line of code is modified by tool/grind.dart. |
| 17 const version = "0.2.1"; |
| 18 |
15 void main(List<String> args) { | 19 void main(List<String> args) { |
16 var parser = new ArgParser(allowTrailingOptions: true); | 20 var parser = new ArgParser(allowTrailingOptions: true); |
17 | 21 |
18 parser.addFlag("help", | 22 parser.addFlag("help", |
19 abbr: "h", negatable: false, help: "Shows usage information."); | 23 abbr: "h", negatable: false, help: "Shows usage information."); |
| 24 parser.addFlag("version", |
| 25 negatable: false, help: "Shows version information."); |
20 parser.addOption("line-length", | 26 parser.addOption("line-length", |
21 abbr: "l", help: "Wrap lines longer than this.", defaultsTo: "80"); | 27 abbr: "l", help: "Wrap lines longer than this.", defaultsTo: "80"); |
| 28 parser.addOption("indent", |
| 29 abbr: "i", help: "Spaces of leading indentation.", defaultsTo: "0"); |
22 parser.addOption("preserve", | 30 parser.addOption("preserve", |
23 help: 'Selection to preserve, formatted as "start:length".'); | 31 help: 'Selection to preserve, formatted as "start:length".'); |
24 parser.addFlag("dry-run", | 32 parser.addFlag("dry-run", |
25 abbr: "n", | 33 abbr: "n", |
26 negatable: false, | 34 negatable: false, |
27 help: "Show which files would be modified but make no changes."); | 35 help: "Show which files would be modified but make no changes."); |
28 parser.addFlag("overwrite", | 36 parser.addFlag("overwrite", |
29 abbr: "w", | 37 abbr: "w", |
30 negatable: false, | 38 negatable: false, |
31 help: "Overwrite input files with formatted output."); | 39 help: "Overwrite input files with formatted output."); |
32 parser.addFlag("machine", | 40 parser.addFlag("machine", |
33 abbr: "m", | 41 abbr: "m", |
34 negatable: false, | 42 negatable: false, |
35 help: "Produce machine-readable JSON output."); | 43 help: "Produce machine-readable JSON output."); |
| 44 parser.addFlag("profile", |
| 45 negatable: false, help: "Display profile times after running."); |
36 parser.addFlag("follow-links", | 46 parser.addFlag("follow-links", |
37 negatable: false, | 47 negatable: false, |
38 help: "Follow links to files and directories.\n" | 48 help: "Follow links to files and directories.\n" |
39 "If unset, links will be ignored."); | 49 "If unset, links will be ignored."); |
40 parser.addFlag("transform", | 50 parser.addFlag("transform", |
41 abbr: "t", | 51 abbr: "t", |
42 negatable: false, | 52 negatable: false, |
43 help: "Unused flag for compability with the old formatter."); | 53 help: "Unused flag for compability with the old formatter."); |
44 | 54 |
45 var argResults; | 55 var argResults; |
46 try { | 56 try { |
47 argResults = parser.parse(args); | 57 argResults = parser.parse(args); |
48 } on FormatException catch (err) { | 58 } on FormatException catch (err) { |
49 usageError(parser, err.message); | 59 usageError(parser, err.message); |
50 } | 60 } |
51 | 61 |
52 if (argResults["help"]) { | 62 if (argResults["help"]) { |
53 printUsage(parser); | 63 printUsage(parser); |
54 return; | 64 return; |
55 } | 65 } |
56 | 66 |
| 67 if (argResults["version"]) { |
| 68 print(version); |
| 69 return; |
| 70 } |
| 71 |
57 // Can only preserve a selection when parsing from stdin. | 72 // Can only preserve a selection when parsing from stdin. |
58 var selection; | 73 var selection; |
59 | 74 |
60 if (argResults["preserve"] != null && argResults.rest.isNotEmpty) { | 75 if (argResults["preserve"] != null && argResults.rest.isNotEmpty) { |
61 usageError(parser, "Can only use --preserve when reading from stdin."); | 76 usageError(parser, "Can only use --preserve when reading from stdin."); |
62 } | 77 } |
63 | 78 |
64 try { | 79 try { |
65 selection = parseSelection(argResults["preserve"]); | 80 selection = parseSelection(argResults["preserve"]); |
66 } on FormatException catch (_) { | 81 } on FormatException catch (_) { |
(...skipping 26 matching lines...) Expand all Loading... |
93 if (argResults.rest.isEmpty) { | 108 if (argResults.rest.isEmpty) { |
94 usageError(parser, | 109 usageError(parser, |
95 "Cannot use --overwrite without providing any paths to format."); | 110 "Cannot use --overwrite without providing any paths to format."); |
96 } | 111 } |
97 | 112 |
98 reporter = OutputReporter.overwrite; | 113 reporter = OutputReporter.overwrite; |
99 } else if (argResults["machine"]) { | 114 } else if (argResults["machine"]) { |
100 reporter = OutputReporter.printJson; | 115 reporter = OutputReporter.printJson; |
101 } | 116 } |
102 | 117 |
| 118 if (argResults["profile"]) { |
| 119 reporter = new ProfileReporter(reporter); |
| 120 } |
| 121 |
103 var pageWidth; | 122 var pageWidth; |
104 | |
105 try { | 123 try { |
106 pageWidth = int.parse(argResults["line-length"]); | 124 pageWidth = int.parse(argResults["line-length"]); |
107 } on FormatException catch (_) { | 125 } on FormatException catch (_) { |
108 usageError( | 126 usageError( |
109 parser, | 127 parser, |
110 '--line-length must be an integer, was ' | 128 '--line-length must be an integer, was ' |
111 '"${argResults['line-length']}".'); | 129 '"${argResults['line-length']}".'); |
112 } | 130 } |
113 | 131 |
| 132 var indent; |
| 133 |
| 134 try { |
| 135 indent = int.parse(argResults["indent"]); |
| 136 if (indent < 0 || indent.toInt() != indent) throw new FormatException(); |
| 137 } on FormatException catch (_) { |
| 138 usageError( |
| 139 parser, |
| 140 '--indent must be a non-negative integer, was ' |
| 141 '"${argResults['indent']}".'); |
| 142 } |
| 143 |
114 var followLinks = argResults["follow-links"]; | 144 var followLinks = argResults["follow-links"]; |
115 | 145 |
116 var options = new FormatterOptions(reporter, | 146 var options = new FormatterOptions(reporter, |
117 pageWidth: pageWidth, followLinks: followLinks); | 147 indent: indent, pageWidth: pageWidth, followLinks: followLinks); |
118 | 148 |
119 if (argResults.rest.isEmpty) { | 149 if (argResults.rest.isEmpty) { |
120 formatStdin(options, selection); | 150 formatStdin(options, selection); |
121 } else { | 151 } else { |
122 formatPaths(options, argResults.rest); | 152 formatPaths(options, argResults.rest); |
123 } | 153 } |
| 154 |
| 155 if (argResults["profile"]) { |
| 156 (reporter as ProfileReporter).showProfile(); |
| 157 } |
124 } | 158 } |
125 | 159 |
126 List<int> parseSelection(String selection) { | 160 List<int> parseSelection(String selection) { |
127 if (selection == null) return null; | 161 if (selection == null) return null; |
128 | 162 |
129 var coordinates = selection.split(":"); | 163 var coordinates = selection.split(":"); |
130 if (coordinates.length != 2) { | 164 if (coordinates.length != 2) { |
131 throw new FormatException( | 165 throw new FormatException( |
132 'Selection should be a colon-separated pair of integers, "123:45".'); | 166 'Selection should be a colon-separated pair of integers, "123:45".'); |
133 } | 167 } |
134 | 168 |
135 return coordinates.map((coord) => coord.trim()).map(int.parse).toList(); | 169 return coordinates.map((coord) => coord.trim()).map(int.parse).toList(); |
136 } | 170 } |
137 | 171 |
138 /// Reads input from stdin until it's closed, and the formats it. | 172 /// Reads input from stdin until it's closed, and the formats it. |
139 void formatStdin(FormatterOptions options, List<int> selection) { | 173 void formatStdin(FormatterOptions options, List<int> selection) { |
140 var selectionStart = 0; | 174 var selectionStart = 0; |
141 var selectionLength = 0; | 175 var selectionLength = 0; |
142 | 176 |
143 if (selection != null) { | 177 if (selection != null) { |
144 selectionStart = selection[0]; | 178 selectionStart = selection[0]; |
145 selectionLength = selection[1]; | 179 selectionLength = selection[1]; |
146 } | 180 } |
147 | 181 |
148 var input = new StringBuffer(); | 182 var input = new StringBuffer(); |
149 stdin.transform(new Utf8Decoder()).listen(input.write, onDone: () { | 183 stdin.transform(new Utf8Decoder()).listen(input.write, onDone: () { |
150 var formatter = new DartFormatter(pageWidth: options.pageWidth); | 184 var formatter = |
| 185 new DartFormatter(indent: options.indent, pageWidth: options.pageWidth); |
151 try { | 186 try { |
| 187 options.reporter.beforeFile(null, "<stdin>"); |
152 var source = new SourceCode(input.toString(), | 188 var source = new SourceCode(input.toString(), |
153 uri: "stdin", | 189 uri: "stdin", |
154 selectionStart: selectionStart, | 190 selectionStart: selectionStart, |
155 selectionLength: selectionLength); | 191 selectionLength: selectionLength); |
156 var output = formatter.formatSource(source); | 192 var output = formatter.formatSource(source); |
157 options.reporter | 193 options.reporter |
158 .showFile(null, "<stdin>", output, changed: source != output); | 194 .afterFile(null, "<stdin>", output, changed: source != output); |
159 return true; | 195 return true; |
160 } on FormatterException catch (err) { | 196 } on FormatterException catch (err) { |
161 stderr.writeln(err.message()); | 197 stderr.writeln(err.message()); |
162 exitCode = 65; // sysexits.h: EX_DATAERR | 198 exitCode = 65; // sysexits.h: EX_DATAERR |
163 } catch (err, stack) { | 199 } catch (err, stack) { |
164 stderr.writeln('''Hit a bug in the formatter when formatting stdin. | 200 stderr.writeln('''Hit a bug in the formatter when formatting stdin. |
165 Please report at: github.com/dart-lang/dart_style/issues | 201 Please report at: github.com/dart-lang/dart_style/issues |
166 $err | 202 $err |
167 $stack'''); | 203 $stack'''); |
168 exitCode = 70; // sysexits.h: EX_SOFTWARE | 204 exitCode = 70; // sysexits.h: EX_SOFTWARE |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 output = stdout; | 243 output = stdout; |
208 } | 244 } |
209 | 245 |
210 output.write("""$message | 246 output.write("""$message |
211 | 247 |
212 Usage: dartfmt [-n|-w] [files or directories...] | 248 Usage: dartfmt [-n|-w] [files or directories...] |
213 | 249 |
214 ${parser.usage} | 250 ${parser.usage} |
215 """); | 251 """); |
216 } | 252 } |
OLD | NEW |