Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
[tool] Update tool to set macOS deployment target to 10.15. (#6605)
Browse files Browse the repository at this point in the history
  • Loading branch information
IVLIVS-III committed Oct 28, 2022
1 parent 2eb9a1b commit 6f91122
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 2 deletions.
87 changes: 85 additions & 2 deletions script/tool/lib/src/create_all_plugins_app_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,30 @@ import 'dart:io' as io;

import 'package:file/file.dart';
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';

import 'common/core.dart';
import 'common/package_command.dart';
import 'common/process_runner.dart';
import 'common/repository_package.dart';

const String _outputDirectoryFlag = 'output-dir';

const int _exitUpdateMacosPodfileFailed = 3;
const int _exitUpdateMacosPbxprojFailed = 4;
const int _exitGenNativeBuildFilesFailed = 5;

/// A command to create an application that builds all in a single application.
class CreateAllPluginsAppCommand extends PackageCommand {
/// Creates an instance of the builder command.
CreateAllPluginsAppCommand(
Directory packagesDir, {
ProcessRunner processRunner = const ProcessRunner(),
Directory? pluginsRoot,
}) : super(packagesDir) {
Platform platform = const LocalPlatform(),
}) : super(packagesDir, processRunner: processRunner, platform: platform) {
final Directory defaultDir =
pluginsRoot ?? packagesDir.fileSystem.currentDirectory;
argParser.addOption(_outputDirectoryFlag,
Expand Down Expand Up @@ -61,10 +69,28 @@ class CreateAllPluginsAppCommand extends PackageCommand {
print('');
}

await _genPubspecWithAllPlugins();

// Run `flutter pub get` to generate all native build files.
// TODO(stuartmorgan): This hangs on Windows for some reason. Since it's
// currently not needed on Windows, skip it there, but we should investigate
// further and/or implement https://github.com/flutter/flutter/issues/93407,
// and remove the need for this conditional.
if (!platform.isWindows) {
if (!await _genNativeBuildFiles()) {
printError(
"Failed to generate native build files via 'flutter pub get'");
throw ToolExit(_exitGenNativeBuildFilesFailed);
}
}

await Future.wait(<Future<void>>[
_genPubspecWithAllPlugins(),
_updateAppGradle(),
_updateManifest(),
_updateMacosPbxproj(),
// This step requires the native file generation triggered by
// flutter pub get above, so can't currently be run on Windows.
if (!platform.isWindows) _updateMacosPodfile(),
]);
}

Expand Down Expand Up @@ -259,4 +285,61 @@ dev_dependencies:${_pubspecMapString(pubspec.devDependencies)}

return buffer.toString();
}

Future<bool> _genNativeBuildFiles() async {
final int exitCode = await processRunner.runAndStream(
flutterCommand,
<String>['pub', 'get'],
workingDir: _appDirectory,
);
return exitCode == 0;
}

Future<void> _updateMacosPodfile() async {
/// Only change the macOS deployment target if the host platform is macOS.
/// The Podfile is not generated on other platforms.
if (!platform.isMacOS) {
return;
}

final File podfileFile =
app.platformDirectory(FlutterPlatform.macos).childFile('Podfile');
if (!podfileFile.existsSync()) {
printError("Can't find Podfile for macOS");
throw ToolExit(_exitUpdateMacosPodfileFailed);
}

final StringBuffer newPodfile = StringBuffer();
for (final String line in podfileFile.readAsLinesSync()) {
if (line.contains('platform :osx')) {
// macOS 10.15 is required by in_app_purchase.
newPodfile.writeln("platform :osx, '10.15'");
} else {
newPodfile.writeln(line);
}
}
podfileFile.writeAsStringSync(newPodfile.toString());
}

Future<void> _updateMacosPbxproj() async {
final File pbxprojFile = app
.platformDirectory(FlutterPlatform.macos)
.childDirectory('Runner.xcodeproj')
.childFile('project.pbxproj');
if (!pbxprojFile.existsSync()) {
printError("Can't find project.pbxproj for macOS");
throw ToolExit(_exitUpdateMacosPbxprojFailed);
}

final StringBuffer newPbxproj = StringBuffer();
for (final String line in pbxprojFile.readAsLinesSync()) {
if (line.contains('MACOSX_DEPLOYMENT_TARGET')) {
// macOS 10.15 is required by in_app_purchase.
newPbxproj.writeln(' MACOSX_DEPLOYMENT_TARGET = 10.15;');
} else {
newPbxproj.writeln(line);
}
}
pbxprojFile.writeAsStringSync(newPbxproj.toString());
}
}
90 changes: 90 additions & 0 deletions script/tool/test/create_all_plugins_app_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import 'dart:io' as io;
import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/create_all_plugins_app_command.dart';
import 'package:platform/platform.dart';
import 'package:test/test.dart';

