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
14 changes: 14 additions & 0 deletions tools/engine_tool/lib/src/commands/build_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ et build //flutter/fml:fml_benchmarks # Build a specific target in `//flutter/f
allTargets.addAll(targets.map((target) => target.label));
}

// Warn that we've discarded some targets.
// Other warnings should have been emitted above, so if this ends up being
// unneccesarily noisy, we can remove it or limit it to verbose mode.
if (allTargets.length < commandLineTargets.length) {
// Report which targets were not found.
final notFound = commandLineTargets.where(
(target) => !allTargets.contains(Label.parse(target)),
);
environment.logger.warning(
'One or more targets specified did not match any build targets:\n\n'
'${notFound.join('\n')}',
);
}

return runBuild(
environment,
plan.build,
Expand Down
46 changes: 46 additions & 0 deletions tools/engine_tool/lib/src/gn.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:collection/collection.dart';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file needs a copyright header.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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

Expand Down Expand Up @@ -106,6 +111,9 @@ interface class Gn {
JsonObject(properties),
);
if (target == null) {
_environment.logger.warning(
'Unknown target type for $label: type=${properties['type']}',
);
return null;
}
return target;
Expand Down Expand Up @@ -180,6 +188,11 @@ sealed class BuildTarget {
testOnly: testOnly,
json: json,
),
'group' => GroupBuildTarget(
label: Label.parseGn(label),
testOnly: testOnly,
deps: json.stringList('deps').map(Label.parseGn).toList(),
),
_ => null,
};
}
Expand Down Expand Up @@ -281,3 +294,36 @@ final class ExecutableBuildTarget extends BuildTarget {
String toString() =>
'ExecutableBuildTarget($label, testOnly=$testOnly, executable=$executable)';
}

/// A build target that [group]s a meta-target of other build targets.
///
/// [group]: https://gn.googlesource.com/gn/+/main/docs/reference.md#func_group
final class GroupBuildTarget extends BuildTarget {
/// Construct a group build target.
const GroupBuildTarget({
required super.label,
required super.testOnly,
required this.deps,
});

/// The list of dependencies for this group target.
final List<Label> deps;

@override
bool operator ==(Object other) {
if (other is! GroupBuildTarget) {
return false;
}
if (label != other.label || testOnly != other.testOnly) {
return false;
}
return const ListEquality<Object>().equals(deps, other.deps);
}

@override
int get hashCode => Object.hash(label, testOnly, Object.hashAll(deps));

@override
String toString() =>
'GroupBuildTarget($label, testOnly=$testOnly, deps=$deps)';
}
72 changes: 72 additions & 0 deletions tools/engine_tool/test/commands/build_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:engine_tool/src/logger.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import '../src/matchers.dart';
import '../src/test_build_configs.dart';
import '../src/utils.dart';

Expand Down Expand Up @@ -659,6 +660,77 @@ The input testing/scenario_app:sceario_app matches no targets, configs or files.
);
});

test('build command warns on an unrecognized action', () async {
final testEnv = TestEnvironment.withTestEngine(
abi: Abi.macosArm64,
cannedProcesses: [
CannedProcess(
(command) => command.contains('desc'),
stdout: convert.jsonEncode({
'//flutter/tools/unrecognized:action': {
'outputs': [
'//out/host_debug/unrecognized_action',
],
'testonly': true,
'type': 'unrecognized',
},
}),
),
],
);
addTearDown(testEnv.cleanup);

final builder = TestBuilderConfig();
builder.addBuild(
name: 'ci/host_debug',
targetDir: 'host_debug',
dimension: TestDroneDimension.mac,
);
final runner = ToolCommandRunner(
environment: testEnv.environment,
configs: {
'mac_test_config': builder.buildConfig(
path: 'ci/builders/mac_test_config.json',
),
},
);

final result = await runner.run([
'build',
'--config',
'ci/host_debug',
'//flutter/tools/unrecognized:action',
]);

printOnFailure(testEnv.testLogs.map((r) => r.message).join('\n'));
expect(result, equals(0));

expect(
testEnv.testLogs,
contains(
logRecord(
stringContainsInOrder([
'Unknown target type',
'//flutter/tools/unrecognized:action',
'type=unrecognized',
]),
level: Logger.warningLevel,
),
),
);

expect(
testEnv.testLogs,
contains(logRecord(
stringContainsInOrder([
'One or more targets specified did not match',
'//flutter/tools/unrecognized:action',
]),
level: Logger.warningLevel,
)),
);
});

test('et help build line length is not too big', () async {
final testEnv = TestEnvironment.withTestEngine(
verbose: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import 'package:process_fakes/process_fakes.dart';
import 'package:process_runner/process_runner.dart';
import 'package:test/test.dart';

import 'src/test_build_configs.dart';
import '../src/test_build_configs.dart';

void main() {
late io.Directory tempRoot;
Expand Down
34 changes: 34 additions & 0 deletions tools/engine_tool/test/external_tools/gn_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ void main() {
);
});

test('parses a group', () async {
final testEnv = TestEnvironment.withTestEngine(
cannedProcesses: [
CannedProcess(
(List<String> command) => command.contains('desc'),
stdout: '''
{
"//foo/bar:baz_group": {
"deps": ["//foo/bar:baz_shared_library"],
"testonly": true,
"type": "group"
}
}
''',
),
],
);
addTearDown(testEnv.cleanup);

final gn = Gn.fromEnvironment(testEnv.environment);
final targets = await gn.desc('out/Release', TargetPattern('//foo', 'bar'));
expect(targets, hasLength(1));

final groupTarget = targets.single;
expect(
groupTarget,
GroupBuildTarget(
label: Label('//foo/bar', 'baz_group'),
testOnly: true,
deps: [Label('//foo/bar', 'baz_shared_library')],
),
);
});

test('parses a dart_test action as an executable', () async {
final testEnv = TestEnvironment.withTestEngine(
cannedProcesses: [
Expand Down