Remove Finder extended attributes from iOS project files (#54488)
This commit is contained in:
parent
f646e26e90
commit
ddf63a8b05
@ -105,6 +105,8 @@ Future<XcodeBuildResult> buildXcodeProject({
|
||||
return XcodeBuildResult(success: false);
|
||||
}
|
||||
|
||||
await removeFinderExtendedAttributes(app.project.hostAppRoot, processUtils, globals.logger);
|
||||
|
||||
final XcodeProjectInfo projectInfo = await globals.xcodeProjectInterpreter.getInfo(app.project.hostAppRoot.path);
|
||||
if (!projectInfo.targets.contains('Runner')) {
|
||||
globals.printError('The Xcode project does not define target "Runner" which is needed by Flutter tooling.');
|
||||
@ -405,6 +407,25 @@ Future<XcodeBuildResult> buildXcodeProject({
|
||||
}
|
||||
}
|
||||
|
||||
/// Extended attributes applied by Finder can cause code signing errors. Remove them.
|
||||
/// https://developer.apple.com/library/archive/qa/qa1940/_index.html
|
||||
@visibleForTesting
|
||||
Future<void> removeFinderExtendedAttributes(Directory iosProjectDirectory, ProcessUtils processUtils, Logger logger) async {
|
||||
final bool success = await processUtils.exitsHappy(
|
||||
<String>[
|
||||
'xattr',
|
||||
'-r',
|
||||
'-d',
|
||||
'com.apple.FinderInfo',
|
||||
iosProjectDirectory.path,
|
||||
]
|
||||
);
|
||||
// Ignore all errors, for example if directory is missing.
|
||||
if (!success) {
|
||||
logger.printTrace('Failed to remove xattr com.apple.FinderInfo from ${iosProjectDirectory.path}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<RunResult> _runBuildWithRetries(List<String> buildCommands, BuildableIOSApp app) async {
|
||||
int buildRetryDelaySeconds = 1;
|
||||
int remainingTries = 8;
|
||||
|
@ -22,6 +22,16 @@ import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/fake_process_manager.dart';
|
||||
|
||||
List<String> _xattrArgs(FlutterProject flutterProject) {
|
||||
return <String>[
|
||||
'xattr',
|
||||
'-r',
|
||||
'-d',
|
||||
'com.apple.FinderInfo',
|
||||
flutterProject.ios.hostAppRoot.path,
|
||||
];
|
||||
}
|
||||
|
||||
const List<String> kRunReleaseArgs = <String>[
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
@ -74,6 +84,7 @@ void main() {
|
||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
||||
|
||||
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
|
||||
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
|
||||
processManager.addCommand(const FakeCommand(command: <String>[...kRunReleaseArgs, '-showBuildSettings']));
|
||||
processManager.addCommand(FakeCommand(
|
||||
@ -123,6 +134,7 @@ void main() {
|
||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
||||
|
||||
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
|
||||
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
|
||||
// The first showBuildSettings call should timeout.
|
||||
processManager.addCommand(
|
||||
@ -194,6 +206,7 @@ void main() {
|
||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
||||
|
||||
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
|
||||
// The first xcrun call should fail with a
|
||||
// concurrent build exception.
|
||||
processManager.addCommand(
|
||||
|
@ -5,10 +5,12 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart' show ProcessResult;
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/process.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/ios/mac.dart';
|
||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||
@ -428,6 +430,46 @@ Exited (sigterm)''',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('remove Finder extended attributes', () {
|
||||
Directory iosProjectDirectory;
|
||||
setUp(() {
|
||||
final MemoryFileSystem fs = MemoryFileSystem.test();
|
||||
iosProjectDirectory = fs.directory('ios');
|
||||
});
|
||||
|
||||
testWithoutContext('removes xattr', () async {
|
||||
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
'xattr',
|
||||
'-r',
|
||||
'-d',
|
||||
'com.apple.FinderInfo',
|
||||
iosProjectDirectory.path,
|
||||
])
|
||||
]);
|
||||
|
||||
await removeFinderExtendedAttributes(iosProjectDirectory, ProcessUtils(processManager: processManager, logger: logger), logger);
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
});
|
||||
|
||||
testWithoutContext('ignores errors', () async {
|
||||
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
'xattr',
|
||||
'-r',
|
||||
'-d',
|
||||
'com.apple.FinderInfo',
|
||||
iosProjectDirectory.path,
|
||||
], exitCode: 1,
|
||||
)
|
||||
]);
|
||||
|
||||
await removeFinderExtendedAttributes(iosProjectDirectory, ProcessUtils(processManager: processManager, logger: logger), logger);
|
||||
expect(logger.traceText, contains('Failed to remove xattr com.apple.FinderInfo'));
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockUsage extends Mock implements Usage {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user