Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
673806f
[CP: 3.32] [Widget Inspector] Update on-device inspector button to ge…
elliette May 20, 2025
44b32ec
[CP-stable][reland] Fix regression in NDK version checking (#169289)
flutteractionsbot May 23, 2025
6e07e1f
[CP-stable]Skip running `Linux fuchsia_test` on non-master channel. (…
flutteractionsbot May 23, 2025
9057717
[CP-stable]Use `.flutter-plugins-dependencies` for crash reporting. (…
flutteractionsbot May 27, 2025
80f085c
[stable] Roll `package:dds` to 5.0.2 (#169471) (#169515)
bkonyi May 27, 2025
c56879b
Roll Skia to the flutter/3.32 branch (#169531)
jason-simmons May 28, 2025
7d3efe4
[CP-stable]Fixes tab semantics gets dropped if the child produce a se…
flutteractionsbot May 28, 2025
1425e5e
Update dart revision (3.8.1) for 3.32.1 release (#169601)
eyebrowsoffire May 28, 2025
6374794
Update `engine.version` to `1425e5e9ec5eeb4f225c401d8db69b860e0fde9a`…
matanlurey May 29, 2025
0a159b3
[CP-stable]Roll forward: "Initialize default-app-flavor" (#169298) (#…
flutteractionsbot May 29, 2025
b25305a
Update engine.version and changelog for upcoming stable release 3.32.…
eyebrowsoffire May 29, 2025
1091508
[CP-Stable] Use `Linux windows_*_engine` orchestrators (#169772)
matanlurey May 30, 2025
04f9ead
[CP-stable]🐛 Use consist slashes when generating dep files (#169630)
flutteractionsbot May 30, 2025
d88a675
[CP-stable] Split `Linux docs_publish` into `Linux docs_generate_rele…
flutteractionsbot Jun 3, 2025
fa17ad1
Update `engine.version` for 3.32.2 stable hotfix release (#169952)
camsim99 Jun 3, 2025
8defaa7
Re-update `engine.version` for 3.32.2 stable hotfix release to the la…
camsim99 Jun 4, 2025
46a4c05
[CP-stable]Revert "Fix NavigationBar indicator overlay color (#164484…
flutteractionsbot Jun 5, 2025
31c4875
[CP-stable][Impeller] Maintain a global map of each context's current…
flutteractionsbot Jun 5, 2025
b02643b
[CP-stable]fix: add the missing type of debug metadata (#170003)
flutteractionsbot Jun 5, 2025
5c14335
Prepare to publish 3.32.3, update changelog+engine.version. (#170470)
matanlurey Jun 11, 2025
8cd19e5
Trigger a new engine build from HEAD in `3.32` (#170558)
matanlurey Jun 12, 2025
6fba244
Update `engine.version` (#170560)
matanlurey Jun 13, 2025
f7ec6d9
[Tizen] Cherrypicks from flutter-3.27.1 of flutter-tizen/engine
JSUYA Mar 5, 2025
78a8141
[Tizen] Add CI related files
JSUYA Mar 5, 2025
13cd62c
[Tizen][impeller] Disable gles3 compile
JSUYA Mar 12, 2025
7ce8bde
[Tizen] Support EmbedderExternalTextureGL for impeller
xiaowei-guan Mar 18, 2025
9b5e52f
[Tizen] Remove unnecessary CI
JSUYA May 23, 2025
816d1b0
[Tizen] Upgrade llvm 17 to 18
JSUYA May 23, 2025
b98ef12
[Tizen] Remove unnecessary CI
JSUYA Jun 19, 2025
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
Prev Previous commit
Next Next commit
[CP-stable]Roll forward: "Initialize default-app-flavor" (flutter#169298
) (flutter#169623)

This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request)
Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.

### Issue Link:
What is the link to the issue this cherry-pick is addressing?

flutter#169602

### Changelog Description:
Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examples

Fixes a bug where `appFlavor` is `null` when being run with `flutter test` or being hot-restarted.

### Impact Description:
What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch)

Cannot reliably use `appFlavor` without rebuilding the app from scratch.

### Workaround:
Is there a workaround for this issue?

Do not use hot restart, do not use `flutter test`.

### Risk:
What is the risk level of this cherry-pick?

### Test Coverage:
Are you confident that your fix is well-tested by automated tests?

### Validation Steps:
What are the steps to validate that this fix works?

Automated test coverage.
  • Loading branch information
flutteractionsbot authored May 29, 2025
commit 0a159b315d33153beba629e3bc93182f331853c2
24 changes: 12 additions & 12 deletions packages/flutter_tools/lib/src/build_system/targets/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import 'package:package_config/package_config.dart';

import '../../artifacts.dart';
import '../../base/build.dart';
import '../../base/common.dart';
import '../../base/file_system.dart';
import '../../base/io.dart';
import '../../build_info.dart';
import '../../compile.dart';
import '../../dart/package_map.dart';
import '../../devfs.dart';
import '../../globals.dart' as globals show platform, xcode;
import '../../globals.dart' as globals show xcode;
import '../../project.dart';
import '../../runner/flutter_command.dart';
import '../build_system.dart';
import '../depfile.dart';
import '../exceptions.dart';
Expand Down Expand Up @@ -310,15 +308,17 @@ class KernelSnapshot extends Target {
if (flavor == null) {
return;
}
if (globals.platform.environment[kAppFlavor] != null) {
throwToolExit('$kAppFlavor is used by the framework and cannot be set in the environment.');
}
if (dartDefines.any((String define) => define.startsWith(kAppFlavor))) {
throwToolExit(
'$kAppFlavor is used by the framework and cannot be '
'set using --${FlutterOptions.kDartDefinesOption} or --${FlutterOptions.kDartDefineFromFileOption}',
);
}

// It is possible there is a flavor already in dartDefines, from another
// part of the build process, but this should take precedence as it happens
// last (xcodebuild execution).
//
// See https://github.com/flutter/flutter/issues/169598.

// If the flavor is already in the dart defines, remove it.
dartDefines.removeWhere((String define) => define.startsWith(kAppFlavor));

// Then, add it to the end.
dartDefines.add('$kAppFlavor=$flavor');
}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/flutter_tools/lib/src/runner/flutter_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1438,6 +1438,18 @@ abstract class FlutterCommand extends Command<void> {
final String? cliFlavor = argParser.options.containsKey('flavor') ? stringArg('flavor') : null;
final String? flavor = cliFlavor ?? defaultFlavor;

if (globals.platform.environment[kAppFlavor] != null) {
throwToolExit('$kAppFlavor is used by the framework and cannot be set in the environment.');
}
if (dartDefines.any((String define) => define.startsWith(kAppFlavor))) {
throwToolExit(
'$kAppFlavor is used by the framework and cannot be '
'set using --${FlutterOptions.kDartDefinesOption} or --${FlutterOptions.kDartDefineFromFileOption}',
);
}
if (flavor != null) {
dartDefines.add('$kAppFlavor=$flavor');
}
_addFlutterVersionToDartDefines(globals.flutterVersion, dartDefines);

return BuildInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:flutter_tools/src/build_system/exceptions.dart';
import 'package:flutter_tools/src/build_system/targets/common.dart';
import 'package:flutter_tools/src/build_system/targets/ios.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:test/fake.dart';

Expand Down Expand Up @@ -440,69 +441,76 @@ void main() {
);

testUsingContext(
"tool exits when $kAppFlavor is already set in user's environment",
'KernelSnapshot sets flavor in dartDefines from Xcode build configuration if ios app',
() async {
fileSystem.file('.dart_tool/package_config.json')
..createSync(recursive: true)
..writeAsStringSync('{"configVersion": 2, "packages":[]}');
final Future<void> buildResult = const KernelSnapshot().build(
androidEnvironment
..defines[kTargetPlatform] = getNameForTargetPlatform(TargetPlatform.android)
..defines[kBuildMode] = BuildMode.debug.cliName
..defines[kFlavor] = 'strawberry'
..defines[kTrackWidgetCreation] = 'false',
final String build = iosEnvironment.buildDir.path;
final String flutterPatchedSdkPath = artifacts.getArtifactPath(
Artifact.flutterPatchedSdkPath,
platform: TargetPlatform.ios,
mode: BuildMode.debug,
);

expect(
buildResult,
throwsToolExit(
message: '$kAppFlavor is used by the framework and cannot be set in the environment.',
fileSystem.directory('/ios/Runner.xcodeproj').createSync(recursive: true);
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
artifacts.getArtifactPath(Artifact.engineDartAotRuntime),
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
'$flutterPatchedSdkPath/',
'--target=flutter',
'--no-print-incremental-dependencies',
'-D$kAppFlavor=chocolate',
...buildModeOptions(BuildMode.debug, <String>[]),
'--no-link-platform',
'--packages',
'/.dart_tool/package_config.json',
'--output-dill',
'$build/app.dill',
'--depfile',
'$build/kernel_snapshot_program.d',
'--incremental',
'--initialize-from-dill',
'$build/app.dill',
'--verbosity=error',
'file:///lib/main.dart',
],
stdout: 'result $kBoundaryKey\n$kBoundaryKey\n$kBoundaryKey $build/app.dill 0\n',
),
);
},
overrides: <Type, Generator>{
Platform: () => FakePlatform(environment: <String, String>{kAppFlavor: 'I was already set'}),
},
);
]);

testUsingContext(
'tool exits when $kAppFlavor is set in --dart-define or --dart-define-from-file',
() async {
fileSystem.file('.dart_tool/package_config.json')
..createSync(recursive: true)
..writeAsStringSync('{"configVersion": 2, "packages":[]}');
final Future<void> buildResult = const KernelSnapshot().build(
androidEnvironment
..defines[kTargetPlatform] = getNameForTargetPlatform(TargetPlatform.android)
await const KernelSnapshot().build(
iosEnvironment
..defines[kTargetPlatform] = getNameForTargetPlatform(TargetPlatform.ios)
..defines[kBuildMode] = BuildMode.debug.cliName
..defines[kFlavor] = 'strawberry'
..defines[kDartDefines] = encodeDartDefines(<String>[kAppFlavor, 'strawberry'])
..defines[kXcodeConfiguration] = 'Debug-chocolate'
..defines[kTrackWidgetCreation] = 'false',
);

expect(
buildResult,
throwsToolExit(
message:
'$kAppFlavor is used by the framework and cannot be set using --dart-define or --dart-define-from-file',
),
);
expect(processManager, hasNoRemainingExpectations);
},
overrides: <Type, Generator>{
XcodeProjectInterpreter:
() => FakeXcodeProjectInterpreter(schemes: <String>['Runner', 'chocolate']),
},
);

testUsingContext(
'KernelSnapshot sets flavor in dartDefines from Xcode build configuration if ios app',
'KernelSnapshot sets flavor in dartDefines from Xcode build configuration if macos app',
() async {
fileSystem.file('.dart_tool/package_config.json')
..createSync(recursive: true)
..writeAsStringSync('{"configVersion": 2, "packages":[]}');
final String build = iosEnvironment.buildDir.path;
final String flutterPatchedSdkPath = artifacts.getArtifactPath(
Artifact.flutterPatchedSdkPath,
platform: TargetPlatform.ios,
platform: TargetPlatform.darwin,
mode: BuildMode.debug,
);
fileSystem.directory('/ios/Runner.xcodeproj').createSync(recursive: true);
fileSystem.directory('/macos/Runner.xcodeproj').createSync(recursive: true);
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
Expand All @@ -514,7 +522,6 @@ void main() {
'--no-print-incremental-dependencies',
'-D$kAppFlavor=chocolate',
...buildModeOptions(BuildMode.debug, <String>[]),
'--no-link-platform',
'--packages',
'/.dart_tool/package_config.json',
'--output-dill',
Expand All @@ -533,7 +540,7 @@ void main() {

await const KernelSnapshot().build(
iosEnvironment
..defines[kTargetPlatform] = getNameForTargetPlatform(TargetPlatform.ios)
..defines[kTargetPlatform] = getNameForTargetPlatform(TargetPlatform.darwin)
..defines[kBuildMode] = BuildMode.debug.cliName
..defines[kFlavor] = 'strawberry'
..defines[kXcodeConfiguration] = 'Debug-chocolate'
Expand All @@ -549,7 +556,7 @@ void main() {
);

testUsingContext(
'KernelSnapshot sets flavor in dartDefines from Xcode build configuration if macos app',
'KernelSnapshot does not add kAppFlavor twice to Dart defines',
() async {
fileSystem.file('.dart_tool/package_config.json')
..createSync(recursive: true)
Expand All @@ -560,7 +567,6 @@ void main() {
platform: TargetPlatform.darwin,
mode: BuildMode.debug,
);
fileSystem.directory('/macos/Runner.xcodeproj').createSync(recursive: true);
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
Expand All @@ -570,7 +576,7 @@ void main() {
'$flutterPatchedSdkPath/',
'--target=flutter',
'--no-print-incremental-dependencies',
'-D$kAppFlavor=chocolate',
'-D$kAppFlavor=strawberry',
...buildModeOptions(BuildMode.debug, <String>[]),
'--packages',
'/.dart_tool/package_config.json',
Expand All @@ -592,16 +598,17 @@ void main() {
iosEnvironment
..defines[kTargetPlatform] = getNameForTargetPlatform(TargetPlatform.darwin)
..defines[kBuildMode] = BuildMode.debug.cliName
..defines[kDartDefines] = base64Encode(utf8.encode('FLUTTER_APP_FLAVOR=vanilla'))
..defines[kFlavor] = 'strawberry'
..defines[kXcodeConfiguration] = 'Debug-chocolate'
..defines[kTrackWidgetCreation] = 'false',
);

expect(processManager, hasNoRemainingExpectations);
},
overrides: <Type, Generator>{
XcodeProjectInterpreter:
() => FakeXcodeProjectInterpreter(schemes: <String>['Runner', 'chocolate']),
Platform: () => macPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
},
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,98 @@ flutter:
);
});

testUsingContext(
"tool exits when $kAppFlavor is already set in user's environemnt",
() async {
final CommandRunner<void> runner = createTestCommandRunner(
_TestRunCommandThatOnlyValidates(),
);
expect(
runner.run(<String>['run', '--no-pub', '--no-hot']),
throwsToolExit(
message: '$kAppFlavor is used by the framework and cannot be set in the environment.',
),
);
},
overrides: <Type, Generator>{
DeviceManager:
() => FakeDeviceManager()..attachedDevices = <Device>[FakeDevice('name', 'id')],
FileSystem: () {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('lib/main.dart').createSync(recursive: true);
fileSystem.file('pubspec.yaml').createSync();
return fileSystem;
},
ProcessManager: FakeProcessManager.empty,
Platform: () => FakePlatform()..environment = <String, String>{kAppFlavor: 'AlreadySet'},
},
);

testUsingContext(
'tool exits when $kAppFlavor is set in --dart-define',
() async {
final CommandRunner<void> runner = createTestCommandRunner(
_TestRunCommandThatOnlyValidates(),
);
expect(
runner.run(<String>[
'run',
'--dart-define=$kAppFlavor=AlreadySet',
'--no-pub',
'--no-hot',
]),
throwsToolExit(
message: '$kAppFlavor is used by the framework and cannot be set using --dart-define',
),
);
},
overrides: <Type, Generator>{
DeviceManager:
() => FakeDeviceManager()..attachedDevices = <Device>[FakeDevice('name', 'id')],
FileSystem: () {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('lib/main.dart').createSync(recursive: true);
fileSystem.file('pubspec.yaml').createSync();
return fileSystem;
},
ProcessManager: FakeProcessManager.empty,
},
);

testUsingContext(
'tool exits when $kAppFlavor is set in --dart-define-from-file',
() async {
final CommandRunner<void> runner = createTestCommandRunner(
_TestRunCommandThatOnlyValidates(),
);
expect(
runner.run(<String>[
'run',
'--dart-define-from-file=config.json',
'--no-pub',
'--no-hot',
]),
throwsToolExit(
message: '$kAppFlavor is used by the framework and cannot be set using --dart-define',
),
);
},
overrides: <Type, Generator>{
DeviceManager:
() => FakeDeviceManager()..attachedDevices = <Device>[FakeDevice('name', 'id')],
FileSystem: () {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('lib/main.dart').createSync(recursive: true);
fileSystem.file('pubspec.yaml').createSync();
fileSystem.file('config.json')
..createSync()
..writeAsStringSync('{"$kAppFlavor": "AlreadySet"}');
return fileSystem;
},
ProcessManager: FakeProcessManager.empty,
},
);

group('Flutter version', () {
for (final String dartDefine in FlutterCommand.flutterVersionDartDefines) {
testUsingContext(
Expand Down
Loading