[flutter_tools] fix cast error when dart-defines-json file includes null (#128909)
Fixes https://github.com/flutter/flutter/issues/128787
This commit is contained in:
parent
dc4541fa05
commit
3f68b25b46
@ -38,7 +38,7 @@ class BuildInfo {
|
||||
this.webRenderer = WebRendererMode.auto,
|
||||
required this.treeShakeIcons,
|
||||
this.performanceMeasurementFile,
|
||||
this.dartDefineConfigJsonMap,
|
||||
this.dartDefineConfigJsonMap = const <String, Object?>{},
|
||||
this.packagesPath = '.dart_tool/package_config.json', // TODO(zanderso): make this required and remove the default.
|
||||
this.nullSafetyMode = NullSafetyMode.sound,
|
||||
this.codeSizeDirectory,
|
||||
@ -144,7 +144,7 @@ class BuildInfo {
|
||||
///
|
||||
/// An additional field `dartDefineConfigJsonMap` is provided to represent the native JSON value of the configuration file
|
||||
///
|
||||
final Map<String, Object>? dartDefineConfigJsonMap;
|
||||
final Map<String, Object?> dartDefineConfigJsonMap;
|
||||
|
||||
/// If provided, an output directory where one or more v8-style heap snapshots
|
||||
/// will be written for code size profiling.
|
||||
@ -267,7 +267,7 @@ class BuildInfo {
|
||||
/// Fields that are `null` are excluded from this configuration.
|
||||
Map<String, String> toEnvironmentConfig() {
|
||||
final Map<String, String> map = <String, String>{};
|
||||
dartDefineConfigJsonMap?.forEach((String key, Object value) {
|
||||
dartDefineConfigJsonMap.forEach((String key, Object? value) {
|
||||
map[key] = '$value';
|
||||
});
|
||||
final Map<String, String> environmentMap = <String, String>{
|
||||
@ -327,17 +327,15 @@ class BuildInfo {
|
||||
for (final String projectArg in androidProjectArgs)
|
||||
'-P$projectArg',
|
||||
];
|
||||
if (dartDefineConfigJsonMap != null) {
|
||||
final Iterable<String> gradleConfKeys = result.map((final String gradleConf) => gradleConf.split('=')[0].substring(2));
|
||||
dartDefineConfigJsonMap!.forEach((String key, Object value) {
|
||||
if (gradleConfKeys.contains(key)) {
|
||||
globals.printWarning(
|
||||
'The key: [$key] already exists, you cannot use gradle variables that have been used by the system!');
|
||||
} else {
|
||||
result.add('-P$key=$value');
|
||||
}
|
||||
});
|
||||
}
|
||||
final Iterable<String> gradleConfKeys = result.map((final String gradleConf) => gradleConf.split('=')[0].substring(2));
|
||||
dartDefineConfigJsonMap.forEach((String key, Object? value) {
|
||||
if (gradleConfKeys.contains(key)) {
|
||||
globals.printWarning(
|
||||
'The key: [$key] already exists, you cannot use gradle variables that have been used by the system!');
|
||||
} else {
|
||||
result.add('-P$key=$value');
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import 'devfs.dart';
|
||||
import 'globals.dart' as globals;
|
||||
import 'project.dart';
|
||||
|
||||
|
||||
/// Provides a `build` method that builds the bundle.
|
||||
class BundleBuilder {
|
||||
/// Builds the bundle for the given target platform.
|
||||
|
@ -258,7 +258,7 @@ class AssembleCommand extends FlutterCommand {
|
||||
results[kExtraGenSnapshotOptions] = (argumentResults[FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(',');
|
||||
}
|
||||
|
||||
final Map<String, Object>? defineConfigJsonMap = extractDartDefineConfigJsonMap();
|
||||
final Map<String, Object?> defineConfigJsonMap = extractDartDefineConfigJsonMap();
|
||||
final List<String> dartDefines = extractDartDefines(defineConfigJsonMap: defineConfigJsonMap);
|
||||
if (dartDefines.isNotEmpty){
|
||||
results[kDartDefines] = dartDefines.join(',');
|
||||
|
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
@ -1190,7 +1190,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
? stringArg(FlutterOptions.kPerformanceMeasurementFile)
|
||||
: null;
|
||||
|
||||
final Map<String, Object>? defineConfigJsonMap = extractDartDefineConfigJsonMap();
|
||||
final Map<String, Object?> defineConfigJsonMap = extractDartDefineConfigJsonMap();
|
||||
List<String> dartDefines = extractDartDefines(defineConfigJsonMap: defineConfigJsonMap);
|
||||
|
||||
WebRendererMode webRenderer = WebRendererMode.auto;
|
||||
@ -1323,29 +1323,26 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
}
|
||||
|
||||
List<String> extractDartDefines({Map<String, Object>? defineConfigJsonMap}) {
|
||||
List<String> extractDartDefines({required Map<String, Object?> defineConfigJsonMap}) {
|
||||
final List<String> dartDefines = <String>[];
|
||||
|
||||
if (argParser.options.containsKey(FlutterOptions.kDartDefinesOption)) {
|
||||
dartDefines.addAll(stringsArg(FlutterOptions.kDartDefinesOption));
|
||||
}
|
||||
|
||||
if (defineConfigJsonMap == null) {
|
||||
return dartDefines;
|
||||
}
|
||||
defineConfigJsonMap.forEach((String key, Object value) {
|
||||
defineConfigJsonMap.forEach((String key, Object? value) {
|
||||
dartDefines.add('$key=$value');
|
||||
});
|
||||
|
||||
return dartDefines;
|
||||
}
|
||||
|
||||
Map<String, Object>? extractDartDefineConfigJsonMap() {
|
||||
final Map<String, Object> dartDefineConfigJsonMap = <String, Object>{};
|
||||
Map<String, Object?> extractDartDefineConfigJsonMap() {
|
||||
final Map<String, Object?> dartDefineConfigJsonMap = <String, Object?>{};
|
||||
|
||||
if (argParser.options.containsKey(FlutterOptions.kDartDefineFromFileOption)) {
|
||||
final List<String> configJsonPaths = stringsArg(
|
||||
FlutterOptions.kDartDefineFromFileOption,
|
||||
FlutterOptions.kDartDefineFromFileOption,
|
||||
);
|
||||
|
||||
for (final String path in configJsonPaths) {
|
||||
@ -1359,8 +1356,8 @@ abstract class FlutterCommand extends Command<void> {
|
||||
try {
|
||||
// Fix json convert Object value :type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, Object>' in type cast
|
||||
(json.decode(configJsonRaw) as Map<String, dynamic>)
|
||||
.forEach((String key, dynamic value) {
|
||||
dartDefineConfigJsonMap[key] = value as Object;
|
||||
.forEach((String key, Object? value) {
|
||||
dartDefineConfigJsonMap[key] = value;
|
||||
});
|
||||
} on FormatException catch (err) {
|
||||
throwToolExit('Json config define file "--${FlutterOptions
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
@ -12,6 +14,7 @@ import 'package:flutter_tools/src/bundle.dart';
|
||||
import 'package:flutter_tools/src/bundle_builder.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/build_bundle.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
@ -504,7 +507,7 @@ void main() {
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('test --dart-define-from-file option', () async {
|
||||
testUsingContext('--dart-define-from-file successfully forwards values to build env', () async {
|
||||
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
@ -514,7 +517,8 @@ void main() {
|
||||
"kInt": 1,
|
||||
"kDouble": 1.1,
|
||||
"name": "denghaizhu",
|
||||
"title": "this is title from config json file"
|
||||
"title": "this is title from config json file",
|
||||
"nullValue": null
|
||||
}
|
||||
'''
|
||||
);
|
||||
@ -537,7 +541,17 @@ void main() {
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
expect(environment.defines[kDartDefines], 'a0ludD0x,a0RvdWJsZT0xLjE=,bmFtZT1kZW5naGFpemh1,dGl0bGU9dGhpcyBpcyB0aXRsZSBmcm9tIGNvbmZpZyBqc29uIGZpbGU=,Ym9keT10aGlzIGlzIGJvZHkgZnJvbSBjb25maWcganNvbiBmaWxl');
|
||||
expect(
|
||||
_decodeDartDefines(environment),
|
||||
containsAllInOrder(const <String>[
|
||||
'kInt=1',
|
||||
'kDouble=1.1',
|
||||
'name=denghaizhu',
|
||||
'title=this is title from config json file',
|
||||
'nullValue=null',
|
||||
'body=this is body from config json file',
|
||||
]),
|
||||
);
|
||||
}),
|
||||
FileSystem: fsFactory,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
@ -576,7 +590,10 @@ void main() {
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
expect(environment.defines[kDartDefines], 'a0ludD0y,a0RvdWJsZT0xLjE=,bmFtZT1kZW5naGFpemh1,dGl0bGU9dGhpcyBpcyB0aXRsZSBmcm9tIGNvbmZpZyBqc29uIGZpbGU=');
|
||||
expect(
|
||||
_decodeDartDefines(environment),
|
||||
containsAllInOrder(<String>['kInt=2', 'kDouble=1.1', 'name=denghaizhu', 'title=this is title from config json file']),
|
||||
);
|
||||
}),
|
||||
FileSystem: fsFactory,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
@ -632,6 +649,15 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
Iterable<String> _decodeDartDefines(Environment environment) {
|
||||
final String encodedDefines = environment.defines[kDartDefines]!;
|
||||
const Utf8Decoder byteDecoder = Utf8Decoder();
|
||||
return encodedDefines
|
||||
.split(',')
|
||||
.map<Uint8List>(base64.decode)
|
||||
.map<String>(byteDecoder.convert);
|
||||
}
|
||||
|
||||
class FakeBundleBuilder extends Fake implements BundleBuilder {
|
||||
@override
|
||||
Future<void> build({
|
||||
|
Loading…
x
Reference in New Issue
Block a user