Skip to content

Commit 09dfe3e

Browse files
Merge pull request #466 from Workiva/handle_removed_dart_style_cli_option
Update FormatTool. -w bug fix and support language version
2 parents 4dd94f8 + 7ae8a00 commit 09dfe3e

63 files changed

Lines changed: 2662 additions & 1414 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/tools/format-tool.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ dartfmt -w --fix .
7979
----------------------------
8080
```
8181

82+
### Configuring the formatter language version
83+
84+
For formatters that support `--language-version`, you can configure the value
85+
used by `dart_dev`.
86+
87+
```dart
88+
// tool/dart_dev/config.dart
89+
import 'package:dart_dev/dart_dev.dart';
90+
91+
final config = {
92+
'format': FormatTool()
93+
..languageVersion = '3.0'
94+
};
95+
```
96+
97+
If `languageVersion` is not configured, `dart_dev` will use `latest` only in
98+
the cases where it decides the formatter needs an explicit language version.
99+
82100
### Excluding files from formatting
83101

84102
```dart

lib/src/core_config.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ library dart_dev.src.core_config;
66
import 'package:dart_dev/dart_dev.dart';
77

88
Map<String, DevTool> get coreConfig => {
9-
'analyze': AnalyzeTool(),
10-
'format': FormatTool(),
11-
'test': TestTool(),
12-
};
9+
'analyze': AnalyzeTool(),
10+
'format': FormatTool(),
11+
'test': TestTool(),
12+
};

lib/src/dart_dev_runner.dart

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import 'utils/version.dart';
1111

1212
class DartDevRunner extends CommandRunner<int> {
1313
DartDevRunner(Map<String, DevTool> commands)
14-
: super('dart_dev', 'Dart tool runner.') {
14+
: super('dart_dev', 'Dart tool runner.') {
1515
// For backwards-compatibility, only add the `clean` command if it doesn't
1616
// conflict with any configured command.
1717
if (!commands.containsKey('clean')) {
@@ -32,10 +32,17 @@ class DartDevRunner extends CommandRunner<int> {
3232
});
3333

3434
argParser
35-
..addFlag('verbose',
36-
abbr: 'v', negatable: false, help: 'Enables verbose logging.')
37-
..addFlag('version',
38-
negatable: false, help: 'Prints the dart_dev version.');
35+
..addFlag(
36+
'verbose',
37+
abbr: 'v',
38+
negatable: false,
39+
help: 'Enables verbose logging.',
40+
)
41+
..addFlag(
42+
'version',
43+
negatable: false,
44+
help: 'Prints the dart_dev version.',
45+
);
3946
}
4047

4148
@override
@@ -60,7 +67,8 @@ class DartDevRunner extends CommandRunner<int> {
6067
final exitCode = (await super.run(args)) ?? 0;
6168
stopwatch.stop();
6269
await events.commandComplete(
63-
events.CommandResult(args.toList(), exitCode, stopwatch.elapsed));
70+
events.CommandResult(args.toList(), exitCode, stopwatch.elapsed),
71+
);
6472
return exitCode;
6573
}
6674
}
@@ -71,6 +79,7 @@ class CommandNameMismatch implements Exception {
7179
CommandNameMismatch(this.actual, this.expected);
7280

7381
@override
74-
String toString() => 'CommandNameMismatch: '
82+
String toString() =>
83+
'CommandNameMismatch: '
7584
'Expected a "$expected" command but got one named "$actual".';
7685
}

lib/src/dart_dev_tool.dart

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,21 @@ abstract class DevTool {
1212
DevTool();
1313

1414
factory DevTool.fromFunction(
15-
FutureOr<int?> Function(DevToolExecutionContext context) function,
16-
{ArgParser? argParser}) =>
17-
FunctionTool(function, argParser: argParser);
18-
19-
factory DevTool.fromProcess(String executable, List<String> args,
20-
{ProcessStartMode? mode, String? workingDirectory}) =>
21-
ProcessTool(executable, args,
22-
mode: mode, workingDirectory: workingDirectory);
15+
FutureOr<int?> Function(DevToolExecutionContext context) function, {
16+
ArgParser? argParser,
17+
}) => FunctionTool(function, argParser: argParser);
18+
19+
factory DevTool.fromProcess(
20+
String executable,
21+
List<String> args, {
22+
ProcessStartMode? mode,
23+
String? workingDirectory,
24+
}) => ProcessTool(
25+
executable,
26+
args,
27+
mode: mode,
28+
workingDirectory: workingDirectory,
29+
);
2330

