[flutter_tools] switch dart defines to base64 to avoid windows control characters (#75027)

= gets escaped into %3D which seems to be tripping up cmake on windows since % is a control character. Switch to base64 encoding, since this does not have % nor , in the output character set.

This change is not trivially cherry pickable, and isn't tested on windows aside from my local, manual tests due to the planned CI work not being complete yet.

Fixes #75017
Fixes #74705
This commit is contained in:
Jonah Williams 2021-02-02 09:10:48 -08:00 committed by GitHub
parent aebf548436
commit 44d5950d27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 149 additions and 88 deletions

View File

@ -56,7 +56,6 @@ or
]); ]);
final String bundlePlatform = targetPlatform == 'windows-x64' ? 'windows' : 'linux'; final String bundlePlatform = targetPlatform == 'windows-x64' ? 'windows' : 'linux';
final String target = '${buildMode}_bundle_${bundlePlatform}_assets'; final String target = '${buildMode}_bundle_${bundlePlatform}_assets';
final Process assembleProcess = await Process.start( final Process assembleProcess = await Process.start(
flutterExecutable, flutterExecutable,
<String>[ <String>[

View File

@ -308,15 +308,8 @@ Future<void> buildGradleApp({
if (target != null) { if (target != null) {
command.add('-Ptarget=$target'); command.add('-Ptarget=$target');
} }
assert(buildInfo.trackWidgetCreation != null); command.addAll(androidBuildInfo.buildInfo.toGradleConfig());
command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
if (buildInfo.extraFrontEndOptions != null) {
command.add('-Pextra-front-end-options=${encodeDartDefines(buildInfo.extraFrontEndOptions)}');
}
if (buildInfo.extraGenSnapshotOptions != null) {
command.add('-Pextra-gen-snapshot-options=${encodeDartDefines(buildInfo.extraGenSnapshotOptions)}');
}
if (buildInfo.fileSystemRoots != null && buildInfo.fileSystemRoots.isNotEmpty) { if (buildInfo.fileSystemRoots != null && buildInfo.fileSystemRoots.isNotEmpty) {
command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}'); command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}');
} }
@ -326,9 +319,6 @@ Future<void> buildGradleApp({
if (androidBuildInfo.splitPerAbi) { if (androidBuildInfo.splitPerAbi) {
command.add('-Psplit-per-abi=true'); command.add('-Psplit-per-abi=true');
} }
if (androidBuildInfo.buildInfo.dartDefines?.isNotEmpty ?? false) {
command.add('-Pdart-defines=${encodeDartDefines(androidBuildInfo.buildInfo.dartDefines)}');
}
if (shouldBuildPluginAsAar) { if (shouldBuildPluginAsAar) {
// Pass a system flag instead of a project flag, so this flag can be // Pass a system flag instead of a project flag, so this flag can be
// read from include_flutter.groovy. // read from include_flutter.groovy.
@ -339,24 +329,6 @@ Future<void> buildGradleApp({
if (androidBuildInfo.fastStart) { if (androidBuildInfo.fastStart) {
command.add('-Pfast-start=true'); command.add('-Pfast-start=true');
} }
if (androidBuildInfo.buildInfo.splitDebugInfoPath != null) {
command.add('-Psplit-debug-info=${androidBuildInfo.buildInfo.splitDebugInfoPath}');
}
if (androidBuildInfo.buildInfo.treeShakeIcons) {
command.add('-Ptree-shake-icons=true');
}
if (androidBuildInfo.buildInfo.dartObfuscation) {
command.add('-Pdart-obfuscation=true');
}
if (androidBuildInfo.buildInfo.bundleSkSLPath != null) {
command.add('-Pbundle-sksl-path=${androidBuildInfo.buildInfo.bundleSkSLPath}');
}
if (androidBuildInfo.buildInfo.performanceMeasurementFile != null) {
command.add('-Pperformance-measurement-file=${androidBuildInfo.buildInfo.performanceMeasurementFile}');
}
if (buildInfo.codeSizeDirectory != null) {
command.add('-Pcode-size-directory=${buildInfo.codeSizeDirectory}');
}
command.add(assembleTask); command.add(assembleTask);
GradleHandledError detectedGradleError; GradleHandledError detectedGradleError;
@ -611,18 +583,12 @@ Future<void> buildGradleAar({
if (target != null && target.isNotEmpty) { if (target != null && target.isNotEmpty) {
command.add('-Ptarget=$target'); command.add('-Ptarget=$target');
} }
if (buildInfo.splitDebugInfoPath != null) { command.addAll(androidBuildInfo.buildInfo.toGradleConfig());
command.add('-Psplit-debug-info=${buildInfo.splitDebugInfoPath}'); if (buildInfo.dartObfuscation && buildInfo.mode != BuildMode.release) {
} globals.printStatus(
if (buildInfo.treeShakeIcons) { 'Dart obfuscation is not supported in ${toTitleCase(buildInfo.friendlyModeName)}'
command.add('-Pfont-subset=true'); ' mode, building as un-obfuscated.',
} );
if (buildInfo.dartObfuscation) {
if (buildInfo.mode == BuildMode.debug || buildInfo.mode == BuildMode.profile) {
globals.printStatus('Dart obfuscation is not supported in ${toTitleCase(buildInfo.friendlyModeName)} mode, building as un-obfuscated.');
} else {
command.add('-Pdart-obfuscation=true');
}
} }
if (globals.artifacts is LocalEngineArtifacts) { if (globals.artifacts is LocalEngineArtifacts) {

View File

@ -13,6 +13,7 @@ import 'base/file_system.dart';
import 'base/logger.dart'; import 'base/logger.dart';
import 'base/utils.dart'; import 'base/utils.dart';
import 'build_system/targets/icon_tree_shaker.dart'; import 'build_system/targets/icon_tree_shaker.dart';
import 'convert.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
/// Information about a build to be performed or used. /// Information about a build to be performed or used.
@ -192,9 +193,9 @@ class BuildInfo {
if (dartObfuscation != null) if (dartObfuscation != null)
'DART_OBFUSCATION': dartObfuscation.toString(), 'DART_OBFUSCATION': dartObfuscation.toString(),
if (extraFrontEndOptions?.isNotEmpty ?? false) if (extraFrontEndOptions?.isNotEmpty ?? false)
'EXTRA_FRONT_END_OPTIONS': encodeDartDefines(extraFrontEndOptions), 'EXTRA_FRONT_END_OPTIONS': extraFrontEndOptions?.join(','),
if (extraGenSnapshotOptions?.isNotEmpty ?? false) if (extraGenSnapshotOptions?.isNotEmpty ?? false)
'EXTRA_GEN_SNAPSHOT_OPTIONS': encodeDartDefines(extraGenSnapshotOptions), 'EXTRA_GEN_SNAPSHOT_OPTIONS': extraGenSnapshotOptions?.join(','),
if (splitDebugInfoPath != null) if (splitDebugInfoPath != null)
'SPLIT_DEBUG_INFO': splitDebugInfoPath, 'SPLIT_DEBUG_INFO': splitDebugInfoPath,
if (trackWidgetCreation != null) if (trackWidgetCreation != null)
@ -211,6 +212,34 @@ class BuildInfo {
'CODE_SIZE_DIRECTORY': codeSizeDirectory, 'CODE_SIZE_DIRECTORY': codeSizeDirectory,
}; };
} }
/// Convert this config to a series of project level arguments to be passed
/// on the command line to gradle.
List<String> toGradleConfig() {
// PACKAGE_CONFIG not currently supported.
return <String>[
if (dartDefines?.isNotEmpty ?? false)
'-Pdart-defines=${encodeDartDefines(dartDefines)}',
if (dartObfuscation != null)
'-Pdart-obfuscation=$dartObfuscation',
if (extraFrontEndOptions?.isNotEmpty ?? false)
'-Pextra-front-end-options=${extraFrontEndOptions?.join(',')}',
if (extraGenSnapshotOptions?.isNotEmpty ?? false)
'-Pextra-gen-snapshot-options=${extraGenSnapshotOptions?.join(',')}',
if (splitDebugInfoPath != null)
'-Psplit-debug-info=$splitDebugInfoPath',
if (trackWidgetCreation != null)
'-Ptrack-widget-creation=$trackWidgetCreation',
if (treeShakeIcons != null)
'-Ptree-shake-icons=$treeShakeIcons',
if (performanceMeasurementFile != null)
'-Pperformance-measurement-file=$performanceMeasurementFile',
if (bundleSkSLPath != null)
'-Pbundle-sksl-path=$bundleSkSLPath',
if (codeSizeDirectory != null)
'-Pcode-size-directory=$codeSizeDirectory',
];
}
} }
/// Information about an Android build to be performed or used. /// Information about an Android build to be performed or used.
@ -737,9 +766,32 @@ String getFuchsiaBuildDirectory() {
/// These values are URI-encoded and then combined into a comma-separated string. /// These values are URI-encoded and then combined into a comma-separated string.
const String kDartDefines = 'DartDefines'; const String kDartDefines = 'DartDefines';
/// Encode a List of dart defines in a URI string. final Converter<String, String> _defineEncoder = utf8.encoder.fuse(base64.encoder);
final Converter<String, String> _defineDecoder = base64.decoder.fuse(utf8.decoder);
/// Encode a List of dart defines in a base64 string.
///
/// This encoding does not include `,`, which is used to distinguish
/// the individual entries, nor does it include `%` which is often a
/// control character on windows command lines.
///
/// When decoding this string, it can be safely split on commas, since any
/// user provided commans will still be encoded.
///
/// If the presence of the `/` character ends up being an issue, this can
/// be changed to use base32 instead.
String encodeDartDefines(List<String> defines) { String encodeDartDefines(List<String> defines) {
return defines.map(Uri.encodeComponent).join(','); return defines.map(_defineEncoder.convert).join(',');
}
List<String> decodeCommaSeparated(Map<String, String> environmentDefines, String key) {
if (!environmentDefines.containsKey(key) || environmentDefines[key].isEmpty) {
return <String>[];
}
return environmentDefines[key]
.split(',')
.cast<String>()
.toList();
} }
/// Dart defines are encoded inside [environmentDefines] as a comma-separated list. /// Dart defines are encoded inside [environmentDefines] as a comma-separated list.
@ -749,7 +801,7 @@ List<String> decodeDartDefines(Map<String, String> environmentDefines, String ke
} }
return environmentDefines[key] return environmentDefines[key]
.split(',') .split(',')
.map<Object>(Uri.decodeComponent) .map<Object>(_defineDecoder.convert)
.cast<String>() .cast<String>()
.toList(); .toList();
} }

View File

@ -215,7 +215,7 @@ class AndroidAot extends AotElfBase {
if (!output.existsSync()) { if (!output.existsSync()) {
output.createSync(recursive: true); output.createSync(recursive: true);
} }
final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions); final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true'; final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
final String codeSizeDirectory = environment.defines[kCodeSizeDirectory]; final String codeSizeDirectory = environment.defines[kCodeSizeDirectory];

View File

@ -227,7 +227,7 @@ class KernelSnapshot extends Target {
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]); final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
// This configuration is all optional. // This configuration is all optional.
final List<String> extraFrontEndOptions = decodeDartDefines(environment.defines, kExtraFrontEndOptions); final List<String> extraFrontEndOptions = decodeCommaSeparated(environment.defines, kExtraFrontEndOptions);
final List<String> fileSystemRoots = environment.defines[kFileSystemRoots]?.split(','); final List<String> fileSystemRoots = environment.defines[kFileSystemRoots]?.split(',');
final String fileSystemScheme = environment.defines[kFileSystemScheme]; final String fileSystemScheme = environment.defines[kFileSystemScheme];
@ -306,7 +306,7 @@ abstract class AotElfBase extends Target {
if (environment.defines[kTargetPlatform] == null) { if (environment.defines[kTargetPlatform] == null) {
throw MissingDefineException(kTargetPlatform, 'aot_elf'); throw MissingDefineException(kTargetPlatform, 'aot_elf');
} }
final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions); final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]); final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
final String splitDebugInfo = environment.defines[kSplitDebugInfo]; final String splitDebugInfo = environment.defines[kSplitDebugInfo];

View File

@ -54,7 +54,7 @@ abstract class AotAssemblyBase extends Target {
throw MissingDefineException(kSdkRoot, 'aot_assembly'); throw MissingDefineException(kSdkRoot, 'aot_assembly');
} }
final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions); final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
final bool bitcode = environment.defines[kBitcodeFlag] == 'true'; final bool bitcode = environment.defines[kBitcodeFlag] == 'true';
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]); final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);

