Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions tools/engine_tool/lib/src/build_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,9 @@ void debugCheckBuilds(List<Build> builds) {
}

/// Build the build target in the environment.
Future<int> runBuild(
Environment environment,
Build build, {
List<String> extraGnArgs = const <String>[],
}) async {
Future<int> runBuild(Environment environment, Build build,
{List<String> extraGnArgs = const <String>[],
List<String> targets = const <String>[]}) async {
// If RBE config files aren't in the tree, then disable RBE.
final String rbeConfigPath = p.join(
environment.engine.srcDir.path,
Expand All @@ -79,10 +77,11 @@ Future<int> runBuild(
'rbe',
);
final List<String> gnArgs = <String>[
...extraGnArgs,
if (!io.Directory(rbeConfigPath).existsSync()) '--no-rbe',
...extraGnArgs,
];

// TODO(loic-sharma): Fetch dependencies if needed.
final BuildRunner buildRunner = BuildRunner(
platform: environment.platform,
processRunner: environment.processRunner,
Expand All @@ -91,6 +90,7 @@ Future<int> runBuild(
build: build,
extraGnArgs: gnArgs,
runTests: false,
extraNinjaArgs: targets,
);

Spinner? spinner;
Expand Down
18 changes: 2 additions & 16 deletions tools/engine_tool/lib/src/commands/build_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,12 @@ final class BuildCommand extends CommandBase {
}) {
builds = runnableBuilds(environment, configs);
debugCheckBuilds(builds);
argParser.addOption(
configFlag,
abbr: 'c',
defaultsTo: 'host_debug',
help: 'Specify the build config to use',
allowed: <String>[
for (final Build config in runnableBuilds(environment, configs))
config.name,
],
allowedHelp: <String, String>{
for (final Build config in runnableBuilds(environment, configs))
config.name: config.gn.join(' '),
},
);
addConfigOption(argParser, runnableBuilds(environment, configs));
argParser.addFlag(
rbeFlag,
defaultsTo: true,
help: 'RBE is enabled by default when available. Use --no-rbe to '
'disable it.',
'disable it.',
);
}

Expand Down Expand Up @@ -63,7 +50,6 @@ final class BuildCommand extends CommandBase {
if (!useRbe) '--no-rbe',
];

// TODO(loic-sharma): Fetch dependencies if needed.
return runBuild(environment, build, extraGnArgs: extraGnArgs);
}
}
24 changes: 21 additions & 3 deletions tools/engine_tool/lib/src/commands/command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:engine_build_configs/engine_build_configs.dart';

import '../environment.dart';
import 'flags.dart';

/// The base class that all commands and subcommands should inherit from.
abstract base class CommandBase extends Command<int> {
/// Constructs the base command.
CommandBase({
required this.environment
});
CommandBase({required this.environment});

/// The host system environment.
final Environment environment;
}

/// Adds the -c (--config) option to the parser.
void addConfigOption(ArgParser parser, List<Build> builds,
{String defaultsTo = 'host_debug'}) {
parser.addOption(
configFlag,
abbr: 'c',
defaultsTo: defaultsTo,
help: 'Specify the build config to use',
allowed: <String>[
for (final Build config in builds) config.name,
],
allowedHelp: <String, String>{
for (final Build config in builds) config.name: config.gn.join(' '),
},
);
}
2 changes: 2 additions & 0 deletions tools/engine_tool/lib/src/commands/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'format_command.dart';
import 'lint_command.dart';
import 'query_command.dart';
import 'run_command.dart';
import 'test_command.dart';

const int _usageLineLength = 80;

Expand All @@ -31,6 +32,7 @@ final class ToolCommandRunner extends CommandRunner<int> {
BuildCommand(environment: environment, configs: configs),
RunCommand(environment: environment, configs: configs),
LintCommand(environment: environment),
TestCommand(environment: environment, configs: configs),
];
commands.forEach(addCommand);

Expand Down
115 changes: 1 addition & 114 deletions tools/engine_tool/lib/src/commands/lint_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
// found in the LICENSE file.

import 'dart:io' show Directory;
import 'dart:math';

import 'package:path/path.dart' as p;

import '../dart_utils.dart';
import '../environment.dart';
import '../logger.dart';

import '../proc_utils.dart';
import '../worker_pool.dart';
import 'command.dart';
Expand Down Expand Up @@ -113,114 +111,3 @@ final class LintCommand extends CommandBase {
return r ? 0 : 1;
}
}