2431
/// The argument parser for this tool, if needed.
2532
///
@@ -79,12 +86,12 @@ abstract class DevTool {
7986
/// or not global verbose mode is enabled, and the [usageException] utility
8087
/// function from [Command].
8188
class DevToolExecutionContext {
82-
DevToolExecutionContext(
83-
{this.argResults,
84-
this.commandName,
85-
void Function(String message)? usageException,
86-
this.verbose = false})
87-
: _usageException = usageException;
89+
DevToolExecutionContext({
90+
this.argResults,
91+
this.commandName,
92+
void Function(String message)? usageException,
93+
this.verbose = false,
94+
}) : _usageException = usageException;
8895

8996
final void Function(String message)? _usageException;
9097

@@ -113,13 +120,12 @@ class DevToolExecutionContext {
113120
String? commandName,
114121
void Function(String message)? usageException,
115122
bool? verbose,
116-
}) =>
117-
DevToolExecutionContext(
118-
argResults: argResults ?? this.argResults,
119-
commandName: commandName ?? this.commandName,
120-
usageException: usageException ?? this.usageException,
121-
verbose: verbose ?? this.verbose,
122-
);
123+
}) => DevToolExecutionContext(
124+
argResults: argResults ?? this.argResults,
125+
commandName: commandName ?? this.commandName,
126+
usageException: usageException ?? this.usageException,
127+
verbose: verbose ?? this.verbose,
128+
);
123129

124130
/// Calling this will throw a [UsageException] with [message] that should be
125131
/// caught by [CommandRunner] and used to set the exit code accordingly and

lib/src/events.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import 'dart:async';
22

33
Future<void> commandComplete(CommandResult result) async {
4-
await Future.wait(_commandCompleteListeners
5-
.map((listener) => Future<void>.value(listener(result))));
4+
await Future.wait(
5+
_commandCompleteListeners.map(
6+
(listener) => Future<void>.value(listener(result)),
7+
),
8+
);
69
}
710

