diff --git a/packages/flutter_tools/bin/tool_backend.dart b/packages/flutter_tools/bin/tool_backend.dart index 13ce668b3e..f8b278f35d 100644 --- a/packages/flutter_tools/bin/tool_backend.dart +++ b/packages/flutter_tools/bin/tool_backend.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - // Do not add package imports to this file. import 'dart:convert'; // flutter_ignore: dart_convert_import. import 'dart:io'; // flutter_ignore: dart_io_import. @@ -13,24 +11,33 @@ Future main(List arguments) async { final String targetPlatform = arguments[0]; final String buildMode = arguments[1].toLowerCase(); - final String dartDefines = Platform.environment['DART_DEFINES']; + final String? dartDefines = Platform.environment['DART_DEFINES']; final bool dartObfuscation = Platform.environment['DART_OBFUSCATION'] == 'true'; - final String extraFrontEndOptions = Platform.environment['EXTRA_FRONT_END_OPTIONS']; - final String extraGenSnapshotOptions = Platform.environment['EXTRA_GEN_SNAPSHOT_OPTIONS']; - final String flutterEngine = Platform.environment['FLUTTER_ENGINE']; - final String flutterRoot = Platform.environment['FLUTTER_ROOT']; + final String? extraFrontEndOptions = Platform.environment['EXTRA_FRONT_END_OPTIONS']; + final String? extraGenSnapshotOptions = Platform.environment['EXTRA_GEN_SNAPSHOT_OPTIONS']; + final String? flutterEngine = Platform.environment['FLUTTER_ENGINE']; + final String? flutterRoot = Platform.environment['FLUTTER_ROOT']; final String flutterTarget = Platform.environment['FLUTTER_TARGET'] ?? pathJoin(['lib', 'main.dart']); - final String codeSizeDirectory = Platform.environment['CODE_SIZE_DIRECTORY']; - final String localEngine = Platform.environment['LOCAL_ENGINE']; - final String projectDirectory = Platform.environment['PROJECT_DIR']; - final String splitDebugInfo = Platform.environment['SPLIT_DEBUG_INFO']; - final String bundleSkSLPath = Platform.environment['BUNDLE_SKSL_PATH']; + final String? codeSizeDirectory = Platform.environment['CODE_SIZE_DIRECTORY']; + final String? localEngine = Platform.environment['LOCAL_ENGINE']; + final String? projectDirectory = Platform.environment['PROJECT_DIR']; + final String? splitDebugInfo = Platform.environment['SPLIT_DEBUG_INFO']; + final String? bundleSkSLPath = Platform.environment['BUNDLE_SKSL_PATH']; final bool trackWidgetCreation = Platform.environment['TRACK_WIDGET_CREATION'] == 'true'; final bool treeShakeIcons = Platform.environment['TREE_SHAKE_ICONS'] == 'true'; final bool verbose = Platform.environment['VERBOSE_SCRIPT_LOGGING'] == 'true'; final bool prefixedErrors = Platform.environment['PREFIXED_ERROR_LOGGING'] == 'true'; + if (projectDirectory == null) { + stderr.write('PROJECT_DIR environment variable must be set to the location of Flutter project to be built.'); + exit(1); + } + if (flutterRoot == null || flutterRoot.isEmpty) { + stderr.write('FLUTTER_ROOT environment variable must be set to the location of the Flutter SDK.'); + exit(1); + } + Directory.current = projectDirectory; if (localEngine != null && !localEngine.contains(buildMode)) { diff --git a/packages/flutter_tools/test/integration.shard/tool_backend_test.dart b/packages/flutter_tools/test/integration.shard/tool_backend_test.dart new file mode 100644 index 0000000000..d91e6e5092 --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/tool_backend_test.dart @@ -0,0 +1,60 @@ +// Copyright 2014 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. + +// @dart = 2.8 + +import 'package:flutter_tools/src/base/io.dart'; + +import '../src/common.dart'; +import 'test_utils.dart'; + +final String toolBackend = fileSystem.path.join(getFlutterRoot(), 'packages', 'flutter_tools', 'bin', 'tool_backend.dart'); +final String examplePath = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world'); +final String dart = fileSystem.path.join(getFlutterRoot(), 'bin', platform.isWindows ? 'dart.bat' : 'dart'); + +void main() { + testWithoutContext('tool_backend.dart exits if PROJECT_DIR is not set', () async { + final ProcessResult result = await processManager.run([ + dart, + toolBackend, + 'linux-x64', + 'debug', + ]); + + expect(result.exitCode, 1); + expect(result.stderr, 'PROJECT_DIR environment variable must be set to the location of Flutter project to be built.'); + }); + + testWithoutContext('tool_backend.dart exits if FLUTTER_ROOT is not set', () async { + // Removing parent environment means that batch script cannot be run. + final String dart = fileSystem.path.join(getFlutterRoot(), 'bin', 'cache', 'dart-sdk', 'bin', platform.isWindows ? 'dart.exe' : 'dart'); + + final ProcessResult result = await processManager.run([ + dart, + toolBackend, + 'linux-x64', + 'debug', + ], environment: { + 'PROJECT_DIR': examplePath, + }, includeParentEnvironment: false); // Prevent FLUTTER_ROOT set by test environment from leaking + + expect(result.exitCode, 1); + expect(result.stderr, 'FLUTTER_ROOT environment variable must be set to the location of the Flutter SDK.'); + }); + + testWithoutContext('tool_backend.dart exits if local engine does not match build mode', () async { + final ProcessResult result = await processManager.run([ + dart, + toolBackend, + 'linux-x64', + 'debug', + ], environment: { + 'PROJECT_DIR': examplePath, + 'LOCAL_ENGINE': 'release_foo_bar', // Does not contain "debug", + }); + + expect(result.exitCode, 1); + expect(result.stderr, contains('ERROR: Requested build with Flutter local engine at \'release_foo_bar\'')); + }); +}