/// A WorkerPoolProgressReporter designed to work with ProcessTasks.
class ProcessTaskProgressReporter implements WorkerPoolProgressReporter {
/// Construct a new reporter.
ProcessTaskProgressReporter(this._environment);

final Environment _environment;
Spinner? _spinner;
bool _finished = false;
int _longestName = 0;

@override
void onRun(Set<WorkerTask> tasks) {
for (final WorkerTask task in tasks) {
_longestName = max(_longestName, task.name.length);
}
}

@override
void onFinish() {
_finished = true;
_updateSpinner(<ProcessTask>[]);
}

List<ProcessTask> _makeProcessTaskList(WorkerPool pool) {
final List<ProcessTask> runningTasks = <ProcessTask>[];
for (final WorkerTask task in pool.running) {
if (task is! ProcessTask) {
continue;
}
runningTasks.add(task);
}
return runningTasks;
}

@override
void onTaskStart(WorkerPool pool, WorkerTask task) {
final List<ProcessTask> running = _makeProcessTaskList(pool);
_updateSpinner(running);
}

@override
void onTaskDone(WorkerPool pool, WorkerTask task, [Object? err]) {
final List<ProcessTask> running = _makeProcessTaskList(pool);
task as ProcessTask;
final ProcessArtifacts pa = task.processArtifacts;
final String dt = _formatDurationShort(task.runTime);
if (pa.exitCode != 0) {
final String paPath = task.processArtifactsPath;
_environment.logger.clearLine();
_environment.logger.status(
'FAIL: ${task.name.padLeft(_longestName)} after $dt [details in $paPath]');
} else {
_environment.logger.clearLine();
_environment.logger
.status('OKAY: ${task.name.padLeft(_longestName)} after $dt');
}
_updateSpinner(running);
}

void _updateSpinner(List<ProcessTask> tasks) {
if (_spinner != null) {
_spinner!.finish();
_spinner = null;
}
if (_finished) {
return;
}
_environment.logger.clearLine();
String runStatus = '[';
for (final ProcessTask pt in tasks) {
if (runStatus != '[') {
runStatus += ' ';
}
runStatus += pt.name;
}
if (tasks.isNotEmpty) {
runStatus += '...';
}
runStatus += '] ';
_environment.logger.status('Linting $runStatus', newline: false);
_spinner = _environment.logger.startSpinner();
}
}

String _formatDurationShort(Duration dur) {
int micros = dur.inMicroseconds;
String r = '';
if (micros >= Duration.microsecondsPerMinute) {
final int minutes = micros ~/ Duration.microsecondsPerMinute;
micros -= minutes * Duration.microsecondsPerMinute;
r += '${minutes}m';
}
if (micros >= Duration.microsecondsPerSecond) {
final int seconds = micros ~/ Duration.microsecondsPerSecond;
micros -= seconds * Duration.microsecondsPerSecond;
if (r.isNotEmpty) {
r += '.';
}
r += '${seconds}s';
}
if (micros >= Duration.microsecondsPerMillisecond) {
final int millis = micros ~/ Duration.microsecondsPerMillisecond;
micros -= millis * Duration.microsecondsPerMillisecond;
if (r.isNotEmpty) {
r += '.';
}
r += '${millis}ms';
}
return r;
}
56 changes: 54 additions & 2 deletions tools/engine_tool/lib/src/commands/query_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:engine_build_configs/engine_build_configs.dart';

import 'package:path/path.dart' as p;

import '../build_utils.dart';
import '../gn_utils.dart';
import 'command.dart';
import 'flags.dart';

Expand Down Expand Up @@ -42,6 +48,10 @@ final class QueryCommand extends CommandBase {
environment: environment,
configs: configs,
));
addSubcommand(QueryTestsCommand(
environment: environment,
configs: configs,
));
}

/// Build configurations loaded from the engine from under ci/builders.
Expand All @@ -55,9 +65,9 @@ final class QueryCommand extends CommandBase {
'and tests.';
}

/// The 'query builds' command.
/// The 'query builders' command.
final class QueryBuildersCommand extends CommandBase {
/// Constructs the 'query build' command.
/// Constructs the 'query builders' command.
QueryBuildersCommand({
required super.environment,
required this.configs,
Expand Down Expand Up @@ -120,3 +130,45 @@ final class QueryBuildersCommand extends CommandBase {
return 0;
}
}

/// The query tests command.
final class QueryTestsCommand extends CommandBase {
/// Constructs the 'query tests' command.
QueryTestsCommand({
required super.environment,
required this.configs,
}) {
builds = runnableBuilds(environment, configs);
debugCheckBuilds(builds);
addConfigOption(argParser, runnableBuilds(environment, configs));
}

/// Build configurations loaded from the engine from under ci/builders.
final Map<String, BuilderConfig> configs;

/// List of compatible builds.
late final List<Build> builds;

@override
String get name => 'tests';

@override
String get description => 'Provides information about test targets';

@override
Future<int> run() async {
final String configName = argResults![configFlag] as String;
final Build? build =
builds.where((Build build) => build.name == configName).firstOrNull;
if (build == null) {
environment.logger.error('Could not find config $configName');
return 1;
}
final Map<String, TestTarget> targets = await findTestTargets(environment,
Directory(p.join(environment.engine.outDir.path, build.ninja.config)));
for (final TestTarget target in targets.values) {
environment.logger.status(target.label);
}
return 0;
}
}
22 changes: 5 additions & 17 deletions tools/engine_tool/lib/src/commands/run_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,15 @@ final class RunCommand extends CommandBase {
}) {
builds = runnableBuilds(environment, configs);
debugCheckBuilds(builds);

argParser.addOption(
configFlag,
abbr: 'c',
defaultsTo: '',
help:
'Specify the build config to use for the target build (usually auto detected)',
allowed: <String>[
for (final Build build in runnableBuilds(environment, configs))
build.name,
],
allowedHelp: <String, String>{
for (final Build build in runnableBuilds(environment, configs))
build.name: build.gn.join(' '),
},
);
// We default to nothing in order to automatically detect attached devices
// and select an appropriate target from them.
addConfigOption(argParser, runnableBuilds(environment, configs),
defaultsTo: '');
argParser.addFlag(
rbeFlag,
defaultsTo: true,
help: 'RBE is enabled by default when available. Use --no-rbe to '
'disable it.',
'disable it.',
);
}

Expand Down
Loading