mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[flutter_tools] Reland: fix multiple dart defines (#54973)
This commit is contained in:
parent
fd397e1fc0
commit
e092dcfa22
@ -590,6 +590,18 @@ Future<void> _runWebIntegrationTests() async {
|
||||
await _runWebDebugTest('lib/stack_trace.dart');
|
||||
await _runWebDebugTest('lib/web_directory_loading.dart');
|
||||
await _runWebDebugTest('test/test.dart');
|
||||
await _runWebDebugTest('lib/web_define_loading.dart',
|
||||
additionalArguments: <String>[
|
||||
'--dart-define=test.valueA=Example',
|
||||
'--dart-define=test.valueB=Value',
|
||||
]
|
||||
);
|
||||
await _runWebReleaseTest('lib/web_define_loading.dart',
|
||||
additionalArguments: <String>[
|
||||
'--dart-define=test.valueA=Example',
|
||||
'--dart-define=test.valueB=Value',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _runWebStackTraceTest(String buildMode) async {
|
||||
@ -632,10 +644,56 @@ Future<void> _runWebStackTraceTest(String buildMode) async {
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a web integration test in release mode.
|
||||
Future<void> _runWebReleaseTest(String target, {
|
||||
List<String> additionalArguments = const<String>[],
|
||||
}) async {
|
||||
final String testAppDirectory = path.join(flutterRoot, 'dev', 'integration_tests', 'web');
|
||||
final String appBuildDirectory = path.join(testAppDirectory, 'build', 'web');
|
||||
|
||||
// Build the app.
|
||||
await runCommand(
|
||||
flutter,
|
||||
<String>[ 'clean' ],
|
||||
workingDirectory: testAppDirectory,
|
||||
);
|
||||
await runCommand(
|
||||
flutter,
|
||||
<String>[
|
||||
'build',
|
||||
'web',
|
||||
'--release',
|
||||
...additionalArguments,
|
||||
'-t',
|
||||
target,
|
||||
],
|
||||
workingDirectory: testAppDirectory,
|
||||
environment: <String, String>{
|
||||
'FLUTTER_WEB': 'true',
|
||||
},
|
||||
);
|
||||
|
||||
// Run the app.
|
||||
final String result = await evalTestAppInChrome(
|
||||
appUrl: 'http://localhost:8080/index.html',
|
||||
appDirectory: appBuildDirectory,
|
||||
);
|
||||
|
||||
if (result.contains('--- TEST SUCCEEDED ---')) {
|
||||
print('${green}Web release mode test passed.$reset');
|
||||
} else {
|
||||
print(result);
|
||||
print('${red}Web release mode test failed.$reset');
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Debug mode is special because `flutter build web` doesn't build in debug mode.
|
||||
///
|
||||
/// Instead, we use `flutter run --debug` and sniff out the standard output.
|
||||
Future<void> _runWebDebugTest(String target) async {
|
||||
Future<void> _runWebDebugTest(String target, {
|
||||
List<String> additionalArguments = const<String>[],
|
||||
}) async {
|
||||
final String testAppDirectory = path.join(flutterRoot, 'dev', 'integration_tests', 'web');
|
||||
final CapturedOutput output = CapturedOutput();
|
||||
bool success = false;
|
||||
@ -647,6 +705,7 @@ Future<void> _runWebDebugTest(String target) async {
|
||||
'-d',
|
||||
'chrome',
|
||||
'--web-run-headless',
|
||||
...additionalArguments,
|
||||
'-t',
|
||||
target,
|
||||
],
|
||||
|
@ -21,7 +21,8 @@ Future<TaskResult> runDartDefinesTask() async {
|
||||
'--verbose',
|
||||
'-d',
|
||||
deviceId,
|
||||
'--dart-define=test.value=ExampleValue',
|
||||
'--dart-define=test.valueA=Example',
|
||||
'--dart-define=test.valueB=Value',
|
||||
'lib/defines.dart',
|
||||
]);
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ void main() {
|
||||
runApp(
|
||||
const Center(
|
||||
child: Text(
|
||||
String.fromEnvironment('test.value'),
|
||||
String.fromEnvironment('test.valueA') + String.fromEnvironment('test.valueB'),
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
),
|
||||
|
@ -16,7 +16,7 @@ void main() {
|
||||
await driver.close();
|
||||
});
|
||||
|
||||
test('Can run with --dart-deinfe', () async {
|
||||
test('Can run with --dart-define', () async {
|
||||
await driver.waitFor(find.text('ExampleValue'));
|
||||
});
|
||||
}
|
||||
|
24
dev/integration_tests/web/lib/web_define_loading.dart
Normal file
24
dev/integration_tests/web/lib/web_define_loading.dart
Normal file
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
import 'dart:html' as html;
|
||||
|
||||
Future<void> main() async {
|
||||
final StringBuffer output = StringBuffer();
|
||||
const String combined = String.fromEnvironment('test.valueA') +
|
||||
String.fromEnvironment('test.valueB');
|
||||
if (combined == 'ExampleValue') {
|
||||
output.write('--- TEST SUCCEEDED ---');
|
||||
print('--- TEST SUCCEEDED ---');
|
||||
} else {
|
||||
output.write('--- TEST FAILED ---');
|
||||
print('--- TEST FAILED ---');
|
||||
}
|
||||
|
||||
html.HttpRequest.request(
|
||||
'/test-result',
|
||||
method: 'POST',
|
||||
sendData: '$output',
|
||||
);
|
||||
}
|
@ -83,7 +83,7 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" \
|
||||
-dTreeShakeIcons="${icon_tree_shaker_flag}" \
|
||||
-dDartObfuscation="${dart_obfuscation_flag}" \
|
||||
-dSplitDebugInfo="${SPLIT_DEBUG_INFO}" \
|
||||
-dDartDefines="${DART_DEFINES}" \
|
||||
--DartDefines="${DART_DEFINES}" \
|
||||
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
|
||||
--build-inputs="${build_inputs_path}" \
|
||||
--build-outputs="${build_outputs_path}" \
|
||||
|
@ -186,7 +186,7 @@ BuildApp() {
|
||||
-dTrackWidgetCreation="${track_widget_creation_flag}" \
|
||||
-dDartObfuscation="${dart_obfuscation_flag}" \
|
||||
-dEnableBitcode="${bitcode_flag}" \
|
||||
-dDartDefines="${DART_DEFINES}" \
|
||||
--DartDefines="${DART_DEFINES}" \
|
||||
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
|
||||
"${build_mode}_ios_bundle_flutter_assets"
|
||||
|
||||
|
@ -916,7 +916,7 @@ abstract class BaseFlutterTask extends DefaultTask {
|
||||
args "-dDartObfuscation=true"
|
||||
}
|
||||
if (dartDefines != null) {
|
||||
args "-dDartDefines=${dartDefines}"
|
||||
args "--DartDefines=${dartDefines}"
|
||||
}
|
||||
if (extraGenSnapshotOptions != null) {
|
||||
args "--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}"
|
||||
|
@ -19,7 +19,6 @@ import '../base/terminal.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../build_info.dart';
|
||||
import '../cache.dart';
|
||||
import '../convert.dart';
|
||||
import '../flutter_manifest.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../project.dart';
|
||||
@ -331,7 +330,7 @@ Future<void> buildGradleApp({
|
||||
command.add('-Pshrink=true');
|
||||
}
|
||||
if (androidBuildInfo.buildInfo.dartDefines?.isNotEmpty ?? false) {
|
||||
command.add('-Pdart-defines=${jsonEncode(androidBuildInfo.buildInfo.dartDefines)}');
|
||||
command.add('-Pdart-defines=${androidBuildInfo.buildInfo.dartDefines.join(',')}');
|
||||
}
|
||||
if (shouldBuildPluginAsAar) {
|
||||
// Pass a system flag instead of a project flag, so this flag can be
|
||||
|
@ -14,7 +14,6 @@ import 'build_system/targets/dart.dart';
|
||||
import 'build_system/targets/icon_tree_shaker.dart';
|
||||
import 'build_system/targets/ios.dart';
|
||||
import 'cache.dart';
|
||||
import 'convert.dart';
|
||||
import 'globals.dart' as globals;
|
||||
import 'ios/bitcode.dart';
|
||||
import 'project.dart';
|
||||
@ -87,7 +86,7 @@ class AotBuilder {
|
||||
kBuildMode: getNameForBuildMode(buildInfo.mode),
|
||||
kTargetPlatform: getNameForTargetPlatform(platform),
|
||||
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
|
||||
kDartDefines: jsonEncode(buildInfo.dartDefines),
|
||||
kDartDefines: buildInfo.dartDefines.join(','),
|
||||
kBitcodeFlag: bitcode.toString(),
|
||||
if (buildInfo?.extraGenSnapshotOptions?.isNotEmpty ?? false)
|
||||
kExtraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions.join(','),
|
||||
|
@ -7,7 +7,6 @@ import '../../base/build.dart';
|
||||
import '../../base/file_system.dart';
|
||||
import '../../build_info.dart';
|
||||
import '../../compile.dart';
|
||||
import '../../convert.dart';
|
||||
import '../../globals.dart' as globals;
|
||||
import '../../project.dart';
|
||||
import '../build_system.dart';
|
||||
@ -390,21 +389,10 @@ abstract class CopyFlutterAotBundle extends Target {
|
||||
}
|
||||
}
|
||||
|
||||
/// Dart defines are encoded inside [Environment] as a JSON array.
|
||||
/// Dart defines are encoded inside [Environment] as a comma-separated list.
|
||||
List<String> parseDartDefines(Environment environment) {
|
||||
if (!environment.defines.containsKey(kDartDefines) || environment.defines[kDartDefines].isEmpty) {
|
||||
return const <String>[];
|
||||
}
|
||||
|
||||
final String dartDefinesJson = environment.defines[kDartDefines];
|
||||
try {
|
||||
final List<Object> parsedDefines = jsonDecode(dartDefinesJson) as List<Object>;
|
||||
return parsedDefines.cast<String>();
|
||||
} on FormatException {
|
||||
throw Exception(
|
||||
'The value of -D$kDartDefines is not formatted correctly.\n'
|
||||
'The value must be a JSON-encoded list of strings but was:\n'
|
||||
'$dartDefinesJson'
|
||||
);
|
||||
}
|
||||
return environment.defines[kDartDefines].split(',');
|
||||
}
|
||||
|
@ -168,6 +168,8 @@ class Dart2JSTarget extends Target {
|
||||
'--libraries-spec=$specPath',
|
||||
'-o',
|
||||
outputKernel.path,
|
||||
for (final String dartDefine in dartDefines)
|
||||
'-D$dartDefine',
|
||||
'--packages=$packageFile',
|
||||
'--cfe-only',
|
||||
environment.buildDir.childFile('main.dart').path,
|
||||
|
@ -17,7 +17,6 @@ import 'build_system/depfile.dart';
|
||||
import 'build_system/targets/dart.dart';
|
||||
import 'build_system/targets/icon_tree_shaker.dart';
|
||||
import 'cache.dart';
|
||||
import 'convert.dart';
|
||||
import 'dart/package_map.dart';
|
||||
import 'devfs.dart';
|
||||
import 'globals.dart' as globals;
|
||||
@ -130,7 +129,7 @@ Future<void> buildWithAssemble({
|
||||
kTrackWidgetCreation: trackWidgetCreation?.toString(),
|
||||
kIconTreeShakerFlag: treeShakeIcons ? 'true' : null,
|
||||
if (dartDefines != null && dartDefines.isNotEmpty)
|
||||
kDartDefines: jsonEncode(dartDefines),
|
||||
kDartDefines: dartDefines.join(','),
|
||||
},
|
||||
artifacts: globals.artifacts,
|
||||
fileSystem: globals.fs,
|
||||
|
@ -87,6 +87,7 @@ class AssembleCommand extends FlutterCommand {
|
||||
'root of the current Flutter project.',
|
||||
);
|
||||
argParser.addOption(kExtraGenSnapshotOptions);
|
||||
argParser.addOption(kDartDefines);
|
||||
argParser.addOption(
|
||||
'resource-pool-size',
|
||||
help: 'The maximum number of concurrent tasks the build system will run.',
|
||||
@ -182,6 +183,10 @@ class AssembleCommand extends FlutterCommand {
|
||||
if (argResults.wasParsed(kExtraGenSnapshotOptions)) {
|
||||
results[kExtraGenSnapshotOptions] = argResults[kExtraGenSnapshotOptions] as String;
|
||||
}
|
||||
// Workaround for dart-define formatting
|
||||
if (argResults.wasParsed(kDartDefines)) {
|
||||
results[kDartDefines] = argResults[kDartDefines] as String;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ import '../base/terminal.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../build_info.dart';
|
||||
import '../cache.dart';
|
||||
import '../convert.dart';
|
||||
import '../flutter_manifest.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../project.dart';
|
||||
@ -236,7 +235,7 @@ List<String> _xcodeBuildSettingsLines({
|
||||
}
|
||||
|
||||
if (buildInfo.dartDefines?.isNotEmpty ?? false) {
|
||||
xcodeBuildSettings.add('DART_DEFINES=${jsonEncode(buildInfo.dartDefines)}');
|
||||
xcodeBuildSettings.add('DART_DEFINES=${buildInfo.dartDefines.join(',')}');
|
||||
}
|
||||
|
||||
if (buildInfo.extraFrontEndOptions?.isNotEmpty ?? false) {
|
||||
|
@ -13,7 +13,6 @@ import '../build_system/build_system.dart';
|
||||
import '../build_system/targets/dart.dart';
|
||||
import '../build_system/targets/icon_tree_shaker.dart';
|
||||
import '../build_system/targets/web.dart';
|
||||
import '../convert.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../platform_plugins.dart';
|
||||
import '../plugins.dart';
|
||||
@ -49,7 +48,7 @@ Future<void> buildWeb(
|
||||
kTargetFile: target,
|
||||
kInitializePlatform: initializePlatform.toString(),
|
||||
kHasWebPlugins: hasWebPlugins.toString(),
|
||||
kDartDefines: jsonEncode(buildInfo.dartDefines),
|
||||
kDartDefines: buildInfo.dartDefines.join(','),
|
||||
kCspMode: csp.toString(),
|
||||
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
|
||||
},
|
||||
|
@ -360,12 +360,14 @@ void main() {
|
||||
|
||||
test('Dart2JSTarget calls dart2js with Dart defines in release mode', () => testbed.run(() async {
|
||||
environment.defines[kBuildMode] = 'release';
|
||||
environment.defines[kDartDefines] = '["FOO=bar","BAZ=qux"]';
|
||||
environment.defines[kDartDefines] = 'FOO=bar,BAZ=qux';
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
...kDart2jsLinuxArgs,
|
||||
'-o',
|
||||
environment.buildDir.childFile('app.dill').absolute.path,
|
||||
'-DFOO=bar',
|
||||
'-DBAZ=qux',
|
||||
'--packages=${globals.fs.path.join('foo', '.packages')}',
|
||||
'--cfe-only',
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
@ -391,12 +393,14 @@ void main() {
|
||||
|
||||
test('Dart2JSTarget calls dart2js with Dart defines in profile mode', () => testbed.run(() async {
|
||||
environment.defines[kBuildMode] = 'profile';
|
||||
environment.defines[kDartDefines] = '["FOO=bar","BAZ=qux"]';
|
||||
environment.defines[kDartDefines] = 'FOO=bar,BAZ=qux';
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
...kDart2jsLinuxArgs,
|
||||
'-o',
|
||||
environment.buildDir.childFile('app.dill').absolute.path,
|
||||
'-DFOO=bar',
|
||||
'-DBAZ=qux',
|
||||
'--packages=${globals.fs.path.join('foo', '.packages')}',
|
||||
'--cfe-only',
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
@ -421,27 +425,6 @@ void main() {
|
||||
ProcessManager: () => processManager,
|
||||
}));
|
||||
|
||||
test('Dart2JSTarget throws developer-friendly exception on misformatted DartDefines', () => testbed.run(() async {
|
||||
environment.defines[kBuildMode] = 'profile';
|
||||
environment.defines[kDartDefines] = '[misformatted json';
|
||||
try {
|
||||
await const Dart2JSTarget().build(environment);
|
||||
fail('Call to build() must not have succeeded.');
|
||||
} on Exception catch(exception) {
|
||||
expect(
|
||||
'$exception',
|
||||
'Exception: The value of -D$kDartDefines is not formatted correctly.\n'
|
||||
'The value must be a JSON-encoded list of strings but was:\n'
|
||||
'[misformatted json',
|
||||
);
|
||||
}
|
||||
|
||||
// Should not attempt to run any processes.
|
||||
verifyNever(globals.processManager.run(any));
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => MockProcessManager(),
|
||||
}));
|
||||
|
||||
test('Generated service worker correctly inlines file hashes', () {
|
||||
final String result = generateServiceWorker(<String, String>{'/foo': 'abcd'});
|
||||
|
||||
|
@ -109,7 +109,8 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('build aot outputs timing info', () async {
|
||||
globals.fs.file('.dart_tool/flutter_build/cce09742720db17ffec62331bd7e42d5/app.so')
|
||||
globals.fs
|
||||
.file('.dart_tool/flutter_build/0c21fd4ab3b8bde8b385ff01d08e0093/app.so')
|
||||
.createSync(recursive: true);
|
||||
when(globals.buildSystem.build(any, any))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
|
Loading…
Reference in New Issue
Block a user