Detect ARM ffi CocoaPods error, suggest gem install (#70801)
This commit is contained in:
parent
ef4741540b
commit
37f4f1f281
@ -135,6 +135,7 @@ Future<T> runInContext<T>(
|
||||
platform: globals.platform,
|
||||
xcodeProjectInterpreter: globals.xcodeProjectInterpreter,
|
||||
artifacts: globals.artifacts,
|
||||
usage: globals.flutterUsage,
|
||||
),
|
||||
CocoaPodsValidator: () => CocoaPodsValidator(
|
||||
globals.cocoaPods,
|
||||
|
@ -12,6 +12,7 @@ import '../base/error_handling_io.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/io.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../base/os.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/process.dart';
|
||||
import '../base/version.dart';
|
||||
@ -19,6 +20,7 @@ import '../build_info.dart';
|
||||
import '../cache.dart';
|
||||
import '../ios/xcodeproj.dart';
|
||||
import '../project.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
|
||||
const String noCocoaPodsConsequence = '''
|
||||
CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
|
||||
@ -82,23 +84,33 @@ class CocoaPods {
|
||||
@required Logger logger,
|
||||
@required Platform platform,
|
||||
@required Artifacts artifacts,
|
||||
@required Usage usage,
|
||||
}) : _fileSystem = fileSystem,
|
||||
_processManager = processManager,
|
||||
_xcodeProjectInterpreter = xcodeProjectInterpreter,
|
||||
_logger = logger,
|
||||
_platform = platform,
|
||||
_artifacts = artifacts,
|
||||
_usage = usage,
|
||||
_processUtils = ProcessUtils(processManager: processManager, logger: logger),
|
||||
_fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform);
|
||||
_fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform),
|
||||
_operatingSystemUtils = OperatingSystemUtils(
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
platform: platform,
|
||||
processManager: processManager,
|
||||
);
|
||||
|
||||
final FileSystem _fileSystem;
|
||||
final ProcessManager _processManager;
|
||||
final FileSystemUtils _fileSystemUtils;
|
||||
final ProcessUtils _processUtils;
|
||||
final OperatingSystemUtils _operatingSystemUtils;
|
||||
final XcodeProjectInterpreter _xcodeProjectInterpreter;
|
||||
final Logger _logger;
|
||||
final Platform _platform;
|
||||
final Artifacts _artifacts;
|
||||
final Usage _usage;
|
||||
|
||||
Future<String> _versionText;
|
||||
|
||||
@ -370,14 +382,31 @@ class CocoaPods {
|
||||
}
|
||||
|
||||
void _diagnosePodInstallFailure(ProcessResult result) {
|
||||
final dynamic stdout = result.stdout;
|
||||
if (stdout is String && stdout.contains('out-of-date source repos')) {
|
||||
if (result.stdout is! String) {
|
||||
return;
|
||||
}
|
||||
final String stdout = result.stdout as String;
|
||||
if (stdout.contains('out-of-date source repos')) {
|
||||
_logger.printError(
|
||||
"Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.\n"
|
||||
'To update the CocoaPods specs, run:\n'
|
||||
' pod repo update\n',
|
||||
emphasis: true,
|
||||
);
|
||||
} else if (stdout.contains('Init_ffi_c') &&
|
||||
stdout.contains('symbol not found') &&
|
||||
_operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm) {
|
||||
// https://github.com/flutter/flutter/issues/70796
|
||||
UsageEvent(
|
||||
'pod-install-failure',
|
||||
'arm-ffi',
|
||||
flutterUsage: _usage,
|
||||
).send();
|
||||
_logger.printError(
|
||||
'Error: To set up CocoaPods for ARM macOS, run:\n'
|
||||
' arch -x86_64 sudo gem install ffi\n',
|
||||
emphasis: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||
import 'package:flutter_tools/src/macos/cocoapods.dart';
|
||||
import 'package:flutter_tools/src/plugins.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
@ -32,6 +33,7 @@ void main() {
|
||||
CocoaPods cocoaPodsUnderTest;
|
||||
InvokeProcess resultOfPodVersion;
|
||||
BufferLogger logger;
|
||||
Usage usage;
|
||||
|
||||
void pretendPodVersionFails() {
|
||||
resultOfPodVersion = () async => exitsWithError();
|
||||
@ -68,15 +70,17 @@ void main() {
|
||||
projectUnderTest = FlutterProject.fromDirectory(fileSystem.directory('project'));
|
||||
projectUnderTest.ios.xcodeProject.createSync(recursive: true);
|
||||
projectUnderTest.macos.xcodeProject.createSync(recursive: true);
|
||||
usage = Usage.test();
|
||||
cocoaPodsUnderTest = CocoaPods(
|
||||
fileSystem: fileSystem,
|
||||
processManager: mockProcessManager,
|
||||
logger: logger,
|
||||
platform: FakePlatform(),
|
||||
platform: FakePlatform(operatingSystem: 'macos'),
|
||||
artifacts: Artifacts.test(),
|
||||
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
|
||||
usage: usage,
|
||||
);
|
||||
pretendPodVersionIs('1.8.0');
|
||||
pretendPodVersionIs('1.9.0');
|
||||
fileSystem.file(fileSystem.path.join(
|
||||
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-objc',
|
||||
))
|
||||
@ -450,6 +454,79 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
|
||||
}
|
||||
});
|
||||
|
||||
testWithoutContext('ffi failure on ARM macOS prompts gem install', () async {
|
||||
pretendPodIsInstalled();
|
||||
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
|
||||
..createSync()
|
||||
..writeAsStringSync('Existing Podfile');
|
||||
|
||||
when(mockProcessManager.runSync(<String>['sysctl', 'hw.optional.arm64']))
|
||||
.thenReturn(ProcessResult(0, 0, 'hw.optional.arm64: 1', ''));
|
||||
|
||||
when(mockProcessManager.run(
|
||||
<String>['pod', 'install', '--verbose'],
|
||||
workingDirectory: 'project/ios',
|
||||
environment: <String, String>{
|
||||
'COCOAPODS_DISABLE_STATS': 'true',
|
||||
'LANG': 'en_US.UTF-8',
|
||||
},
|
||||
)).thenAnswer((_) async => exitsWithError(
|
||||
'LoadError - dlsym(0x7fbbeb6837d0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle',
|
||||
));
|
||||
|
||||
// Capture Usage.test() events.
|
||||
final StringBuffer buffer =
|
||||
await capturedConsolePrint(() => expectToolExitLater(
|
||||
cocoaPodsUnderTest.processPods(
|
||||
xcodeProject: projectUnderTest.ios,
|
||||
buildMode: BuildMode.debug,
|
||||
),
|
||||
equals('Error running pod install'),
|
||||
));
|
||||
expect(
|
||||
logger.errorText,
|
||||
contains('set up CocoaPods for ARM macOS'),
|
||||
);
|
||||
expect(buffer.toString(),
|
||||
contains('event {category: pod-install-failure, action: arm-ffi'));
|
||||
});
|
||||
|
||||
testWithoutContext('ffi failure on x86 macOS does not prompt gem install', () async {
|
||||
pretendPodIsInstalled();
|
||||
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
|
||||
..createSync()
|
||||
..writeAsStringSync('Existing Podfile');
|
||||
|
||||
when(mockProcessManager.runSync(<String>['sysctl', 'hw.optional.arm64']))
|
||||
.thenReturn(ProcessResult(0, 1, '', ''));
|
||||
|
||||
when(mockProcessManager.run(
|
||||
<String>['pod', 'install', '--verbose'],
|
||||
workingDirectory: 'project/ios',
|
||||
environment: <String, String>{
|
||||
'COCOAPODS_DISABLE_STATS': 'true',
|
||||
'LANG': 'en_US.UTF-8',
|
||||
},
|
||||
)).thenAnswer((_) async => exitsWithError(
|
||||
'LoadError - dlsym(0x7fbbeb6837d0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle',
|
||||
));
|
||||
|
||||
// Capture Usage.test() events.
|
||||
final StringBuffer buffer =
|
||||
await capturedConsolePrint(() => expectToolExitLater(
|
||||
cocoaPodsUnderTest.processPods(
|
||||
xcodeProject: projectUnderTest.ios,
|
||||
buildMode: BuildMode.debug,
|
||||
),
|
||||
equals('Error running pod install'),
|
||||
));
|
||||
expect(
|
||||
logger.errorText,
|
||||
isNot(contains('ARM macOS')),
|
||||
);
|
||||
expect(buffer.isEmpty, true);
|
||||
});
|
||||
|
||||
testWithoutContext('run pod install, if Podfile.lock is missing', () async {
|
||||
pretendPodIsInstalled();
|
||||
projectUnderTest.ios.podfile
|
||||
|
Loading…
x
Reference in New Issue
Block a user