811
void onCommandComplete(FutureOr<void> Function(CommandResult result) callback) {

lib/src/executable.dart

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,19 @@ Future<void> run(List<String> args) async {
4141
final oldDevDartExists = File(_paths.legacyConfig).existsSync();
4242

4343
if (!configExists) {
44-
log.fine('No custom `${_paths.config}` file found; '
45-
'using default config.');
44+
log.fine(
45+
'No custom `${_paths.config}` file found; '
46+
'using default config.',
47+
);
4648
}
4749
if (oldDevDartExists) {
48-
log.warning(yellow.wrap(
50+
log.warning(
51+
yellow.wrap(
4952
'dart_dev v3 now expects configuration to be at `${_paths.config}`,\n'
5053
'but `${_paths.legacyConfig}` still exists. View the guide to see how to upgrade:\n'
51-
'https://github.com/Workiva/dart_dev/blob/master/doc/v3-upgrade-guide.md'));
54+
'https://github.com/Workiva/dart_dev/blob/master/doc/v3-upgrade-guide.md',
55+
),
56+
);
5257
}
5358

5459
if (args.contains('hackFastFormat') && !oldDevDartExists) {
@@ -57,13 +62,10 @@ Future<void> run(List<String> args) async {
5762
}
5863

5964
final processArgs = generateRunScript();
60-
final process = await Process.start(
61-
processArgs.first,
62-
[
63-
if (processArgs.length > 1) ...processArgs.sublist(1),
64-
...args,
65-
],
66-
mode: ProcessStartMode.inheritStdio);
65+
final process = await Process.start(processArgs.first, [
66+
if (processArgs.length > 1) ...processArgs.sublist(1),
67+
...args,
68+
], mode: ProcessStartMode.inheritStdio);
6769
ensureProcessExit(process);
6870
exitCode = await process.exitCode;
6971
}
@@ -75,17 +77,19 @@ Future<void> handleFastFormat(List<String> args) async {
7577
final configFile = File(_paths.config);
7678
if (configFile.existsSync()) {
7779
final toolBuilder = FormatToolBuilder();
78-
parseString(content: configFile.readAsStringSync())
79-
.unit
80-
.accept(toolBuilder);
80+
parseString(
81+
content: configFile.readAsStringSync(),
82+
).unit.accept(toolBuilder);
8183
formatTool = toolBuilder
8284
.formatDevTool; // could be null if no custom `format` entry found
8385

8486
if (formatTool == null && toolBuilder.failedToDetectAKnownFormatter) {
8587
exitCode = ExitCode.config.code;
86-
log.severe('Failed to reconstruct the format tool\'s configuration.\n\n'
87-
'This is likely because dart_dev expects either the FormatTool class or the\n'
88-
'OverReactFormatTool class.');
88+
log.severe(
89+
'Failed to reconstruct the format tool\'s configuration.\n\n'
90+
'This is likely because dart_dev expects either the FormatTool class or the\n'
91+
'OverReactFormatTool class.',
92+
);
8993
return;
9094
}
9195
}
@@ -116,27 +120,31 @@ bool _allPackagesAreImportedImmutably(Iterable<String> packageNames) {
116120
File pubspecLockFile = File('pubspec.lock');
117121
if (!pubspecLockFile.existsSync()) return false;
118122
final pubSpecLock = loadYamlDocument(pubspecLockFile.readAsStringSync());
119-
return getDependencySources(pubSpecLock, packageNames)
120-
.values
121-
.every((source) => source == 'hosted' || source == 'git');
123+
return getDependencySources(
124+
pubSpecLock,
125+
packageNames,
126+
).values.every((source) => source == 'hosted' || source == 'git');
122127
}
123128

124129
/// Return null iff it is not possible to account for all
125130
/// recompilation-necessitating factors in the digest.
126131
String? _computeRunScriptDigest() {
127-
final currentPackageName =
128-
Pubspec.parse(File('pubspec.yaml').readAsStringSync()).name;
132+
final currentPackageName = Pubspec.parse(
133+
File('pubspec.yaml').readAsStringSync(),
134+
).name;
129135
final configFile = File(_paths.config);
130136
var configHasRelativeImports = false;
131137
if (configFile.existsSync()) {
132138
final configImports = parseImports(configFile.readAsStringSync());
133139
configHasRelativeImports = configImports.any((i) => !i.contains(':'));
134-
final configHasSamePackageImports =
135-
configImports.any((i) => i.startsWith('package:$currentPackageName'));
140+
final configHasSamePackageImports = configImports.any(
141+
(i) => i.startsWith('package:$currentPackageName'),
142+
);
136143

137144
if (configHasSamePackageImports) {
138145
log.fine(
139-
'Skipping compilation because ${_paths.config} imports from its own package.');
146+
'Skipping compilation because ${_paths.config} imports from its own package.',
147+
);
140148

141149
// If the config imports from its own source files, we don't have a way of
142150
// efficiently tracking changes that would require recompilation of this
@@ -148,7 +156,8 @@ String? _computeRunScriptDigest() {
148156
final packageNames = computePackageNamesFromImports(configImports);
149157
if (!_allPackagesAreImportedImmutably(packageNames)) {
150158
log.fine(
151-
'Skipping compilation because ${_paths.config} imports non-hosted packages.');
159+
'Skipping compilation because ${_paths.config} imports non-hosted packages.',
160+
);
152161
_deleteRunExecutableAndDigest();
153162
return null;
154163
}
@@ -162,11 +171,14 @@ String? _computeRunScriptDigest() {
162171
if (packageConfig.existsSync()) ...packageConfig.readAsBytesSync(),
163172
if (configFile.existsSync()) ...configFile.readAsBytesSync(),
164173
if (configHasRelativeImports)
165-
for (final file in Glob('tool/**.dart', recursive: true)
166-
.listSync()
167-
.whereType<File>()
168-
.where((f) => p.canonicalize(f.path) != p.canonicalize(_paths.config))
169-
.sortedBy((f) => f.path))
174+
for (final file
175+
in Glob('tool/**.dart', recursive: true)
176+
.listSync()
177+
.whereType<File>()
178+
.where(
179+
(f) => p.canonicalize(f.path) != p.canonicalize(_paths.config),
180+
)
181+
.sortedBy((f) => f.path))
170182
...file.readAsBytesSync(),
171183
]);
172184
return base64.encode(digest.bytes);
@@ -190,9 +202,12 @@ List<String> generateRunScript() {
190202
// Generate a digest of inputs to the run script. We use this to determine
191203
// whether we need to recompile the executable.
192204
String? encodedDigest;
193-
logTimedSync(log, 'Computing run script digest',
194-
() => encodedDigest = _computeRunScriptDigest(),
195-
level: Level.FINE);
205+
logTimedSync(
206+
log,
207+
'Computing run script digest',
208+
() => encodedDigest = _computeRunScriptDigest(),
209+
level: Level.FINE,
210+
);
196211

197212
if (encodedDigest != null &&
198213
(!runExecutableDigest.existsSync() ||
@@ -210,7 +225,7 @@ List<String> generateRunScript() {
210225
'exe',
211226
_paths.runScript,
212227
'-o',
213-
_paths.runExecutable
228+
_paths.runExecutable,
214229
];
215230
final result = Process.runSync(Platform.executable, args);
216231
if (result.exitCode == 0) {
@@ -220,7 +235,8 @@ List<String> generateRunScript() {
220235
// Compilation failed. Dump some logs for debugging, but note to the
221236
// user that dart_dev should still work.
222237
log.warning(
223-
'Could not compile run script; dart_dev will continue without precompilation.');
238+
'Could not compile run script; dart_dev will continue without precompilation.',
239+
);
224240
log.fine('CMD: ${Platform.executable} ${args.join(" ")}');
225241
log.fine('STDOUT:\n${result.stdout}');
226242
log.fine('STDERR:\n${result.stderr}');
@@ -258,9 +274,10 @@ void main(List<String> args) async {
258274
}
259275

260276
Future<void> runWithConfig(
261-
// ignore: library_private_types_in_public_api
262-
List<String> args,
263-
_ConfigGetter configGetter) async {
277+
// ignore: library_private_types_in_public_api
278+
List<String> args,
279+
_ConfigGetter configGetter,
280+
) async {
264281
attachLoggerToStdio(args);
265282

266283
try {
@@ -278,8 +295,10 @@ Future<void> runWithConfig(
278295
stderr
279296
..writeln('Invalid "${_paths.config}" in ${p.absolute(p.current)}')
280297
..writeln()
281-
..writeln('It should provide a `Map<String, DevTool> config;` getter,'
282-
' but it either does not exist or threw unexpectedly:')
298+
..writeln(
299+
'It should provide a `Map<String, DevTool> config;` getter,'
300+
' but it either does not exist or threw unexpectedly:',
301+
)
283302
..writeln(' $error')
284303
..writeln()
285304
..writeln('For more info: https://github.com/Workiva/dart_dev');
@@ -307,7 +326,8 @@ Future<void> runWithConfig(
307326
DevTool chooseDefaultFormatTool({String? path}) {
308327
final pubspec = cachedPubspec(path: path);
309328
const orf = 'over_react_format';
310-
final hasOverReactFormat = pubspec.dependencies.containsKey(orf) ||
329+
final hasOverReactFormat =
330+
pubspec.dependencies.containsKey(orf) ||
311331
pubspec.devDependencies.containsKey(orf) ||
312332
pubspec.dependencyOverrides.containsKey(orf);
313333

0 commit comments

Comments
 (0)