import 'mocks.dart';
import 'util.dart';

void main() {
Expand All @@ -20,6 +22,7 @@ void main() {
late FileSystem fileSystem;
late Directory testRoot;
late Directory packagesDir;
late RecordingProcessRunner processRunner;

setUp(() {
// Since the core of this command is a call to 'flutter create', the test
Expand All @@ -28,9 +31,11 @@ void main() {
fileSystem = const LocalFileSystem();
testRoot = fileSystem.systemTempDirectory.createTempSync();
packagesDir = testRoot.childDirectory('packages');
processRunner = RecordingProcessRunner();

command = CreateAllPluginsAppCommand(
packagesDir,
processRunner: processRunner,
pluginsRoot: testRoot,
);
runner = CommandRunner<void>(
Expand Down Expand Up @@ -103,6 +108,91 @@ void main() {
baselinePubspec.environment?[dartSdkKey]);
});

test('macOS deployment target is modified in Podfile', () async {
createFakePlugin('plugina', packagesDir);

final File podfileFile = command.packagesDir.parent
.childDirectory('all_plugins')
.childDirectory('macos')
.childFile('Podfile');
podfileFile.createSync(recursive: true);
podfileFile.writeAsStringSync("""
platform :osx, '10.11'
# some other line
""");

await runCapturingPrint(runner, <String>['all-plugins-app']);
final List<String> podfile = command.app
.platformDirectory(FlutterPlatform.macos)
.childFile('Podfile')
.readAsLinesSync();

expect(
podfile,
everyElement((String line) =>
!line.contains('platform :osx') || line.contains("'10.15'")));
},
// Podfile is only generated (and thus only edited) on macOS.
skip: !io.Platform.isMacOS);

test('macOS deployment target is modified in pbxproj', () async {
createFakePlugin('plugina', packagesDir);

await runCapturingPrint(runner, <String>['all-plugins-app']);
final List<String> pbxproj = command.app
.platformDirectory(FlutterPlatform.macos)
.childDirectory('Runner.xcodeproj')
.childFile('project.pbxproj')
.readAsLinesSync();

expect(
pbxproj,
everyElement((String line) =>
!line.contains('MACOSX_DEPLOYMENT_TARGET') ||
line.contains('10.15')));
});

test('calls flutter pub get', () async {
createFakePlugin('plugina', packagesDir);

await runCapturingPrint(runner, <String>['all-plugins-app']);

expect(
processRunner.recordedCalls,
orderedEquals(<ProcessCall>[
ProcessCall(
getFlutterCommand(const LocalPlatform()),
const <String>['pub', 'get'],
testRoot.childDirectory('all_plugins').path),
]));
},
// See comment about Windows in create_all_plugins_app_command.dart
skip: io.Platform.isWindows);

test('fails if flutter pub get fails', () async {
createFakePlugin('plugina', packagesDir);

processRunner.mockProcessesForExecutable[
getFlutterCommand(const LocalPlatform())] = <io.Process>[
MockProcess(exitCode: 1)
];
Error? commandError;
final List<String> output = await runCapturingPrint(
runner, <String>['all-plugins-app'], errorHandler: (Error e) {
commandError = e;
});

expect(commandError, isA<ToolExit>());
expect(
output,
containsAllInOrder(<Matcher>[
contains(
"Failed to generate native build files via 'flutter pub get'"),
]));
},
// See comment about Windows in create_all_plugins_app_command.dart
skip: io.Platform.isWindows);

test('handles --output-dir', () async {
createFakePlugin('plugina', packagesDir);

Expand Down

0 comments on commit 6f91122

Please sign in to comment.