• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / mono_repo.dart / 18480472902

13 Oct 2025 11:08PM UTC coverage: 84.383%. First build
18480472902

Pull #514

github

web-flow
Merge c2297d867 into b825610c9
Pull Request #514: Require Dart 3.8, bump deps, regenerate code, update actions

209 of 250 new or added lines in 28 files covered. (83.6%)

1259 of 1492 relevant lines covered (84.38%)

3.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.94
/mono_repo/lib/src/commands/presubmit.dart
1
// Copyright (c) 2017, 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:io/ansi.dart';
9
import 'package:path/path.dart' as p;
10
import 'package:pub_semver/pub_semver.dart';
11

12
import '../ci_shared.dart';
13
import '../package_config.dart';
14
import '../root_config.dart';
15
import '../user_exception.dart';
16
import 'ci_script/generate.dart';
17
import 'mono_repo_command.dart';
18

19
class PresubmitCommand extends MonoRepoCommand {
20
  @override
×
21
  String get name => 'presubmit';
22

23
  @override
×
24
  String get description => 'Run the CI presubmits locally.';
25

26
  PresubmitCommand() {
×
27
    argParser
×
28
      ..addMultiOption(
×
29
        'package',
30
        help: 'The package(s) to run on, defaults to all packages',
31
        abbr: 'p',
32
      )
33
      ..addMultiOption(
×
34
        'task',
35
        help: 'The task(s) to run, defaults to all tasks',
36
        abbr: 't',
37
      )
38
      ..addOption(
×
39
        'sdk',
40
        help: 'Which sdk to use for match tasks, defaults to current sdk',
41
        defaultsTo: _currentSdk,
×
42
      );
43
  }
44

45
  @override
×
46
  Future<void> run() async {
47
    final passed = await presubmit(
×
48
      rootConfig(),
×
49
      packages: argResults!['package'] as List<String>,
×
50
      tasks: argResults!['task'] as List<String>,
×
51
      sdkToRun: argResults!['sdk'] as String,
×
52
    );
53

54
    // Set a bad exit code if it failed.
55
    if (!passed) exitCode = 1;
×
56
  }
57
}
58

59
/// TODO: This doesn't actually match what Travis does, just because
60
/// you are on a dev release sdk doesn't mean you are on the latest
61
/// dev release sdk, but its generally a decent approximation.
62
///
63
/// This also won't match any exact versions listed in your travis config.
64
final _currentSdk =
2✔
65
    Version.parse(Platform.version.split(' ').first).isPreRelease
5✔
66
    ? 'dev'
67
    : 'stable';
68

69
Future<bool> presubmit(
1✔
70
  RootConfig rootConfig, {
71
  Iterable<String>? packages,
72
  Iterable<String>? tasks,
73
  String? sdkToRun,
74
}) async {
75
  packages ??= <String>[];
1✔
76
  tasks ??= <String>[];
1✔
77
  sdkToRun ??= _currentSdk;
1✔
78
  Directory? tmpDir;
79

80
  if (!File(ciScriptPath).existsSync()) {
2✔
81
    throw UserException(
1✔
82
      'No $ciScriptPath file found, please run the `generate` command '
83
      'first.',
84
    );
85
  }
86

87
  final commandsToKeys = extractCommands(rootConfig);
×
88
  // By default, run on all packages.
89
  if (packages.isEmpty) {
×
90
    packages = rootConfig.map((pc) => pc.relativePath).toList();
×
91
  }
92
  packages = packages.toList()..sort();
×
93

94
  // By default run all tasks.
95
  final allKnownTasks = rootConfig.fold(
×
96
    <String>{},
97
    (Set<String> existing, PackageConfig config) => existing
×
98
      ..addAll(
×
99
        config.jobs.expand((job) => job.tasks.map((task) => task.type.name)),
×
100
      ),
101
  );
102
  if (tasks.isEmpty) tasks = allKnownTasks;
×
NEW
103
  final unrecognizedTasks = tasks.where(
×
NEW
104
    (task) => !allKnownTasks.contains(task),
×
105
  );
106
  if (unrecognizedTasks.isNotEmpty) {
×
107
    throw UserException(
×
NEW
108
      'Found ${unrecognizedTasks.length} unrecognized tasks:\n'
×
NEW
109
      '${unrecognizedTasks.map((task) => '  $task').join('\n')}\n\n'
×
110
      'Known tasks are:\n'
NEW
111
      '${allKnownTasks.map((task) => '  $task').join('\n')}',
×
112
    );
113
  }
114

115
  // Status of the presubmit.
116
  var passed = true;
117
  for (var package in packages) {
×
118
    final config = rootConfig.singleWhere(
×
119
      (pkg) => pkg.relativePath == package,
×
120
      orElse: () {
×
121
        throw UserException(
×
122
          'Unrecognized package `$package`, known packages are:\n'
NEW
123
          '${rootConfig.map((pkg) => '  ${pkg.relativePath}').join('\n')}',
×
124
        );
125
      },
126
    );
127

128
    print(styleBold.wrap(package));
×
129
    for (var job in config.jobs) {
×
130
      final sdk = job.sdk;
×
131
      for (var task in job.tasks) {
×
132
        final taskKey = commandsToKeys[task.command]!;
×
133
        // Skip tasks that weren't specified
134
        if (!tasks.contains(task.type.name)) continue;
×
135

NEW
136
        print(
×
NEW
137
          '  SDK: ${styleBold.wrap(white.wrap(job.sdk))} '
×
NEW
138
          'TASK: ${styleBold.wrap(white.wrap(task.command))}',
×
139
        );
140
        if (sdk != sdkToRun) {
×
141
          print(yellow.wrap('    skipped, mismatched sdk'));
×
142
          continue;
143
        }
144

145
        final result = await Process.run(
×
146
          ciScriptPath,
147
          [taskKey],
×
148
          environment: {'PKGS': package},
×
149
        );
150
        if (result.exitCode == 0) {
×
151
          print(green.wrap('    success'));
×
152
        } else {
153
          tmpDir ??= Directory.systemTemp.createTempSync('mono_repo_');
×
NEW
154
          final file = File(
×
NEW
155
            p.join(tmpDir.path, '${package}_${taskKey}_${job.sdk}.txt'),
×
156
          );
157
          await file.create(recursive: true);
×
158
          await file.writeAsString(result.stdout as String);
×
159
          print(red.wrap('    failure, ${file.path}'));
×
160
          passed = false;
161
        }
162
      }
163
    }
164
  }
165
  return passed;
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc