Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 10 additions & 10 deletions dev/devicelab/bin/tasks/module_test_ios.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ dependencies:
});

await inDirectory(projectDir, () async {
await flutter('pub', options: <String>['get']);
await flutter('build', options: <String>['ios', '--config-only']);
});

section('Add to existing iOS Objective-C app');
Expand All @@ -275,7 +275,13 @@ dependencies:
section('Validate iOS Objective-C host app Podfile');

final File podfile = File(path.join(objectiveCHostApp.path, 'Podfile'));
String podfileContent = await podfile.readAsString();
final String correctPodfileContents = await podfile.readAsString();
final File podfileMissingPostInstall = File(
path.join(objectiveCHostApp.path, 'PodfileMissingPostInstall'),
);

podfile.writeAsStringSync(podfileMissingPostInstall.readAsStringSync());

final String podFailure = await eval(
'pod',
<String>['install'],
Expand All @@ -289,18 +295,12 @@ dependencies:
!podFailure.contains(
'Add `flutter_post_install(installer)` to your Podfile `post_install` block to build Flutter plugins',
)) {
print(podfileContent);
print(podfile.readAsStringSync());
throw TaskResult.failure(
'pod install unexpectedly succeed without "flutter_post_install" post_install block',
);
}
podfileContent = '''
$podfileContent

post_install do |installer|
flutter_post_install(installer)
end
''';
String podfileContent = correctPodfileContents;
await podfile.writeAsString(podfileContent, flush: true);

