Skip to content

Commit 5088bdb

Browse files
authored
add a general dart command (#459)
This enables things like mono_repo dart fix --apply, mono_repo dart analyze, mono_repo dart run build_runner build etc. I did bump the min SDK so I could use a switch expression, let me know if you feel strongly about supporting older SDKs. They can still use older versions so I think it's fine though. Closes #458
1 parent 6a8ec22 commit 5088bdb

File tree

15 files changed

+246
-163
lines changed

15 files changed

+246
-163
lines changed

.github/workflows/dart.yml

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

analysis_options.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ linter:
3333
- camel_case_types
3434
- cancel_subscriptions
3535
- cascade_invocations
36+
- collection_methods_unrelated_type
3637
- comment_references
3738
- constant_identifier_names
3839
- control_flow_in_finally
@@ -45,13 +46,11 @@ linter:
4546
- file_names
4647
- hash_and_equals
4748
- implementation_imports
48-
- iterable_contains_unrelated_type
4949
- join_return_with_assignment
5050
- library_names
5151
- library_prefixes
5252
- library_private_types_in_public_api
5353
- lines_longer_than_80_chars
54-
- list_remove_unrelated_type
5554
- literal_only_boolean_expressions
5655
- missing_whitespace_between_adjacent_strings
5756
- no_duplicate_case_values

mono_repo/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 6.6.0
2+
3+
- Added the `dart` command to run arbitrary dart commands across all packages.
4+
- Require the 3.0.0 Dart SDK.
5+
16
## 6.5.7
27

38
- Updated `mono_repo` to use the existing action versions from the generated

mono_repo/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Or, once you've [setup your PATH]:
2323
> mono_repo
2424
```
2525

26-
Prints the following help message:
26+
Prints the following help message:
2727

2828
```
2929
Manage multiple packages in one source repository.
@@ -39,6 +39,7 @@ Global options:
3939
4040
Available commands:
4141
check Check the state of the repository.
42+
dart Runs the `dart` command with the provided arguments across all packages.
4243
generate Generates the CI configuration for child packages.
4344
list List all packages configured for mono_repo.
4445
presubmit Run the CI presubmits locally.
@@ -83,12 +84,12 @@ github:
8384
# `pull_request` while adding a single `schedule` entry.
8485
# `on` and `cron` cannot both be set.
8586
cron: '0 0 * * 0' # “At 00:00 (UTC) on Sunday.”
86-
87+
8788
# Specify additional environment variables accessible to all jobs
8889
env:
8990
FOO: BAR
9091

91-
# You can group stages into individual workflows
92+
# You can group stages into individual workflows
9293
#
9394
# Any stages that are omitted here are put in a default workflow
9495
# named `dart.yml`.
@@ -156,7 +157,7 @@ To configure a package directory to be included it must contain a
156157
`mono_pkg.yaml` file (along with the normal `pubspec.yaml` file).
157158

158159
You can use an empty `mono_pkg.yaml` file to enable the `check` and `pub`
159-
commands.
160+
commands.
160161

161162
To enable `generate` and `presubmit`, you must populate `mono_pkg.yaml` with
162163
details on how you'd like tests to be run.
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'dart:async';
6+
import 'dart:io';
7+
8+
import 'package:args/args.dart';
9+
import 'package:io/ansi.dart';
10+
import 'package:path/path.dart' as p;
11+
12+
import '../package_config.dart';
13+
import '../root_config.dart';
14+
import 'mono_repo_command.dart';
15+
16+
class DartCommand extends MonoRepoCommand {
17+
@override
18+
final ArgParser argParser = ArgParser.allowAnything();
19+
20+
@override
21+
String get name => 'dart';
22+
23+
@override
24+
String get description =>
25+
'Runs the `dart` command with the provided arguments across all '
26+
'packages.';
27+
28+
@override
29+
Future<void> run() => dart(
30+
rootConfig(),
31+
arguments,
32+
executableForPackage,
33+
);
34+
35+
/// The arguments to pass to the executable.
36+
List<String> get arguments => argResults?.rest ?? const [];
37+
38+
/// The executable to use for a given package.
39+
Executable executableForPackage(PackageConfig config) => Executable.dart;
40+
}
41+
42+
Future<void> dart(
43+
RootConfig rootConfig,
44+
List<String> args,
45+
Executable Function(PackageConfig) executableForPackage,
46+
) async {
47+
final pkgDirs = rootConfig.map((pc) => pc.relativePath).toList();
48+
49+
print(
50+
lightBlue.wrap(
51+
'Running `dart ${args.join(' ')}` across ${pkgDirs.length} '
52+
'package(s).',
53+
),
54+
);
55+
56+
var successCount = 0;
57+
final failSet = <String>{};
58+
59+
for (var config in rootConfig) {
60+
final dir = config.relativePath;
61+
62+
print('');
63+
print(
64+
wrapWith(
65+
'`$dir`: Starting `${args.join(' ')}`',
66+
[styleBold, lightBlue],
67+
),
68+
);
69+
final workingDir = p.join(rootConfig.rootDirectory, dir);
70+
71+
final proc = await Process.start(
72+
executableForPackage(config).path,
73+
args,
74+
mode: ProcessStartMode.inheritStdio,
75+
workingDirectory: workingDir,
76+
);
77+
78+
final exit = await proc.exitCode;
79+
80+
if (exit == 0) {
81+
successCount++;
82+
print(wrapWith('`$dir`: success!', [styleBold, green]));
83+
} else {
84+
failSet.add(dir);
85+
print(wrapWith('`$dir`: failed!', [styleBold, red]));
86+
}
87+
88+
if (rootConfig.length > 1) {
89+
print('');
90+
print('Successes: $successCount');
91+
if (failSet.isNotEmpty) {
92+
print(
93+
'Failures: ${failSet.length}\n'
94+
'${failSet.map((e) => ' $e').join('\n')}',
95+
);
96+
}
97+
final remaining = rootConfig.length - (successCount + failSet.length);
98+
if (remaining > 0) {
99+
print('Remaining: $remaining');
100+
}
101+
}
102+
}
103+
}
104+
105+
/// The path to the root directory of the SDK.
106+
final String _sdkDir = (() {
107+
// The Dart executable is in "/path/to/sdk/bin/dart", so two levels up is
108+
// "/path/to/sdk".
109+
final aboveExecutable = p.dirname(p.dirname(Platform.resolvedExecutable));
110+
assert(FileSystemEntity.isFileSync(p.join(aboveExecutable, 'version')));
111+
return aboveExecutable;
112+
})();
113+
114+
final String _dartPath = p.join(_sdkDir, 'bin', 'dart');
115+
116+
/// The "flutter[.bat]" command.
117+
final String _flutterPath = Platform.isWindows ? 'flutter.bat' : 'flutter';
118+
119+
enum Executable {
120+
dart,
121+
flutter,
122+
}
123+
124+
extension ExecutablePath on Executable {
125+
String get path => switch (this) {
126+
Executable.dart => _dartPath,
127+
Executable.flutter => _flutterPath,
128+
};
129+
}

0 commit comments

Comments
 (0)