mirror of
https://github.com/flutter/packages.git
synced 2025-06-18 21:19:48 +08:00
[tool] Update tool to set macOS deployment target to 10.15. (#6605)
This commit is contained in:

committed by
GitHub

parent
fc3e2b1d1e
commit
60ffcafcd5
@ -6,22 +6,30 @@ import 'dart:io' as io;
|
|||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
import 'package:platform/platform.dart';
|
||||||
import 'package:pub_semver/pub_semver.dart';
|
import 'package:pub_semver/pub_semver.dart';
|
||||||
import 'package:pubspec_parse/pubspec_parse.dart';
|
import 'package:pubspec_parse/pubspec_parse.dart';
|
||||||
|
|
||||||
import 'common/core.dart';
|
import 'common/core.dart';
|
||||||
import 'common/package_command.dart';
|
import 'common/package_command.dart';
|
||||||
|
import 'common/process_runner.dart';
|
||||||
import 'common/repository_package.dart';
|
import 'common/repository_package.dart';
|
||||||
|
|
||||||
const String _outputDirectoryFlag = 'output-dir';
|
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.
|
/// A command to create an application that builds all in a single application.
|
||||||
class CreateAllPluginsAppCommand extends PackageCommand {
|
class CreateAllPluginsAppCommand extends PackageCommand {
|
||||||
/// Creates an instance of the builder command.
|
/// Creates an instance of the builder command.
|
||||||
CreateAllPluginsAppCommand(
|
CreateAllPluginsAppCommand(
|
||||||
Directory packagesDir, {
|
Directory packagesDir, {
|
||||||
|
ProcessRunner processRunner = const ProcessRunner(),
|
||||||
Directory? pluginsRoot,
|
Directory? pluginsRoot,
|
||||||
}) : super(packagesDir) {
|
Platform platform = const LocalPlatform(),
|
||||||
|
}) : super(packagesDir, processRunner: processRunner, platform: platform) {
|
||||||
final Directory defaultDir =
|
final Directory defaultDir =
|
||||||
pluginsRoot ?? packagesDir.fileSystem.currentDirectory;
|
pluginsRoot ?? packagesDir.fileSystem.currentDirectory;
|
||||||
argParser.addOption(_outputDirectoryFlag,
|
argParser.addOption(_outputDirectoryFlag,
|
||||||
@ -61,10 +69,28 @@ class CreateAllPluginsAppCommand extends PackageCommand {
|
|||||||
print('');
|
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>>[
|
await Future.wait(<Future<void>>[
|
||||||
_genPubspecWithAllPlugins(),
|
|
||||||
_updateAppGradle(),
|
_updateAppGradle(),
|
||||||
_updateManifest(),
|
_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(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,4 +285,61 @@ dev_dependencies:${_pubspecMapString(pubspec.devDependencies)}
|
|||||||
|
|
||||||
return buffer.toString();
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,12 @@ import 'dart:io' as io;
|
|||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
import 'package:file/local.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:flutter_plugin_tools/src/create_all_plugins_app_command.dart';
|
||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import 'mocks.dart';
|
||||||
import 'util.dart';
|
import 'util.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -20,6 +22,7 @@ void main() {
|
|||||||
late FileSystem fileSystem;
|
late FileSystem fileSystem;
|
||||||
late Directory testRoot;
|
late Directory testRoot;
|
||||||
late Directory packagesDir;
|
late Directory packagesDir;
|
||||||
|
late RecordingProcessRunner processRunner;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
// Since the core of this command is a call to 'flutter create', the test
|
// Since the core of this command is a call to 'flutter create', the test
|
||||||
@ -28,9 +31,11 @@ void main() {
|
|||||||
fileSystem = const LocalFileSystem();
|
fileSystem = const LocalFileSystem();
|
||||||
testRoot = fileSystem.systemTempDirectory.createTempSync();
|
testRoot = fileSystem.systemTempDirectory.createTempSync();
|
||||||
packagesDir = testRoot.childDirectory('packages');
|
packagesDir = testRoot.childDirectory('packages');
|
||||||
|
processRunner = RecordingProcessRunner();
|
||||||
|
|
||||||
command = CreateAllPluginsAppCommand(
|
command = CreateAllPluginsAppCommand(
|
||||||
packagesDir,
|
packagesDir,
|
||||||
|
processRunner: processRunner,
|
||||||
pluginsRoot: testRoot,
|
pluginsRoot: testRoot,
|
||||||
);
|
);
|
||||||
runner = CommandRunner<void>(
|
runner = CommandRunner<void>(
|
||||||
@ -103,6 +108,91 @@ void main() {
|
|||||||
baselinePubspec.environment?[dartSdkKey]);
|
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 {
|
test('handles --output-dir', () async {
|
||||||
createFakePlugin('plugina', packagesDir);
|
createFakePlugin('plugina', packagesDir);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user