when getting xcworkspace, exclude hidden files (#114099)
* exclude xcworkspace that begins with a period * fix if spacing, add comment * add unit test for when no xcworkspace found * update to use xcodeWorkspace, make it nullable and refactor * check if hostAppRoot exists before trying to get xcworkspace * use local variables to take advantage of type promotion * only check if not null, don't need to check if exists * readd exist check for migrate * readd missing line at end of file
This commit is contained in:
parent
77c06c2ca4
commit
378387b139
@ -71,7 +71,8 @@ class CleanCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
Future<void> _cleanXcode(XcodeBasedProject xcodeProject) async {
|
||||
if (!xcodeProject.existsSync()) {
|
||||
final Directory? xcodeWorkspace = xcodeProject.xcodeWorkspace;
|
||||
if (xcodeWorkspace == null) {
|
||||
return;
|
||||
}
|
||||
final Status xcodeStatus = globals.logger.startProgress(
|
||||
@ -79,7 +80,6 @@ class CleanCommand extends FlutterCommand {
|
||||
);
|
||||
try {
|
||||
final XcodeProjectInterpreter xcodeProjectInterpreter = globals.xcodeProjectInterpreter!;
|
||||
final Directory xcodeWorkspace = xcodeProject.xcodeWorkspace;
|
||||
final XcodeProjectInfo projectInfo = (await xcodeProjectInterpreter.getInfo(xcodeWorkspace.parent.path))!;
|
||||
for (final String scheme in projectInfo.schemes) {
|
||||
await xcodeProjectInterpreter.cleanWorkspace(xcodeWorkspace.path, scheme, verbose: _verbose);
|
||||
|
@ -250,17 +250,14 @@ Future<XcodeBuildResult> buildXcodeProject({
|
||||
buildCommands.add('-allowProvisioningDeviceRegistration');
|
||||
}
|
||||
|
||||
final List<FileSystemEntity> contents = app.project.hostAppRoot.listSync();
|
||||
for (final FileSystemEntity entity in contents) {
|
||||
if (globals.fs.path.extension(entity.path) == '.xcworkspace') {
|
||||
final Directory? workspacePath = app.project.xcodeWorkspace;
|
||||
if (workspacePath != null) {
|
||||
buildCommands.addAll(<String>[
|
||||
'-workspace', globals.fs.path.basename(entity.path),
|
||||
'-workspace', workspacePath.basename,
|
||||
'-scheme', scheme,
|
||||
if (buildAction != XcodeBuildAction.archive) // dSYM files aren't copied to the archive if BUILD_DIR is set.
|
||||
'BUILD_DIR=${globals.fs.path.absolute(getIosBuildDirectory())}',
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the project contains a watchOS companion app.
|
||||
|
@ -15,16 +15,17 @@ class XcodeBuildSystemMigration extends ProjectMigrator {
|
||||
super.logger,
|
||||
) : _xcodeWorkspaceSharedSettings = project.xcodeWorkspaceSharedSettings;
|
||||
|
||||
final File _xcodeWorkspaceSharedSettings;
|
||||
final File? _xcodeWorkspaceSharedSettings;
|
||||
|
||||
@override
|
||||
void migrate() {
|
||||
if (!_xcodeWorkspaceSharedSettings.existsSync()) {
|
||||
final File? xcodeWorkspaceSharedSettings = _xcodeWorkspaceSharedSettings;
|
||||
if (xcodeWorkspaceSharedSettings == null || !xcodeWorkspaceSharedSettings.existsSync()) {
|
||||
logger.printTrace('Xcode workspace settings not found, skipping build system migration');
|
||||
return;
|
||||
}
|
||||
|
||||
final String contents = _xcodeWorkspaceSharedSettings.readAsStringSync();
|
||||
final String contents = xcodeWorkspaceSharedSettings.readAsStringSync();
|
||||
|
||||
// Only delete this file when it is pointing to the legacy build system.
|
||||
const String legacyBuildSettingsWorkspace = '''
|
||||
@ -33,8 +34,8 @@ class XcodeBuildSystemMigration extends ProjectMigrator {
|
||||
|
||||
// contains instead of equals to ignore newline file ending variance.
|
||||
if (contents.contains(legacyBuildSettingsWorkspace)) {
|
||||
logger.printStatus('Legacy build system detected, removing ${_xcodeWorkspaceSharedSettings.path}');
|
||||
_xcodeWorkspaceSharedSettings.deleteSync();
|
||||
logger.printStatus('Legacy build system detected, removing ${xcodeWorkspaceSharedSettings.path}');
|
||||
xcodeWorkspaceSharedSettings.deleteSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ Future<void> buildMacOS({
|
||||
required bool verboseLogging,
|
||||
SizeAnalyzer? sizeAnalyzer,
|
||||
}) async {
|
||||
if (!flutterProject.macos.xcodeWorkspace.existsSync()) {
|
||||
final Directory? xcodeWorkspace = flutterProject.macos.xcodeWorkspace;
|
||||
if (xcodeWorkspace == null) {
|
||||
throwToolExit('No macOS desktop project configured. '
|
||||
'See https://docs.flutter.dev/desktop#add-desktop-support-to-an-existing-flutter-app '
|
||||
'to learn about adding macOS support to a project.');
|
||||
@ -106,7 +107,7 @@ Future<void> buildMacOS({
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'xcodebuild',
|
||||
'-workspace', flutterProject.macos.xcodeWorkspace.path,
|
||||
'-workspace', xcodeWorkspace.path,
|
||||
'-configuration', configuration,
|
||||
'-scheme', 'Runner',
|
||||
'-derivedDataPath', flutterBuildDir.absolute.path,
|
||||
|
@ -47,13 +47,26 @@ abstract class XcodeBasedProject extends FlutterProjectPlatform {
|
||||
.childFile('contents.xcworkspacedata');
|
||||
|
||||
/// The Xcode workspace (.xcworkspace directory) of the host app.
|
||||
Directory get xcodeWorkspace => hostAppRoot.childDirectory('$_hostAppProjectName.xcworkspace');
|
||||
Directory? get xcodeWorkspace {
|
||||
if (!hostAppRoot.existsSync()) {
|
||||
return null;
|
||||
}
|
||||
final List<FileSystemEntity> contents = hostAppRoot.listSync();
|
||||
for (final FileSystemEntity entity in contents) {
|
||||
// On certain volume types, there is sometimes a stray `._Runner.xcworkspace` file.
|
||||
// Find the first non-hidden xcworkspace and return the directory.
|
||||
if (globals.fs.path.extension(entity.path) == '.xcworkspace' && !globals.fs.path.basename(entity.path).startsWith('.')) {
|
||||
return hostAppRoot.childDirectory(entity.basename);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Xcode workspace shared data directory for the host app.
|
||||
Directory get xcodeWorkspaceSharedData => xcodeWorkspace.childDirectory('xcshareddata');
|
||||
Directory? get xcodeWorkspaceSharedData => xcodeWorkspace?.childDirectory('xcshareddata');
|
||||
|
||||
/// Xcode workspace shared workspace settings file for the host app.
|
||||
File get xcodeWorkspaceSharedSettings => xcodeWorkspaceSharedData.childFile('WorkspaceSettings.xcsettings');
|
||||
File? get xcodeWorkspaceSharedSettings => xcodeWorkspaceSharedData?.childFile('WorkspaceSettings.xcsettings');
|
||||
|
||||
/// Contains definitions for FLUTTER_ROOT, LOCAL_ENGINE, and more flags for
|
||||
/// the Xcode build.
|
||||
|
@ -99,7 +99,7 @@ void main() {
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'xcodebuild',
|
||||
'-workspace', flutterProject.macos.xcodeWorkspace.path,
|
||||
'-workspace', flutterProject.macos.xcodeWorkspace!.path,
|
||||
'-configuration', configuration,
|
||||
'-scheme', 'Runner',
|
||||
'-derivedDataPath', flutterBuildDir.absolute.path,
|
||||
@ -337,6 +337,7 @@ STDERR STUFF
|
||||
|
||||
final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
|
||||
final Directory flutterBuildDir = fileSystem.directory(getMacOSBuildDirectory());
|
||||
createMinimalMockProjectFiles();
|
||||
|
||||
fakeProcessManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(
|
||||
@ -344,7 +345,7 @@ STDERR STUFF
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'xcodebuild',
|
||||
'-workspace', flutterProject.macos.xcodeWorkspace.path,
|
||||
'-workspace', flutterProject.macos.xcodeWorkspace!.path,
|
||||
'-configuration', 'Debug',
|
||||
'-scheme', 'Runner',
|
||||
'-derivedDataPath', flutterBuildDir.absolute.path,
|
||||
@ -359,7 +360,6 @@ STDERR STUFF
|
||||
]);
|
||||
|
||||
final BuildCommand command = BuildCommand();
|
||||
createMinimalMockProjectFiles();
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>['build', 'macos', '--debug', '--no-pub']
|
||||
|
@ -44,7 +44,7 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('$CleanCommand removes build and .dart_tool and ephemeral directories, cleans Xcode for iOS and macOS', () async {
|
||||
final FlutterProject projectUnderTest = setupProjectUnderTest(fs.currentDirectory);
|
||||
final FlutterProject projectUnderTest = setupProjectUnderTest(fs.currentDirectory, true);
|
||||
// Xcode is installed and version satisfactory.
|
||||
xcodeProjectInterpreter.isInstalled = true;
|
||||
xcodeProjectInterpreter.version = Version(1000, 0, 0);
|
||||
@ -81,8 +81,23 @@ void main() {
|
||||
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||
});
|
||||
|
||||
testUsingContext('$CleanCommand does not run when there is no xcworkspace', () async {
|
||||
setupProjectUnderTest(fs.currentDirectory, false);
|
||||
// Xcode is installed and version satisfactory.
|
||||
xcodeProjectInterpreter.isInstalled = true;
|
||||
xcodeProjectInterpreter.version = Version(1000, 0, 0);
|
||||
await CleanCommand().runCommand();
|
||||
|
||||
expect(xcodeProjectInterpreter.workspaces, const <CleanWorkspaceCall>[]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
Xcode: () => xcode,
|
||||
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||
});
|
||||
|
||||
testUsingContext('$CleanCommand cleans Xcode verbosely for iOS and macOS', () async {
|
||||
setupProjectUnderTest(fs.currentDirectory);
|
||||
setupProjectUnderTest(fs.currentDirectory, true);
|
||||
// Xcode is installed and version satisfactory.
|
||||
xcodeProjectInterpreter.isInstalled = true;
|
||||
xcodeProjectInterpreter.version = Version(1000, 0, 0);
|
||||
@ -154,12 +169,13 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
FlutterProject setupProjectUnderTest(Directory currentDirectory) {
|
||||
FlutterProject setupProjectUnderTest(Directory currentDirectory, bool setupXcodeWorkspace) {
|
||||
// This needs to be run within testWithoutContext and not setUp since FlutterProject uses context.
|
||||
final FlutterProject projectUnderTest = FlutterProject.fromDirectory(currentDirectory);
|
||||
projectUnderTest.ios.xcodeWorkspace.createSync(recursive: true);
|
||||
projectUnderTest.macos.xcodeWorkspace.createSync(recursive: true);
|
||||
|
||||
if (setupXcodeWorkspace == true) {
|
||||
projectUnderTest.ios.hostAppRoot.childDirectory('Runner.xcworkspace').createSync(recursive: true);
|
||||
projectUnderTest.macos.hostAppRoot.childDirectory('Runner.xcworkspace').createSync(recursive: true);
|
||||
}
|
||||
projectUnderTest.dartTool.createSync(recursive: true);
|
||||
projectUnderTest.packagesFile.createSync(recursive: true);
|
||||
projectUnderTest.android.ephemeralDirectory.createSync(recursive: true);
|
||||
|
@ -208,6 +208,20 @@ keep this 2
|
||||
expect(testLogger.statusText, isEmpty);
|
||||
});
|
||||
|
||||
testWithoutContext('skipped if _xcodeWorkspaceSharedSettings is null', () {
|
||||
final XcodeBuildSystemMigration iosProjectMigration = XcodeBuildSystemMigration(
|
||||
project,
|
||||
testLogger,
|
||||
);
|
||||
project.xcodeWorkspaceSharedSettings = null;
|
||||
|
||||
iosProjectMigration.migrate();
|
||||
expect(xcodeWorkspaceSharedSettings.existsSync(), isFalse);
|
||||
|
||||
expect(testLogger.traceText, contains('Xcode workspace settings not found, skipping build system migration'));
|
||||
expect(testLogger.statusText, isEmpty);
|
||||
});
|
||||
|
||||
testWithoutContext('skipped if nothing to upgrade', () {
|
||||
const String contents = '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@ -995,7 +1009,7 @@ class FakeIosProject extends Fake implements IosProject {
|
||||
File xcodeProjectWorkspaceData = MemoryFileSystem.test().file('xcodeProjectWorkspaceData');
|
||||
|
||||
@override
|
||||
File xcodeWorkspaceSharedSettings = MemoryFileSystem.test().file('xcodeWorkspaceSharedSettings');
|
||||
File? xcodeWorkspaceSharedSettings = MemoryFileSystem.test().file('xcodeWorkspaceSharedSettings');
|
||||
|
||||
@override
|
||||
File xcodeProjectInfoFile = MemoryFileSystem.test().file('xcodeProjectInfoFile');
|
||||
|
@ -350,6 +350,19 @@ void main() {
|
||||
expect(versionInfo['build_number'],'3');
|
||||
expect(versionInfo['package_name'],'test');
|
||||
});
|
||||
_testInMemory('gets xcworkspace directory', () async {
|
||||
final FlutterProject project = await someProject();
|
||||
project.ios.xcodeProject.createSync();
|
||||
project.ios.hostAppRoot.childFile('._Runner.xcworkspace').createSync(recursive: true);
|
||||
project.ios.hostAppRoot.childFile('Runner.xcworkspace').createSync(recursive: true);
|
||||
|
||||
expect(project.ios.xcodeWorkspace?.basename, 'Runner.xcworkspace');
|
||||
});
|
||||
_testInMemory('no xcworkspace directory found', () async {
|
||||
final FlutterProject project = await someProject();
|
||||
project.ios.xcodeProject.createSync();
|
||||
expect(project.ios.xcodeWorkspace?.basename, null);
|
||||
});
|
||||
});
|
||||
|
||||
group('module status', () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user