Move macOS Podfile logic into the tool (#72020)
This commit is contained in:
parent
9ec1601c46
commit
1c18cf3da8
@ -9,71 +9,32 @@ project 'Runner', {
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def parse_KV_file(file, separator='=')
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return [];
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||
end
|
||||
pods_ary = []
|
||||
skip_line_start_symbols = ["#", "/"]
|
||||
File.foreach(file_abs_path) { |line|
|
||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||
plugin = line.split(pattern=separator)
|
||||
if plugin.length == 2
|
||||
podname = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
podpath = File.expand_path("#{path}", file_abs_path)
|
||||
pods_ary.push({:name => podname, :path => podpath});
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
}
|
||||
return pods_ary
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||
end
|
||||
|
||||
def pubspec_supports_macos(file)
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return false;
|
||||
end
|
||||
File.foreach(file_abs_path) { |line|
|
||||
return true if line =~ /^\s*macos:/
|
||||
}
|
||||
return false
|
||||
end
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_macos_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
ephemeral_dir = File.join('Flutter', 'ephemeral')
|
||||
symlink_dir = File.join(ephemeral_dir, '.symlinks')
|
||||
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
|
||||
system("rm -rf #{symlink_dir}")
|
||||
system("mkdir -p #{symlink_plugins_dir}")
|
||||
|
||||
# Flutter Pods
|
||||
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
|
||||
if generated_xcconfig.empty?
|
||||
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
|
||||
end
|
||||
generated_xcconfig.map { |p|
|
||||
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
|
||||
symlink = File.join(symlink_dir, 'flutter')
|
||||
File.symlink(File.dirname(p[:path]), symlink)
|
||||
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
|
||||
end
|
||||
}
|
||||
|
||||
# Plugin Pods
|
||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
plugin_pods.map { |p|
|
||||
symlink = File.join(symlink_plugins_dir, p[:name])
|
||||
File.symlink(p[:path], symlink)
|
||||
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
|
||||
pod p[:name], :path => File.join(symlink, 'macos')
|
||||
end
|
||||
}
|
||||
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_macos_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
@ -415,7 +415,7 @@ void _validateIosPodfile(String appPath) {
|
||||
|| !podfileLockOutput.contains(':path: ".symlinks/plugins/test_plugin_objc/ios"')
|
||||
|| !podfileLockOutput.contains(':path: ".symlinks/plugins/test_plugin_swift/ios"')
|
||||
|| podfileLockOutput.contains('url_launcher_macos')) {
|
||||
throw TaskResult.failure('Podfile.lock does not contain expected pods');
|
||||
throw TaskResult.failure('iOS Podfile.lock does not contain expected pods');
|
||||
}
|
||||
|
||||
checkDirectoryNotExists(path.join(
|
||||
@ -445,6 +445,11 @@ void _validateIosPodfile(String appPath) {
|
||||
'ios',
|
||||
));
|
||||
|
||||
checkDirectoryNotExists(path.join(
|
||||
pluginSymlinks,
|
||||
'url_launcher_macos',
|
||||
));
|
||||
|
||||
checkDirectoryExists(path.join(
|
||||
pluginSymlinks,
|
||||
'test_plugin_objc',
|
||||
@ -463,12 +468,21 @@ void _validateMacOSPodfile(String appPath) {
|
||||
|
||||
final File podfileLockFile = File(path.join(appPath, 'macos', 'Podfile.lock'));
|
||||
final String podfileLockOutput = podfileLockFile.readAsStringSync();
|
||||
if (!podfileLockOutput.contains(':path: Flutter/ephemeral/.symlinks/flutter/darwin-x64-release')
|
||||
if (!podfileLockOutput.contains(':path: Flutter/ephemeral\n')
|
||||
|| !podfileLockOutput.contains(':path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos')
|
||||
|| !podfileLockOutput.contains(':path: Flutter/ephemeral/.symlinks/plugins/test_plugin_swift/macos')) {
|
||||
throw TaskResult.failure('Podfile.lock does not contain expected pods');
|
||||
|| !podfileLockOutput.contains(':path: Flutter/ephemeral/.symlinks/plugins/test_plugin_swift/macos')
|
||||
|| podfileLockOutput.contains('url_launcher/')) {
|
||||
throw TaskResult.failure('macOS Podfile.lock does not contain expected pods');
|
||||
}
|
||||
|
||||
checkFileExists(path.join(
|
||||
appPath,
|
||||
'macos',
|
||||
'Flutter',
|
||||
'ephemeral',
|
||||
'FlutterMacOS.podspec',
|
||||
));
|
||||
|
||||
final String pluginSymlinks = path.join(
|
||||
appPath,
|
||||
'macos',
|
||||
@ -484,6 +498,11 @@ void _validateMacOSPodfile(String appPath) {
|
||||
'macos',
|
||||
));
|
||||
|
||||
checkDirectoryNotExists(path.join(
|
||||
pluginSymlinks,
|
||||
'url_launcher',
|
||||
));
|
||||
|
||||
checkDirectoryExists(path.join(
|
||||
pluginSymlinks,
|
||||
'test_plugin_swift',
|
||||
|
@ -9,71 +9,32 @@ project 'Runner', {
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def parse_KV_file(file, separator='=')
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return [];
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||
end
|
||||
pods_ary = []
|
||||
skip_line_start_symbols = ["#", "/"]
|
||||
File.foreach(file_abs_path) { |line|
|
||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||
plugin = line.split(pattern=separator)
|
||||
if plugin.length == 2
|
||||
podname = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
podpath = File.expand_path("#{path}", file_abs_path)
|
||||
pods_ary.push({:name => podname, :path => podpath});
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
}
|
||||
return pods_ary
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||
end
|
||||
|
||||
def pubspec_supports_macos(file)
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return false;
|
||||
end
|
||||
File.foreach(file_abs_path) { |line|
|
||||
return true if line =~ /^\s*macos:/
|
||||
}
|
||||
return false
|
||||
end
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_macos_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
ephemeral_dir = File.join('Flutter', 'ephemeral')
|
||||
symlink_dir = File.join(ephemeral_dir, '.symlinks')
|
||||
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
|
||||
system("rm -rf #{symlink_dir}")
|
||||
system("mkdir -p #{symlink_plugins_dir}")
|
||||
|
||||
# Flutter Pods
|
||||
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
|
||||
if generated_xcconfig.empty?
|
||||
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
|
||||
end
|
||||
generated_xcconfig.map { |p|
|
||||
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
|
||||
symlink = File.join(symlink_dir, 'flutter')
|
||||
File.symlink(File.dirname(p[:path]), symlink)
|
||||
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
|
||||
end
|
||||
}
|
||||
|
||||
# Plugin Pods
|
||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
plugin_pods.map { |p|
|
||||
symlink = File.join(symlink_plugins_dir, p[:name])
|
||||
File.symlink(p[:path], symlink)
|
||||
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
|
||||
pod p[:name], :path => File.join(symlink, 'macos')
|
||||
end
|
||||
}
|
||||
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_macos_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
@ -17,6 +17,10 @@ require 'json'
|
||||
def flutter_ios_podfile_setup
|
||||
end
|
||||
|
||||
# Same as flutter_ios_podfile_setup for macOS.
|
||||
def flutter_macos_podfile_setup
|
||||
end
|
||||
|
||||
# Add iOS build settings to pod targets.
|
||||
#
|
||||
# @example
|
||||
@ -67,6 +71,24 @@ def flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
||||
# Same as flutter_ios_podfile_setup for macOS.
|
||||
def flutter_additional_macos_build_settings(target)
|
||||
print target.platform_name
|
||||
return unless target.platform_name == :osx
|
||||
|
||||
# This podhelper script is at $FLUTTER_ROOT/packages/flutter_tools/bin.
|
||||
# Add search paths from $FLUTTER_ROOT/bin/cache/artifacts/engine.
|
||||
artifacts_dir = File.join('..', '..', '..', '..', 'bin', 'cache', 'artifacts', 'engine')
|
||||
debug_framework_dir = File.expand_path(File.join(artifacts_dir, 'darwin-x64'), __FILE__)
|
||||
release_framework_dir = File.expand_path(File.join(artifacts_dir, 'darwin-x64-release'), __FILE__)
|
||||
|
||||
target.build_configurations.each do |build_configuration|
|
||||
# Profile can't be derived from the CocoaPods build configuration. Use release framework (for linking only).
|
||||
configuration_engine_dir = build_configuration.type == :debug ? debug_framework_dir : release_framework_dir
|
||||
build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] = "\"#{configuration_engine_dir}\" $(inherited)"
|
||||
end
|
||||
end
|
||||
|
||||
# Install pods needed to embed Flutter iOS engine and plugins.
|
||||
#
|
||||
# @example
|
||||
@ -77,7 +99,13 @@ end
|
||||
# Optional, defaults to the Podfile directory.
|
||||
def flutter_install_all_ios_pods(ios_application_path = nil)
|
||||
flutter_install_ios_engine_pod(ios_application_path)
|
||||
flutter_install_ios_plugin_pods(ios_application_path)
|
||||
flutter_install_plugin_pods(ios_application_path, '.symlinks', 'ios')
|
||||
end
|
||||
|
||||
# Same as flutter_install_all_ios_pods for macOS.
|
||||
def flutter_install_all_macos_pods(macos_application_path = nil)
|
||||
flutter_install_macos_engine_pod(macos_application_path)
|
||||
flutter_install_plugin_pods(macos_application_path, File.join('Flutter', 'ephemeral', '.symlinks'), 'macos')
|
||||
end
|
||||
|
||||
# Install iOS Flutter engine pod.
|
||||
@ -125,30 +153,64 @@ def flutter_install_ios_engine_pod(ios_application_path = nil)
|
||||
pod 'Flutter', :path => 'Flutter'
|
||||
end
|
||||
|
||||
# Install iOS Flutter plugin pods.
|
||||
#
|
||||
# @example
|
||||
# target 'Runner' do
|
||||
# flutter_install_ios_plugin_pods
|
||||
# end
|
||||
# @param [String] ios_application_path Path of the iOS directory of the Flutter app.
|
||||
# Optional, defaults to the Podfile directory.
|
||||
def flutter_install_ios_plugin_pods(ios_application_path = nil)
|
||||
# Same as flutter_install_ios_engine_pod for macOS.
|
||||
def flutter_install_macos_engine_pod(mac_application_path = nil)
|
||||
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
|
||||
ios_application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
|
||||
raise 'Could not find iOS application path' unless ios_application_path
|
||||
mac_application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
|
||||
raise 'Could not find macOS application path' unless mac_application_path
|
||||
|
||||
copied_podspec_path = File.expand_path('FlutterMacOS.podspec', File.join(mac_application_path, 'Flutter', 'ephemeral'))
|
||||
|
||||
# Generate a fake podspec to represent the FlutterMacOS framework.
|
||||
# This is only necessary because plugin podspecs contain `s.dependency 'FlutterMacOS'`, and if this Podfile
|
||||
# does not add a `pod 'FlutterMacOS'` CocoaPods will try to download it from the CoocaPods trunk.
|
||||
File.open(copied_podspec_path, 'w') { |podspec|
|
||||
podspec.write <<~EOF
|
||||
#
|
||||
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
||||
# This is a generated file; do not edit or check into version control.
|
||||
#
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'FlutterMacOS'
|
||||
s.version = '1.0.0'
|
||||
s.summary = 'High-performance, high-fidelity mobile apps.'
|
||||
s.homepage = 'https://flutter.io'
|
||||
s.license = { :type => 'MIT' }
|
||||
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
||||
s.osx.deployment_target = '10.11'
|
||||
# Framework linking is handled by Flutter tooling, not CocoaPods.
|
||||
# Add a placeholder to satisfy `s.dependency 'FlutterMacOS'` plugin podspecs.
|
||||
s.vendored_frameworks = 'path/to/nothing'
|
||||
end
|
||||
EOF
|
||||
}
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod 'FlutterMacOS', :path => File.join('Flutter', 'ephemeral')
|
||||
end
|
||||
|
||||
# Install Flutter plugin pods.
|
||||
#
|
||||
# @param [String] application_path Path of the directory of the Flutter app.
|
||||
# Optional, defaults to the Podfile directory.
|
||||
def flutter_install_plugin_pods(application_path = nil, relative_symlink_dir, platform)
|
||||
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
|
||||
application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
|
||||
raise 'Could not find application path' unless application_path
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
|
||||
symlink_dir = File.expand_path('.symlinks', ios_application_path)
|
||||
symlink_dir = File.expand_path(relative_symlink_dir, application_path)
|
||||
system('rm', '-rf', symlink_dir) # Avoid the complication of dependencies like FileUtils.
|
||||
|
||||
symlink_plugins_dir = File.expand_path('plugins', symlink_dir)
|
||||
system('mkdir', '-p', symlink_plugins_dir)
|
||||
|
||||
plugins_file = File.join(ios_application_path, '..', '.flutter-plugins-dependencies')
|
||||
plugin_pods = flutter_parse_plugins_file(plugins_file)
|
||||
plugins_file = File.join(application_path, '..', '.flutter-plugins-dependencies')
|
||||
plugin_pods = flutter_parse_plugins_file(plugins_file, platform)
|
||||
plugin_pods.each do |plugin_hash|
|
||||
plugin_name = plugin_hash['name']
|
||||
plugin_path = plugin_hash['path']
|
||||
@ -157,14 +219,14 @@ def flutter_install_ios_plugin_pods(ios_application_path = nil)
|
||||
File.symlink(plugin_path, symlink)
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod plugin_name, :path => File.join('.symlinks', 'plugins', plugin_name, 'ios')
|
||||
pod plugin_name, :path => File.join(relative_symlink_dir, 'plugins', plugin_name, platform)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# .flutter-plugins-dependencies format documented at
|
||||
# https://flutter.dev/go/plugins-list-migration
|
||||
def flutter_parse_plugins_file(file)
|
||||
def flutter_parse_plugins_file(file, platform)
|
||||
file_path = File.expand_path(file)
|
||||
return [] unless File.exists? file_path
|
||||
|
||||
@ -174,5 +236,5 @@ def flutter_parse_plugins_file(file)
|
||||
# dependencies_hash.dig('plugins', 'ios') not available until Ruby 2.3
|
||||
return [] unless dependencies_hash.has_key?('plugins')
|
||||
return [] unless dependencies_hash['plugins'].has_key?('ios')
|
||||
dependencies_hash['plugins']['ios'] || []
|
||||
dependencies_hash['plugins'][platform] || []
|
||||
end
|
||||
|
@ -136,7 +136,6 @@ Future<T> runInContext<T>(
|
||||
logger: globals.logger,
|
||||
platform: globals.platform,
|
||||
xcodeProjectInterpreter: globals.xcodeProjectInterpreter,
|
||||
artifacts: globals.artifacts,
|
||||
usage: globals.flutterUsage,
|
||||
),
|
||||
CocoaPodsValidator: () => CocoaPodsValidator(
|
||||
|
@ -181,17 +181,6 @@ List<String> _xcodeBuildSettingsLines({
|
||||
xcodeBuildSettings.add('SYMROOT=\${SOURCE_ROOT}/../${getIosBuildDirectory()}');
|
||||
}
|
||||
|
||||
if (!project.isModule && useMacOSConfig) {
|
||||
// For module projects we do not want to write the FLUTTER_FRAMEWORK_DIR
|
||||
// explicitly. Rather we rely on the xcode backend script and the Podfile
|
||||
// logic to derive it from FLUTTER_ROOT and FLUTTER_BUILD_MODE.
|
||||
// However, this is necessary for regular macOS projects using Cocoapods.
|
||||
final String frameworkDir =
|
||||
flutterMacOSFrameworkDir(buildInfo.mode, globals.fs, globals.artifacts);
|
||||
xcodeBuildSettings.add('FLUTTER_FRAMEWORK_DIR=$frameworkDir');
|
||||
}
|
||||
|
||||
|
||||
final String buildName = parsedBuildName(manifest: project.manifest, buildInfo: buildInfo) ?? '1.0.0';
|
||||
xcodeBuildSettings.add('FLUTTER_BUILD_NAME=$buildName');
|
||||
|
||||
|
@ -6,7 +6,6 @@ import 'package:file/file.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/error_handling_io.dart';
|
||||
import '../base/file_system.dart';
|
||||
@ -41,15 +40,18 @@ const String outOfDateFrameworksPodfileConsequence = '''
|
||||
If you have local Podfile edits you would like to keep, see https://github.com/flutter/flutter/issues/24641 for instructions.''';
|
||||
|
||||
const String outOfDatePluginsPodfileConsequence = '''
|
||||
This can cause issues if your application depends on plugins that do not support iOS.
|
||||
This can cause issues if your application depends on plugins that do not support iOS or macOS.
|
||||
See https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms for details.
|
||||
If you have local Podfile edits you would like to keep, see https://github.com/flutter/flutter/issues/45197 for instructions.''';
|
||||
|
||||
const String cocoaPodsInstallInstructions = 'see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.';
|
||||
|
||||
const String podfileMigrationInstructions = '''
|
||||
const String podfileIosMigrationInstructions = '''
|
||||
rm ios/Podfile''';
|
||||
|
||||
const String podfileMacOSMigrationInstructions = '''
|
||||
rm macos/Podfile''';
|
||||
|
||||
/// Result of evaluating the CocoaPods installation.
|
||||
enum CocoaPodsStatus {
|
||||
/// iOS plugins will not work, installation required.
|
||||
@ -83,13 +85,11 @@ class CocoaPods {
|
||||
@required XcodeProjectInterpreter xcodeProjectInterpreter,
|
||||
@required Logger logger,
|
||||
@required Platform platform,
|
||||
@required Artifacts artifacts,
|
||||
@required Usage usage,
|
||||
}) : _fileSystem = fileSystem,
|
||||
_processManager = processManager,
|
||||
_xcodeProjectInterpreter = xcodeProjectInterpreter,
|
||||
_logger = logger,
|
||||
_artifacts = artifacts,
|
||||
_usage = usage,
|
||||
_processUtils = ProcessUtils(processManager: processManager, logger: logger),
|
||||
_operatingSystemUtils = OperatingSystemUtils(
|
||||
@ -105,7 +105,6 @@ class CocoaPods {
|
||||
final OperatingSystemUtils _operatingSystemUtils;
|
||||
final XcodeProjectInterpreter _xcodeProjectInterpreter;
|
||||
final Logger _logger;
|
||||
final Artifacts _artifacts;
|
||||
final Usage _usage;
|
||||
|
||||
Future<String> _versionText;
|
||||
@ -314,10 +313,6 @@ class CocoaPods {
|
||||
<String>['pod', 'install', '--verbose'],
|
||||
workingDirectory: _fileSystem.path.dirname(xcodeProject.podfile.path),
|
||||
environment: <String, String>{
|
||||
// For macOS Podfile only.
|
||||
if (xcodeProject is MacOSProject)
|
||||
'FLUTTER_FRAMEWORK_DIR':
|
||||
flutterMacOSFrameworkDir(buildMode, _fileSystem, _artifacts),
|
||||
// See https://github.com/flutter/flutter/issues/10873.
|
||||
// CocoaPods analytics adds a lot of latency.
|
||||
'COCOAPODS_DISABLE_STATS': 'true',
|
||||
@ -374,29 +369,28 @@ class CocoaPods {
|
||||
}
|
||||
|
||||
void _warnIfPodfileOutOfDate(XcodeBasedProject xcodeProject) {
|
||||
if (xcodeProject is! IosProject) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Previously, the Podfile created a symlink to the cached artifacts engine framework
|
||||
// and installed the Flutter pod from that path. This could get out of sync with the copy
|
||||
// of the Flutter engine that was copied to ios/Flutter by the xcode_backend script.
|
||||
// It was possible for the symlink to point to a Debug version of the engine when the
|
||||
// Xcode build configuration was Release, which caused App Store submission rejections.
|
||||
//
|
||||
// Warn the user if they are still symlinking to the framework.
|
||||
final Link flutterSymlink = _fileSystem.link(_fileSystem.path.join(
|
||||
(xcodeProject as IosProject).symlinks.path,
|
||||
'flutter',
|
||||
));
|
||||
if (flutterSymlink.existsSync()) {
|
||||
throwToolExit(
|
||||
'Warning: Podfile is out of date\n'
|
||||
'$outOfDateFrameworksPodfileConsequence\n'
|
||||
'To regenerate the Podfile, run:\n'
|
||||
'$podfileMigrationInstructions\n',
|
||||
);
|
||||
return;
|
||||
final bool isIos = xcodeProject is IosProject;
|
||||
if (isIos) {
|
||||
// Previously, the Podfile created a symlink to the cached artifacts engine framework
|
||||
// and installed the Flutter pod from that path. This could get out of sync with the copy
|
||||
// of the Flutter engine that was copied to ios/Flutter by the xcode_backend script.
|
||||
// It was possible for the symlink to point to a Debug version of the engine when the
|
||||
// Xcode build configuration was Release, which caused App Store submission rejections.
|
||||
//
|
||||
// Warn the user if they are still symlinking to the framework.
|
||||
final Link flutterSymlink = _fileSystem.link(_fileSystem.path.join(
|
||||
(xcodeProject as IosProject).symlinks.path,
|
||||
'flutter',
|
||||
));
|
||||
if (flutterSymlink.existsSync()) {
|
||||
throwToolExit(
|
||||
'Warning: Podfile is out of date\n'
|
||||
'$outOfDateFrameworksPodfileConsequence\n'
|
||||
'To regenerate the Podfile, run:\n'
|
||||
'$podfileIosMigrationInstructions\n',
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Most of the pod and plugin parsing logic was moved from the Podfile
|
||||
// into the tool's podhelper.rb script. If the Podfile still references
|
||||
@ -404,12 +398,16 @@ class CocoaPods {
|
||||
// plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
if (xcodeProject.podfile.existsSync() &&
|
||||
xcodeProject.podfile.readAsStringSync().contains('.flutter-plugins\'')) {
|
||||
throwToolExit(
|
||||
'Warning: Podfile is out of date\n'
|
||||
'$outOfDatePluginsPodfileConsequence\n'
|
||||
'To regenerate the Podfile, run:\n'
|
||||
'$podfileMigrationInstructions\n',
|
||||
);
|
||||
const String error = 'Warning: Podfile is out of date\n'
|
||||
'$outOfDatePluginsPodfileConsequence\n'
|
||||
'To regenerate the Podfile, run:\n';
|
||||
if (isIos) {
|
||||
throwToolExit('$error\n$podfileIosMigrationInstructions\n');
|
||||
} else {
|
||||
// The old macOS Podfile will work until `.flutter-plugins` is removed.
|
||||
// Warn instead of exit.
|
||||
_logger.printError('$error\n$podfileMacOSMigrationInstructions\n', emphasis: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,71 +9,32 @@ project 'Runner', {
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def parse_KV_file(file, separator='=')
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return [];
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||
end
|
||||
pods_ary = []
|
||||
skip_line_start_symbols = ["#", "/"]
|
||||
File.foreach(file_abs_path) { |line|
|
||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||
plugin = line.split(pattern=separator)
|
||||
if plugin.length == 2
|
||||
podname = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
podpath = File.expand_path("#{path}", file_abs_path)
|
||||
pods_ary.push({:name => podname, :path => podpath});
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
}
|
||||
return pods_ary
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||
end
|
||||
|
||||
def pubspec_supports_macos(file)
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return false;
|
||||
end
|
||||
File.foreach(file_abs_path) { |line|
|
||||
return true if line =~ /^\s*macos:/
|
||||
}
|
||||
return false
|
||||
end
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_macos_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
ephemeral_dir = File.join('Flutter', 'ephemeral')
|
||||
symlink_dir = File.join(ephemeral_dir, '.symlinks')
|
||||
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
|
||||
system("rm -rf #{symlink_dir}")
|
||||
system("mkdir -p #{symlink_plugins_dir}")
|
||||
|
||||
# Flutter Pods
|
||||
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
|
||||
if generated_xcconfig.empty?
|
||||
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
|
||||
end
|
||||
generated_xcconfig.map { |p|
|
||||
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
|
||||
symlink = File.join(symlink_dir, 'flutter')
|
||||
File.symlink(File.dirname(p[:path]), symlink)
|
||||
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
|
||||
end
|
||||
}
|
||||
|
||||
# Plugin Pods
|
||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
plugin_pods.map { |p|
|
||||
symlink = File.join(symlink_plugins_dir, p[:name])
|
||||
File.symlink(p[:path], symlink)
|
||||
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
|
||||
pod p[:name], :path => File.join(symlink, 'macos')
|
||||
end
|
||||
}
|
||||
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_macos_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
@ -260,7 +260,6 @@ void main() {
|
||||
'DART_OBFUSCATION=true',
|
||||
'EXTRA_FRONT_END_OPTIONS=--enable-experiment%3Dnon-nullable',
|
||||
'EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment%3Dnon-nullable',
|
||||
'FLUTTER_FRAMEWORK_DIR=.',
|
||||
'SPLIT_DEBUG_INFO=foo/',
|
||||
'TRACK_WIDGET_CREATION=true',
|
||||
'TREE_SHAKE_ICONS=true',
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
@ -76,7 +75,6 @@ void main() {
|
||||
processManager: mockProcessManager,
|
||||
logger: logger,
|
||||
platform: FakePlatform(operatingSystem: 'macos'),
|
||||
artifacts: Artifacts.test(),
|
||||
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
|
||||
usage: usage,
|
||||
);
|
||||
@ -109,7 +107,7 @@ void main() {
|
||||
when(mockProcessManager.run(
|
||||
<String>['pod', 'install', '--verbose'],
|
||||
workingDirectory: 'project/macos',
|
||||
environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': '.', 'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
|
||||
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
|
||||
)).thenAnswer((_) async => exitsHappy());
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
});
|
||||
@ -373,7 +371,7 @@ void main() {
|
||||
), throwsToolExit(message: 'Podfile is out of date'));
|
||||
});
|
||||
|
||||
testWithoutContext('exits if Podfile parses .flutter-plugins', () async {
|
||||
testWithoutContext('exits if iOS Podfile parses .flutter-plugins', () async {
|
||||
pretendPodIsInstalled();
|
||||
|
||||
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
|
||||
@ -386,6 +384,22 @@ void main() {
|
||||
), throwsToolExit(message: 'Podfile is out of date'));
|
||||
});
|
||||
|
||||
testWithoutContext('prints warning if macOS Podfile parses .flutter-plugins', () async {
|
||||
pretendPodIsInstalled();
|
||||
|
||||
fileSystem.file(fileSystem.path.join('project', 'macos', 'Podfile'))
|
||||
..createSync()
|
||||
..writeAsStringSync('plugin_pods = parse_KV_file(\'../.flutter-plugins\')');
|
||||
|
||||
await cocoaPodsUnderTest.processPods(
|
||||
xcodeProject: projectUnderTest.macos,
|
||||
buildMode: BuildMode.debug,
|
||||
);
|
||||
|
||||
expect(logger.errorText, contains('Warning: Podfile is out of date'));
|
||||
expect(logger.errorText, contains('rm macos/Podfile'));
|
||||
});
|
||||
|
||||
testWithoutContext('throws, if Podfile is missing.', () async {
|
||||
pretendPodIsInstalled();
|
||||
try {
|
||||
@ -588,7 +602,6 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
|
||||
<String>['pod', 'install', '--verbose'],
|
||||
workingDirectory: 'project/macos',
|
||||
environment: <String, String>{
|
||||
'FLUTTER_FRAMEWORK_DIR': '.',
|
||||
'COCOAPODS_DISABLE_STATS': 'true',
|
||||
'LANG': 'en_US.UTF-8',
|
||||
},
|
||||
|
@ -41,10 +41,7 @@ void main() {
|
||||
|
||||
// Config is updated if command succeeded.
|
||||
expect(generatedConfig, exists);
|
||||
expect(generatedConfig.readAsStringSync(), allOf(
|
||||
contains('DART_OBFUSCATION=true'),
|
||||
isNot(contains('FLUTTER_FRAMEWORK_DIR')),
|
||||
));
|
||||
expect(generatedConfig.readAsStringSync(), contains('DART_OBFUSCATION=true'));
|
||||
|
||||
// file that only exists if app was fully built.
|
||||
final File frameworkPlist = fileSystem.file(
|
||||
|
Loading…
x
Reference in New Issue
Block a user