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);
|
return XcodeBuildResult(success: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await removeFinderExtendedAttributes(app.project.hostAppRoot, processUtils, globals.logger);
|
||||||
|
|
||||||
final XcodeProjectInfo projectInfo = await globals.xcodeProjectInterpreter.getInfo(app.project.hostAppRoot.path);
|
final XcodeProjectInfo projectInfo = await globals.xcodeProjectInterpreter.getInfo(app.project.hostAppRoot.path);
|
||||||
if (!projectInfo.targets.contains('Runner')) {
|
if (!projectInfo.targets.contains('Runner')) {
|
||||||
globals.printError('The Xcode project does not define target "Runner" which is needed by Flutter tooling.');
|
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 {
|
Future<RunResult> _runBuildWithRetries(List<String> buildCommands, BuildableIOSApp app) async {
|
||||||
int buildRetryDelaySeconds = 1;
|
int buildRetryDelaySeconds = 1;
|
||||||
int remainingTries = 8;
|
int remainingTries = 8;
|
||||||
|
@ -22,6 +22,16 @@ import '../../src/common.dart';
|
|||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
import '../../src/fake_process_manager.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>[
|
const List<String> kRunReleaseArgs = <String>[
|
||||||
'/usr/bin/env',
|
'/usr/bin/env',
|
||||||
'xcrun',
|
'xcrun',
|
||||||
@ -74,6 +84,7 @@ void main() {
|
|||||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||||
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
||||||
|
|
||||||
|
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
|
||||||
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
|
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
|
||||||
processManager.addCommand(const FakeCommand(command: <String>[...kRunReleaseArgs, '-showBuildSettings']));
|
processManager.addCommand(const FakeCommand(command: <String>[...kRunReleaseArgs, '-showBuildSettings']));
|
||||||
processManager.addCommand(FakeCommand(
|
processManager.addCommand(FakeCommand(
|
||||||
@ -123,6 +134,7 @@ void main() {
|
|||||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||||
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
||||||
|
|
||||||
|
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
|
||||||
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
|
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
|
||||||
// The first showBuildSettings call should timeout.
|
// The first showBuildSettings call should timeout.
|
||||||
processManager.addCommand(
|
processManager.addCommand(
|
||||||
@ -194,6 +206,7 @@ void main() {
|
|||||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||||
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter');
|
||||||
|
|
||||||
|
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
|
||||||
// The first xcrun call should fail with a
|
// The first xcrun call should fail with a
|
||||||
// concurrent build exception.
|
// concurrent build exception.
|
||||||
processManager.addCommand(
|
processManager.addCommand(
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
|
import 'package:file/memory.dart';
|
||||||
import 'package:flutter_tools/src/artifacts.dart';
|
import 'package:flutter_tools/src/artifacts.dart';
|
||||||
import 'package:flutter_tools/src/base/file_system.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/io.dart' show ProcessResult;
|
||||||
import 'package:flutter_tools/src/base/logger.dart';
|
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/cache.dart';
|
||||||
import 'package:flutter_tools/src/ios/mac.dart';
|
import 'package:flutter_tools/src/ios/mac.dart';
|
||||||
import 'package:flutter_tools/src/ios/xcodeproj.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 {}
|
class MockUsage extends Mock implements Usage {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user