View File

@ -180,7 +180,7 @@ class CompileMacOSFramework extends Target {
final String codeSizeDirectory = environment.defines[kCodeSizeDirectory]; final String codeSizeDirectory = environment.defines[kCodeSizeDirectory];
final String splitDebugInfo = environment.defines[kSplitDebugInfo]; final String splitDebugInfo = environment.defines[kSplitDebugInfo];
final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true'; final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions); final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
if (codeSizeDirectory != null) { if (codeSizeDirectory != null) {
final File codeSizeFile = environment.fileSystem final File codeSizeFile = environment.fileSystem

View File

@ -202,7 +202,7 @@ class Dart2JSTarget extends Target {
'--disable-dart-dev', '--disable-dart-dev',
globals.artifacts.getArtifactPath(Artifact.dart2jsSnapshot), globals.artifacts.getArtifactPath(Artifact.dart2jsSnapshot),
'--libraries-spec=${globals.fs.path.join(globals.artifacts.getArtifactPath(Artifact.flutterWebSdk), 'libraries.json')}', '--libraries-spec=${globals.fs.path.join(globals.artifacts.getArtifactPath(Artifact.flutterWebSdk), 'libraries.json')}',
...?decodeDartDefines(environment.defines, kExtraFrontEndOptions), ...?decodeCommaSeparated(environment.defines, kExtraFrontEndOptions),
if (nativeNullAssertions) if (nativeNullAssertions)
'--native-null-assertions', '--native-null-assertions',
if (buildMode == BuildMode.profile) if (buildMode == BuildMode.profile)

View File

@ -20,7 +20,6 @@ import '../build_system/targets/common.dart';
import '../build_system/targets/icon_tree_shaker.dart'; import '../build_system/targets/icon_tree_shaker.dart';
import '../build_system/targets/ios.dart'; import '../build_system/targets/ios.dart';
import '../cache.dart'; import '../cache.dart';
import '../convert.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../macos/cocoapod_utils.dart'; import '../macos/cocoapod_utils.dart';
import '../plugins.dart'; import '../plugins.dart';
@ -367,7 +366,7 @@ end
kBuildMode: getNameForBuildMode(buildInfo.mode), kBuildMode: getNameForBuildMode(buildInfo.mode),
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios), kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios),
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(), kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
kDartDefines: jsonEncode(buildInfo.dartDefines), kDartDefines: encodeDartDefines(buildInfo.dartDefines),
kBitcodeFlag: 'true', kBitcodeFlag: 'true',
if (buildInfo?.extraGenSnapshotOptions?.isNotEmpty ?? false) if (buildInfo?.extraGenSnapshotOptions?.isNotEmpty ?? false)
kExtraGenSnapshotOptions: kExtraGenSnapshotOptions:

View File

@ -58,7 +58,7 @@ Future<void> buildWeb(
if (serviceWorkerStrategy != null) if (serviceWorkerStrategy != null)
kServiceWorkerStrategy: serviceWorkerStrategy, kServiceWorkerStrategy: serviceWorkerStrategy,
if (buildInfo.extraFrontEndOptions?.isNotEmpty ?? false) if (buildInfo.extraFrontEndOptions?.isNotEmpty ?? false)
kExtraFrontEndOptions: encodeDartDefines(buildInfo.extraFrontEndOptions), kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(','),
}, },
artifacts: globals.artifacts, artifacts: globals.artifacts,
fileSystem: globals.fs, fileSystem: globals.fs,

View File

@ -368,10 +368,10 @@ ERROR: No file or variants found for asset: images/a_dot_burr.jpeg
expect(configLines, containsAll(<String>[ expect(configLines, containsAll(<String>[
'file(TO_CMAKE_PATH "$_kTestFlutterRoot" FLUTTER_ROOT)', 'file(TO_CMAKE_PATH "$_kTestFlutterRoot" FLUTTER_ROOT)',
'file(TO_CMAKE_PATH "${fileSystem.currentDirectory.path}" PROJECT_DIR)', 'file(TO_CMAKE_PATH "${fileSystem.currentDirectory.path}" PROJECT_DIR)',
' "DART_DEFINES=foo.bar%3D2,fizz.far%3D3"', ' "DART_DEFINES=Zm9vLmJhcj0y,Zml6ei5mYXI9Mw=="',
' "DART_OBFUSCATION=true"', ' "DART_OBFUSCATION=true"',
' "EXTRA_FRONT_END_OPTIONS=--enable-experiment%3Dnon-nullable"', ' "EXTRA_FRONT_END_OPTIONS=--enable-experiment=non-nullable"',
' "EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment%3Dnon-nullable"', ' "EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment=non-nullable"',
' "SPLIT_DEBUG_INFO=foo/"', ' "SPLIT_DEBUG_INFO=foo/"',
' "TRACK_WIDGET_CREATION=true"', ' "TRACK_WIDGET_CREATION=true"',
' "TREE_SHAKE_ICONS=true"', ' "TREE_SHAKE_ICONS=true"',

View File

@ -257,16 +257,21 @@ void main() {
.readAsLinesSync(); .readAsLinesSync();
expect(contents, containsAll(<String>[ expect(contents, containsAll(<String>[
'DART_DEFINES=foo.bar%3D2,fizz.far%3D3', 'FLUTTER_APPLICATION_PATH=/',
'FLUTTER_TARGET=lib/other.dart',
'FLUTTER_BUILD_DIR=build',
'FLUTTER_BUILD_NAME=1.0.0',
'FLUTTER_BUILD_NUMBER=1',
'EXCLUDED_ARCHS=arm64',
'DART_DEFINES=Zm9vLmJhcj0y,Zml6ei5mYXI9Mw==',
'DART_OBFUSCATION=true', 'DART_OBFUSCATION=true',
'EXTRA_FRONT_END_OPTIONS=--enable-experiment%3Dnon-nullable', 'EXTRA_FRONT_END_OPTIONS=--enable-experiment=non-nullable',
'EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment%3Dnon-nullable', 'EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment=non-nullable',
'SPLIT_DEBUG_INFO=foo/', 'SPLIT_DEBUG_INFO=foo/',
'TRACK_WIDGET_CREATION=true', 'TRACK_WIDGET_CREATION=true',
'TREE_SHAKE_ICONS=true', 'TREE_SHAKE_ICONS=true',
'FLUTTER_TARGET=lib/other.dart',
'BUNDLE_SKSL_PATH=foo/bar.sksl.json', 'BUNDLE_SKSL_PATH=foo/bar.sksl.json',
'EXCLUDED_ARCHS=arm64', 'PACKAGE_CONFIG=/.dart_tool/package_config.json'
])); ]));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,

View File

@ -317,10 +317,10 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
expect(configLines, containsAll(<String>[ expect(configLines, containsAll(<String>[
r'file(TO_CMAKE_PATH "C:\\flutter" FLUTTER_ROOT)', r'file(TO_CMAKE_PATH "C:\\flutter" FLUTTER_ROOT)',
r'file(TO_CMAKE_PATH "C:\\" PROJECT_DIR)', r'file(TO_CMAKE_PATH "C:\\" PROJECT_DIR)',
r' "DART_DEFINES=foo%3Da,bar%3Db"', r' "DART_DEFINES=Zm9vPWE=,YmFyPWI="',
r' "DART_OBFUSCATION=true"', r' "DART_OBFUSCATION=true"',
r' "EXTRA_FRONT_END_OPTIONS=--enable-experiment%3Dnon-nullable"', r' "EXTRA_FRONT_END_OPTIONS=--enable-experiment=non-nullable"',
r' "EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment%3Dnon-nullable"', r' "EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment=non-nullable"',
r' "SPLIT_DEBUG_INFO=C:\\foo\\"', r' "SPLIT_DEBUG_INFO=C:\\foo\\"',
r' "TRACK_WIDGET_CREATION=true"', r' "TRACK_WIDGET_CREATION=true"',
r' "TREE_SHAKE_ICONS=true"', r' "TREE_SHAKE_ICONS=true"',

View File

@ -237,6 +237,7 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Pdart-obfuscation=false',
'-Ptrack-widget-creation=true', '-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',
@ -265,8 +266,9 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=true', '-Pdart-obfuscation=false',
'-Psplit-debug-info=${tempDir.path}', '-Psplit-debug-info=${tempDir.path}',
'-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',
], ],
@ -297,8 +299,9 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=true', '-Pdart-obfuscation=false',
'-Pextra-front-end-options=foo,bar', '-Pextra-front-end-options=foo,bar',
'-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',
], ],
@ -329,6 +332,7 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Pdart-obfuscation=false',
'-Ptrack-widget-creation=true', '-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',
@ -353,6 +357,7 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Pdart-obfuscation=false',
'-Ptrack-widget-creation=true', '-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',
@ -422,6 +427,7 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Pdart-obfuscation=false',
'-Ptrack-widget-creation=true', '-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',
@ -481,6 +487,7 @@ void main() {
'-q', '-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}', '-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Pdart-obfuscation=false',
'-Ptrack-widget-creation=true', '-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true', '-Ptree-shake-icons=true',
'assembleRelease', 'assembleRelease',

View File

@ -916,7 +916,9 @@ plugin2=${plugin2.path}
'-Pis-plugin=true', '-Pis-plugin=true',
'-PbuildNumber=1.0', '-PbuildNumber=1.0',
'-q', '-q',
'-Pfont-subset=true', '-Pdart-obfuscation=false',
'-Ptrack-widget-creation=false',
'-Ptree-shake-icons=true',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'assembleAarRelease', 'assembleAarRelease',
], ],
@ -931,7 +933,9 @@ plugin2=${plugin2.path}
'-Pis-plugin=true', '-Pis-plugin=true',
'-PbuildNumber=1.0', '-PbuildNumber=1.0',
'-q', '-q',
'-Pfont-subset=true', '-Pdart-obfuscation=false',
'-Ptrack-widget-creation=false',
'-Ptree-shake-icons=true',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'assembleAarRelease', 'assembleAarRelease',
], ],
@ -2103,7 +2107,9 @@ plugin1=${plugin1.path}
'--no-daemon', '--no-daemon',
'-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=lib/main.dart', '-Ptarget=lib/main.dart',
'-Pdart-obfuscation=false',
'-Ptrack-widget-creation=false', '-Ptrack-widget-creation=false',
'-Ptree-shake-icons=false',
'assembleRelease' 'assembleRelease'
], ],
)); ));

View File

@ -115,40 +115,67 @@ void main() {
expect(buildInfo.toEnvironmentConfig(), <String, String>{ expect(buildInfo.toEnvironmentConfig(), <String, String>{
'TREE_SHAKE_ICONS': 'true', 'TREE_SHAKE_ICONS': 'true',
'TRACK_WIDGET_CREATION': 'true', 'TRACK_WIDGET_CREATION': 'true',
'DART_DEFINES': 'foo%3D2,bar%3D2', 'DART_DEFINES': 'Zm9vPTI=,YmFyPTI=',
'DART_OBFUSCATION': 'true', 'DART_OBFUSCATION': 'true',
'SPLIT_DEBUG_INFO': 'foo/', 'SPLIT_DEBUG_INFO': 'foo/',
'EXTRA_FRONT_END_OPTIONS': '--enable-experiment%3Dnon-nullable,bar', 'EXTRA_FRONT_END_OPTIONS': '--enable-experiment=non-nullable,bar',
'EXTRA_GEN_SNAPSHOT_OPTIONS': '--enable-experiment%3Dnon-nullable,fizz', 'EXTRA_GEN_SNAPSHOT_OPTIONS': '--enable-experiment=non-nullable,fizz',
'BUNDLE_SKSL_PATH': 'foo/bar/baz.sksl.json', 'BUNDLE_SKSL_PATH': 'foo/bar/baz.sksl.json',
'PACKAGE_CONFIG': 'foo/.packages', 'PACKAGE_CONFIG': 'foo/.packages',
'CODE_SIZE_DIRECTORY': 'foo/code-size', 'CODE_SIZE_DIRECTORY': 'foo/code-size',
}); });
}); });
testWithoutContext('encodeDartDefines encodes define values with URI encode compnents', () { testWithoutContext('toGradleConfig encoding of standard values', () {
expect(encodeDartDefines(<String>['"hello"']), '%22hello%22'); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, '',
expect(encodeDartDefines(<String>['https://www.google.com']), 'https%3A%2F%2Fwww.google.com'); treeShakeIcons: true,
expect(encodeDartDefines(<String>['2,3,4', '5']), '2%2C3%2C4,5'); trackWidgetCreation: true,
expect(encodeDartDefines(<String>['true', 'false', 'flase']), 'true,false,flase'); dartDefines: <String>['foo=2', 'bar=2'],
expect(encodeDartDefines(<String>['1232,456', '2']), '1232%2C456,2'); dartObfuscation: true,
splitDebugInfoPath: 'foo/',
extraFrontEndOptions: <String>['--enable-experiment=non-nullable', 'bar'],
extraGenSnapshotOptions: <String>['--enable-experiment=non-nullable', 'fizz'],
bundleSkSLPath: 'foo/bar/baz.sksl.json',
packagesPath: 'foo/.packages',
codeSizeDirectory: 'foo/code-size',
);
expect(buildInfo.toGradleConfig(), <String>[
'-Pdart-defines=Zm9vPTI=,YmFyPTI=',
'-Pdart-obfuscation=true',
'-Pextra-front-end-options=--enable-experiment=non-nullable,bar',
'-Pextra-gen-snapshot-options=--enable-experiment=non-nullable,fizz',
'-Psplit-debug-info=foo/',
'-Ptrack-widget-creation=true',
'-Ptree-shake-icons=true',
'-Pbundle-sksl-path=foo/bar/baz.sksl.json',
'-Pcode-size-directory=foo/code-size'
]);
}); });
testWithoutContext('decodeDartDefines decodes URI encoded dart defines', () { testWithoutContext('encodeDartDefines encodes define values with base64 encoded compnents', () {
expect(encodeDartDefines(<String>['"hello"']), 'ImhlbGxvIg==');
expect(encodeDartDefines(<String>['https://www.google.com']), 'aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbQ==');
expect(encodeDartDefines(<String>['2,3,4', '5']), 'MiwzLDQ=,NQ==');
expect(encodeDartDefines(<String>['true', 'false', 'flase']), 'dHJ1ZQ==,ZmFsc2U=,Zmxhc2U=');
expect(encodeDartDefines(<String>['1232,456', '2']), 'MTIzMiw0NTY=,Mg==');
});
testWithoutContext('decodeDartDefines decodes base64 encoded dart defines', () {
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: '%22hello%22' kDartDefines: 'ImhlbGxvIg=='
}, kDartDefines), <String>['"hello"']); }, kDartDefines), <String>['"hello"']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: 'https%3A%2F%2Fwww.google.com' kDartDefines: 'aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbQ=='
}, kDartDefines), <String>['https://www.google.com']); }, kDartDefines), <String>['https://www.google.com']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: '2%2C3%2C4,5' kDartDefines: 'MiwzLDQ=,NQ=='
}, kDartDefines), <String>['2,3,4', '5']); }, kDartDefines), <String>['2,3,4', '5']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: 'true,false,flase' kDartDefines: 'dHJ1ZQ==,ZmFsc2U=,Zmxhc2U='
}, kDartDefines), <String>['true', 'false', 'flase']); }, kDartDefines), <String>['true', 'false', 'flase']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: '1232%2C456,2' kDartDefines: 'MTIzMiw0NTY=,Mg=='
}, kDartDefines), <String>['1232,456', '2']); }, kDartDefines), <String>['1232,456', '2']);
}); });
} }

View File

@ -481,7 +481,7 @@ void main() {
test('Dart2JSTarget calls dart2js with Dart defines in release mode', () => testbed.run(() async { test('Dart2JSTarget calls dart2js with Dart defines in release mode', () => testbed.run(() async {
environment.defines[kBuildMode] = 'release'; environment.defines[kBuildMode] = 'release';
environment.defines[kDartDefines] = 'FOO=bar,BAZ=qux'; environment.defines[kDartDefines] = encodeDartDefines(<String>['FOO=bar', 'BAZ=qux']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
...kDart2jsLinuxArgs, ...kDart2jsLinuxArgs,
@ -548,7 +548,7 @@ void main() {
test('Dart2JSTarget calls dart2js with Dart defines in profile mode', () => testbed.run(() async { test('Dart2JSTarget calls dart2js with Dart defines in profile mode', () => testbed.run(() async {
environment.defines[kBuildMode] = 'profile'; environment.defines[kBuildMode] = 'profile';
environment.defines[kDartDefines] = 'FOO=bar,BAZ=qux'; environment.defines[kDartDefines] = encodeDartDefines(<String>['FOO=bar', 'BAZ=qux']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
...kDart2jsLinuxArgs, ...kDart2jsLinuxArgs,