await exec(
Expand Down
4 changes: 4 additions & 0 deletions dev/integration_tests/ios_host_app/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ end
target 'FlutterUITests' do
inherit! :search_paths
end

post_install do |installer|
flutter_post_install(installer)
end
12 changes: 12 additions & 0 deletions dev/integration_tests/ios_host_app/PodfileMissingPostInstall
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
platform :ios, '13.0'

flutter_application_path = '../hello'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')

target 'Host' do
install_all_flutter_pods flutter_application_path
end

target 'FlutterUITests' do
inherit! :search_paths
end
50 changes: 49 additions & 1 deletion packages/flutter_tools/bin/xcode_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ class Context {

final String buildMode = parseFlutterBuildMode();

_validateBuildMode(platform, buildMode);

final List<String> flutterArgs = _generateFlutterArgsForAssemble(
command: 'build',
buildMode: buildMode,
Expand Down Expand Up @@ -534,6 +536,53 @@ class Context {
echo('Project $projectPath built and packaged successfully.');
}

/// Validate that the build mode targeted matches the build mode set by the
/// Flutter CLI.
/// If it doesn't match, print a warning unless the Xcode action is `install`,
/// which means the app is being archived for distribution. In that case, print
/// an error and fail the build.
///
/// The targeted build mode might not match the one set by Flutter CLI when it
/// is changed and ran directly through Xcode.
///
/// Flutter may change settings or files depending on the build mode. For
/// example, dev dependencies are excluded from release builds and requires
/// the Flutter CLI to update certain files.
void _validateBuildMode(TargetPlatform platform, String currentBuildMode) {
final String? buildModeCLILastUsed = environment['FLUTTER_CLI_BUILD_MODE'];

// Also fail the build if ACTION=install, which indicates the app is being
// built for distribution.
final String? action = environment['ACTION'];
final bool fatal = action == 'install';

if (buildModeCLILastUsed == null) {
final String message =
'Your Flutter build settings are outdated. Please run '
'"flutter build ${platform.name} --config-only --$currentBuildMode" in your Flutter '
'project and try again.\n';
if (fatal) {
echoXcodeError(message);
exitApp(-1);
} else {
echoXcodeWarning(message);
return;
}
}
if (currentBuildMode != buildModeCLILastUsed) {
final String message =
'Your Flutter project is currently configured for $buildModeCLILastUsed mode. '
'Please run `flutter build ${platform.name} --config-only --$currentBuildMode` '
'in your Flutter project to update your settings.\n';
if (fatal) {
echoXcodeError(message);
exitApp(-1);
} else {
echoXcodeWarning(message);
}
}
}

List<String> _generateFlutterArgsForAssemble({
required String command,
required String buildMode,
Expand Down Expand Up @@ -626,7 +675,6 @@ class Context {
'--DartDefines=${environment['DART_DEFINES'] ?? ''}',
'--ExtraFrontEndOptions=${environment['EXTRA_FRONT_END_OPTIONS'] ?? ''}',
'-dSrcRoot=${environment['SRCROOT'] ?? ''}',
'-dDevDependenciesEnabled=${environment['FLUTTER_DEV_DEPENDENCIES_ENABLED'] ?? ''}',
]);

if (platform == TargetPlatform.ios) {
Expand Down
3 changes: 0 additions & 3 deletions packages/flutter_tools/lib/src/build_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -999,9 +999,6 @@ const String kXcodeAction = 'Action';
/// to the BUILT_PRODUCTS_DIR prior to the build.
const String kXcodePreAction = 'PreBuildAction';

// Whether the last Flutter tool invocation enabled dev dependencies.
const String kDevDependenciesEnabled = 'DevDependenciesEnabled';

final Converter<String, String> _defineEncoder = utf8.encoder.fuse(base64.encoder);
final Converter<String, String> _defineDecoder = base64.decoder.fuse(utf8.decoder);

Expand Down
146 changes: 0 additions & 146 deletions packages/flutter_tools/lib/src/build_system/targets/darwin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,155 +5,9 @@
import 'package:meta/meta.dart';

import '../../artifacts.dart';
import '../../base/common.dart';
import '../../base/file_system.dart';
import '../../base/io.dart';
import '../../build_info.dart';
import '../../flutter_plugins.dart';
import '../../globals.dart' as globals;
import '../../project.dart';
import '../build_system.dart';
import '../exceptions.dart';

/// A target that checks that dev dependencies are enabled on debug/profile
/// builds and disabled on release builds.
///
/// The Flutter tool enables/disables dev dependencies using the build mode.
/// These can get out of sync if the user switches the build mode in Xcode.
///
/// Implementers should override [CheckDevDependencies.inputs] to add a [Source]
/// that changes when dev dependencies status changes.
abstract class CheckDevDependencies extends Target {
const CheckDevDependencies();

@override
List<Target> get dependencies => <Target>[];

@override
List<Source> get inputs => <Source>[
const Source.pattern(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/darwin.dart',
),
Source.fromProject((FlutterProject project) => project.flutterPluginsDependenciesFile),
];

@override
List<Source> get outputs => const <Source>[];

// The command that turns on dev dependencies.
// Displayed in the error message if dev dependencies are off in a debug build.
@visibleForOverriding
String get debugBuildCommand;

// The command that turns on dev dependencies.
// Displayed in the error message if dev dependencies are off in a profile build.
@visibleForOverriding
String get profileBuildCommand;

// The command that turns off dev dependencies.
// Displayed in the error message if dev dependencies are off in a release build.
@visibleForOverriding
String get releaseBuildCommand;

// Check that dev dependencies are enabled on debug or profile builds and
// disabled on release builds.
//
// The Flutter tool enables/disables dev dependencies using the build mode.
// These can get out of sync if the user switches the build mode in Xcode.
@override
Future<void> build(Environment environment) async {
final String? buildModeEnvironment = environment.defines[kBuildMode];
if (buildModeEnvironment == null) {
throw MissingDefineException(kBuildMode, name);
}
final BuildMode buildMode = BuildMode.fromCliName(buildModeEnvironment);
final String? devDependenciesEnabledString = environment.defines[kDevDependenciesEnabled];
if (devDependenciesEnabledString == null) {
throw MissingDefineException(kDevDependenciesEnabled, name);
}

final bool? devDependenciesEnabled = bool.tryParse(
environment.defines[kDevDependenciesEnabled] ?? '',
);
if (devDependenciesEnabled == null) {
throw Exception(
'Unexpected $kDevDependenciesEnabled define value: "$devDependenciesEnabledString"',
);
}

if (devDependenciesEnabled && buildMode.isRelease) {
// Supress this error if the project has no dev dependencies.
if (!_hasDevDependencies(environment)) {
environment.logger.printTrace(
'Ignoring dev dependencies error as the project has no dev dependencies',
);
return;
}

_printXcodeError(
'Release builds should not have Dart dev dependencies enabled\n'
'\n'
'This error happens if:\n'
'\n'
'1. Your pubspec.yaml has dev dependencies\n'
'2. Your last Flutter CLI action turned on dev dependencies\n'
'3. You do a release build in Xcode\n'
'\n'
'You can turn off Dart dev dependencies by running this in your Flutter project:\n'
'\n'
' $releaseBuildCommand\n'
'\n',
);
throwToolExit('Dev dependencies enabled in release build');
} else if (!devDependenciesEnabled && !buildMode.isRelease) {
// Supress this error if the project has no dev dependencies.
if (!_hasDevDependencies(environment)) {
environment.logger.printTrace(
'Ignoring dev dependencies error as the project has no dev dependencies',
);
return;
}

final bool profile = buildMode == BuildMode.profile;
_printXcodeError(
'${profile ? 'Profile' : 'Debug'} builds require Dart dev dependencies\n'
'\n'
'This error happens if:\n'
'\n'
'1. Your pubspec.yaml has dev dependencies\n'
'2. Your last Flutter CLI action turned off dev dependencies\n'
'3. You do a debug or profile build in Xcode\n'
'\n'
'You can turn on Dart dev dependencies by running this in your Flutter project:\n'
'\n'
' ${profile ? profileBuildCommand : debugBuildCommand}\n'
'\n',
);
throwToolExit('Dev dependencies disabled in ${profile ? 'profile' : 'debug'} build');
}
}

// Check if the iOS project has Dart dev dependencies. On error, assumes true.
bool _hasDevDependencies(Environment environment) {
// If the app has no plugins, the .flutter-plugins-dependencies file isn't generated.
final FlutterProject project = FlutterProject.fromDirectory(environment.projectDir);
final File pluginsFile = project.flutterPluginsDependenciesFile;
if (!pluginsFile.existsSync()) {
return false;
}

try {
return flutterPluginsListHasDevDependencies(pluginsFile);
} on Exception catch (e) {
environment.logger.printWarning('Unable to parse .flutter-plugins-dependencies file:\n$e');
return true;
}
}

void _printXcodeError(String message) {
globals.stdio.stderrWrite('error: $message');
}
}

abstract class UnpackDarwin extends Target {
const UnpackDarwin();
Expand Down
44 changes: 2 additions & 42 deletions packages/flutter_tools/lib/src/build_system/targets/ios.dart
Original file line number Diff line number Diff line change
Expand Up @@ -484,37 +484,6 @@ class DebugIosLLDBInit extends IosLLDBInit {
BuildMode get buildMode => BuildMode.debug;
}

class CheckDevDependenciesIos extends CheckDevDependencies {
const CheckDevDependenciesIos();

@override
String get name => 'check_dev_dependencies_ios';

@override
List<Source> get inputs {
return <Source>[
...super.inputs,
const Source.pattern(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/ios.dart',
),

// The generated Xcode properties file contains
// the FLUTTER_DEV_DEPENDENCIES_ENABLED configuration.
// This target should re-run whenever that value changes.
Source.fromProject((FlutterProject project) => project.ios.generatedXcodePropertiesFile),
];
}

@override
String get debugBuildCommand => 'flutter build ios --config-only --debug';

@override
String get profileBuildCommand => 'flutter build ios --config-only --profile';

@override
String get releaseBuildCommand => 'flutter build ios --config-only --release';
}

/// The base class for all iOS bundle targets.
///
/// This is responsible for setting up the basic App.framework structure, including:
Expand Down Expand Up @@ -667,7 +636,6 @@ class DebugIosApplicationBundle extends IosAssetBundle {

@override
List<Target> get dependencies => <Target>[
const CheckDevDependenciesIos(),
const DebugUniversalFramework(),
const DebugIosLLDBInit(),
...super.dependencies,
Expand Down Expand Up @@ -699,11 +667,7 @@ class ProfileIosApplicationBundle extends _IosAssetBundleWithDSYM {
String get name => 'profile_ios_bundle_flutter_assets';

@override
List<Target> get dependencies => const <Target>[
CheckDevDependenciesIos(),
AotAssemblyProfile(),
InstallCodeAssets(),
];
List<Target> get dependencies => const <Target>[AotAssemblyProfile(), InstallCodeAssets()];
}

/// Build a release iOS application bundle.
Expand All @@ -714,11 +678,7 @@ class ReleaseIosApplicationBundle extends _IosAssetBundleWithDSYM {
String get name => 'release_ios_bundle_flutter_assets';

@override
List<Target> get dependencies => const <Target>[
CheckDevDependenciesIos(),
AotAssemblyRelease(),
InstallCodeAssets(),
];
List<Target> get dependencies => const <Target>[AotAssemblyRelease(), InstallCodeAssets()];

@override
Future<void> build(Environment environment) async {
Expand Down
Loading