mirror of
https://github.com/flutter/packages.git
synced 2026-03-13 10:40:37 +08:00
Implements approach E.1b from [the design doc](https://flutter.dev/go/google-maps-spm-versioning) about SwiftPM support. The main changes are: - Adds a new `google_maps_flutter_ios_shared_code` directory which has an exact copy of almost all of the code files from `google_maps_flutter_ios`. - Adds a new `tool` directory to `google_maps_flutter_ios` (and the shared code, so that it stays in sync) with two command scripts: - `run_tests.dart`, which is automatically run by existing repo tool logic, as part of the custom tests task. This validates that for every file in `google_maps_flutter_ios_shared_code`, the corresponding file in `google_maps_flutter_ios` is identical (modulo some expected package name differences in specific cases). It lists all the files checked, to allow for easy auditing in CI output or locally about what is being shared. - `sync_shared_files.dart`, which is a helper script for local use that copies all files in the current package that have changes relative to their shared code counterparts, both to the shared copy and all other copies. This is to make the local development process less painful; for most changes, all someone has to do is work in one of the packages, and then run this script when they are done to sync those changes to all the other copies. It also logs any code files that aren't shared, to remind people adding files to take the step of adding those to the shared copy if they should be shared. - Adds two new duplicates of `google_maps_flutter_ios`, `..._sdk9` and `..._sdk10'` which are direct copies of `google_maps_ios` with very minor changes: - Anything based on the package name is changed/renamed - The podspecs are narrowed to use the relevant dependency versions and have the correct min iOS version for that SDK - Swift.package entries are added, making the packages SwiftPM-compatible - The CHANGELOGs are cleared. - The READMEs are updated to explain each package's role/behavior. There are some minor supporting changes: - The `google_maps_flutter_ios` README has been adjusted to reflect the new set of options. - Obj-C code using the Google Maps Utils package has been updated to handle differences in the package name for Obj-C (adapted from https://github.com/flutter/packages/pull/8288). I created a trampoline header to deal with this difference rather than inline the `#if` and explanation in each file. - Dart test code has been updated to use a non-shared trampoline header to localize the import diffs due to different package names to a tiny non-shared file. (We could switch this to using the file rewriting logic that I ended up having to add to `sync_shared_files.dart` later; I left it this way to minimize the number of files we have to do rewriting in, but I'm fine with either option.) - The Pigeon configuration forces a specific package name instead of auto-determining it. Pigeon currently uses the package name as part of the channel name for each call, so doing this avoids tons of unnecessary diff in the generated files. (This does mean that the different implementation packages are all using the same channel names, but that should be safe since `flutter` should only allow one of the implementations to be registered.) Once this lands and the new packages are published, I will do a follow-up PR to add a `google_maps_flutter` README discussion of how and why to use these new packages. Mostly completes https://github.com/flutter/flutter/issues/146920 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
664 lines
20 KiB
Dart
664 lines
20 KiB
Dart
// Copyright 2013 The Flutter Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:io' as io;
|
|
|
|
import 'package:args/command_runner.dart';
|
|
import 'package:file/file.dart';
|
|
import 'package:flutter_plugin_tools/src/common/core.dart';
|
|
import 'package:flutter_plugin_tools/src/create_all_packages_app_command.dart';
|
|
import 'package:platform/platform.dart';
|
|
import 'package:pubspec_parse/pubspec_parse.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
import 'mocks.dart';
|
|
import 'util.dart';
|
|
|
|
void main() {
|
|
late CommandRunner<void> runner;
|
|
late CreateAllPackagesAppCommand command;
|
|
late Platform mockPlatform;
|
|
late Directory testRoot;
|
|
late Directory packagesDir;
|
|
late RecordingProcessRunner processRunner;
|
|
|
|
setUp(() {
|
|
mockPlatform = MockPlatform(isMacOS: true);
|
|
(:packagesDir, :processRunner, gitProcessRunner: _, gitDir: _) =
|
|
configureBaseCommandMocks(platform: mockPlatform);
|
|
testRoot = packagesDir.parent;
|
|
|
|
command = CreateAllPackagesAppCommand(
|
|
packagesDir,
|
|
processRunner: processRunner,
|
|
platform: mockPlatform,
|
|
);
|
|
runner = CommandRunner<void>(
|
|
'create_all_test',
|
|
'Test for $CreateAllPackagesAppCommand',
|
|
);
|
|
runner.addCommand(command);
|
|
});
|
|
|
|
/// Simulates enough of `flutter create`s output to allow the modifications
|
|
/// made by the command to work.
|
|
void writeFakeFlutterCreateOutput(
|
|
Directory outputDirectory, {
|
|
String dartSdkConstraint = '>=3.0.0 <4.0.0',
|
|
String? appBuildGradleDependencies,
|
|
bool androidOnly = false,
|
|
}) {
|
|
final package = RepositoryPackage(
|
|
outputDirectory.childDirectory(allPackagesProjectName),
|
|
);
|
|
|
|
// Android
|
|
final String dependencies =
|
|
appBuildGradleDependencies ??
|
|
r'''
|
|
dependencies {
|
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
|
}
|
|
''';
|
|
package
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childDirectory('app')
|
|
.childFile('build.gradle')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('''
|
|
android {
|
|
namespace 'dev.flutter.packages.foo.example'
|
|
compileSdk flutter.compileSdkVersion
|
|
sourceSets {
|
|
main.java.srcDirs += 'src/main/kotlin'
|
|
}
|
|
defaultConfig {
|
|
applicationId "dev.flutter.packages.foo.example"
|
|
minSdkVersion flutter.minSdkVersion
|
|
targetSdkVersion 35
|
|
}
|
|
}
|
|
|
|
$dependencies
|
|
''');
|
|
|
|
if (androidOnly) {
|
|
return;
|
|
}
|
|
|
|
// Non-platform-specific
|
|
package.pubspecFile
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('''
|
|
name: $allPackagesProjectName
|
|
description: Flutter app containing all 1st party plugins.
|
|
publish_to: none
|
|
version: 1.0.0
|
|
|
|
environment:
|
|
sdk: '$dartSdkConstraint'
|
|
|
|
dependencies:
|
|
flutter:
|
|
sdk: flutter
|
|
|
|
dev_dependencies:
|
|
flutter_test:
|
|
sdk: flutter
|
|
###
|
|
''');
|
|
|
|
// iOS
|
|
final Directory iOS = package.platformDirectory(FlutterPlatform.ios);
|
|
iOS.childDirectory('Runner.xcodeproj').childFile('project.pbxproj')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('''
|
|
97C147041CF9000F007C117D /* Release */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
|
};
|
|
name = Release;
|
|
};
|
|
''');
|
|
|
|
// macOS
|
|
final Directory macOS = package.platformDirectory(FlutterPlatform.macos);
|
|
macOS.childDirectory('Runner.xcodeproj').childFile('project.pbxproj')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('''
|
|
97C147041CF9000F007C117D /* Release */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
|
};
|
|
name = Release;
|
|
};
|
|
''');
|
|
macOS.childFile('Podfile')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('''
|
|
# platform :osx, '10.14'
|
|
|
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
|
|
|
project 'Runner', {
|
|
'Debug' => :debug,
|
|
'Profile' => :release,
|
|
'Release' => :release,
|
|
}
|
|
''');
|
|
}
|
|
|
|
group('non-macOS host', () {
|
|
setUp(() {
|
|
mockPlatform = MockPlatform(isLinux: true);
|
|
command = CreateAllPackagesAppCommand(
|
|
packagesDir,
|
|
processRunner: processRunner,
|
|
platform: mockPlatform,
|
|
);
|
|
runner = CommandRunner<void>(
|
|
'create_all_test',
|
|
'Test for $CreateAllPackagesAppCommand',
|
|
);
|
|
runner.addCommand(command);
|
|
});
|
|
|
|
test('calls "flutter create"', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
|
|
expect(
|
|
processRunner.recordedCalls,
|
|
contains(
|
|
ProcessCall(getFlutterCommand(mockPlatform), <String>[
|
|
'create',
|
|
'--template=app',
|
|
'--project-name=$allPackagesProjectName',
|
|
testRoot.childDirectory(allPackagesProjectName).path,
|
|
], null),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('pubspec includes all plugins', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
createFakePlugin('pluginb', packagesDir);
|
|
createFakePlugin('pluginc', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
final List<String> pubspec = command.app.pubspecFile.readAsLinesSync();
|
|
|
|
expect(
|
|
pubspec,
|
|
containsAll(<Matcher>[
|
|
contains(RegExp('path: .*/packages/plugina')),
|
|
contains(RegExp('path: .*/packages/pluginb')),
|
|
contains(RegExp('path: .*/packages/pluginc')),
|
|
]),
|
|
);
|
|
});
|
|
|
|
test('pubspec has overrides for all plugins', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
createFakePlugin('pluginb', packagesDir);
|
|
createFakePlugin('pluginc', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
final List<String> pubspec = command.app.pubspecFile.readAsLinesSync();
|
|
|
|
expect(
|
|
pubspec,
|
|
containsAllInOrder(<Matcher>[
|
|
contains('dependency_overrides:'),
|
|
contains(RegExp('path: .*/packages/plugina')),
|
|
contains(RegExp('path: .*/packages/pluginb')),
|
|
contains(RegExp('path: .*/packages/pluginc')),
|
|
]),
|
|
);
|
|
});
|
|
|
|
test(
|
|
'pubspec special-cases camera_android_camerax to remove it from deps but not overrides',
|
|
() async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
final Directory cameraDir = packagesDir.childDirectory('camera');
|
|
createFakePlugin('camera', cameraDir);
|
|
createFakePlugin('camera_android', cameraDir);
|
|
createFakePlugin('camera_android_camerax', cameraDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
final Pubspec pubspec = command.app.parsePubspec();
|
|
|
|
final Dependency? cameraDependency = pubspec.dependencies['camera'];
|
|
final Dependency? cameraAndroidDependency =
|
|
pubspec.dependencies['camera_android'];
|
|
final Dependency? cameraCameraXDependency =
|
|
pubspec.dependencies['camera_android_camerax'];
|
|
expect(cameraDependency, isA<PathDependency>());
|
|
expect(
|
|
(cameraDependency! as PathDependency).path,
|
|
endsWith('/packages/camera/camera'),
|
|
);
|
|
expect(cameraAndroidDependency, isA<PathDependency>());
|
|
expect(
|
|
(cameraAndroidDependency! as PathDependency).path,
|
|
endsWith('/packages/camera/camera_android'),
|
|
);
|
|
expect(cameraCameraXDependency, null);
|
|
|
|
final Dependency? cameraCameraXOverride =
|
|
pubspec.dependencyOverrides['camera_android_camerax'];
|
|
expect(cameraCameraXOverride, isA<PathDependency>());
|
|
expect(
|
|
(cameraCameraXOverride! as PathDependency).path,
|
|
endsWith('/packages/camera/camera_android_camerax'),
|
|
);
|
|
},
|
|
);
|
|
|
|
test('legacy files are copied when requested', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
// Make a fake legacy source with all the necessary files, replacing one
|
|
// of them.
|
|
final Directory legacyDir = testRoot.childDirectory('legacy');
|
|
final legacySource = RepositoryPackage(
|
|
legacyDir.childDirectory(allPackagesProjectName),
|
|
);
|
|
writeFakeFlutterCreateOutput(legacyDir, androidOnly: true);
|
|
const legacyAppBuildGradleContents = 'Fake legacy content';
|
|
final File legacyGradleFile = legacySource
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childFile('build.gradle');
|
|
legacyGradleFile.writeAsStringSync(legacyAppBuildGradleContents);
|
|
|
|
await runCapturingPrint(runner, <String>[
|
|
'create-all-packages-app',
|
|
'--legacy-source=${legacySource.path}',
|
|
]);
|
|
|
|
final File buildGradle = command.app
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childFile('build.gradle');
|
|
|
|
expect(buildGradle.readAsStringSync(), legacyAppBuildGradleContents);
|
|
});
|
|
|
|
test('legacy directory replaces, rather than overlaying', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
final File extraFile = RepositoryPackage(
|
|
testRoot.childDirectory(allPackagesProjectName),
|
|
).platformDirectory(FlutterPlatform.android).childFile('extra_file');
|
|
extraFile.createSync(recursive: true);
|
|
// Make a fake legacy source with all the necessary files, but not
|
|
// including the extra file.
|
|
final Directory legacyDir = testRoot.childDirectory('legacy');
|
|
final legacySource = RepositoryPackage(
|
|
legacyDir.childDirectory(allPackagesProjectName),
|
|
);
|
|
writeFakeFlutterCreateOutput(legacyDir, androidOnly: true);
|
|
|
|
await runCapturingPrint(runner, <String>[
|
|
'create-all-packages-app',
|
|
'--legacy-source=${legacySource.path}',
|
|
]);
|
|
|
|
expect(extraFile.existsSync(), false);
|
|
});
|
|
|
|
test('legacy files are modified as needed by the tool', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
// Make a fake legacy source with all the necessary files, replacing one
|
|
// of them.
|
|
final Directory legacyDir = testRoot.childDirectory('legacy');
|
|
final legacySource = RepositoryPackage(
|
|
legacyDir.childDirectory(allPackagesProjectName),
|
|
);
|
|
writeFakeFlutterCreateOutput(legacyDir, androidOnly: true);
|
|
const legacyAppBuildGradleContents = '''
|
|
# This is the legacy file
|
|
android {
|
|
compileSdk flutter.compileSdkVersion
|
|
defaultConfig {
|
|
minSdkVersion flutter.minSdkVersion
|
|
}
|
|
}
|
|
''';
|
|
final File legacyGradleFile = legacySource
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childDirectory('app')
|
|
.childFile('build.gradle');
|
|
legacyGradleFile.writeAsStringSync(legacyAppBuildGradleContents);
|
|
|
|
await runCapturingPrint(runner, <String>[
|
|
'create-all-packages-app',
|
|
'--legacy-source=${legacySource.path}',
|
|
]);
|
|
|
|
final List<String> buildGradle = command.app
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childDirectory('app')
|
|
.childFile('build.gradle')
|
|
.readAsLinesSync();
|
|
|
|
expect(
|
|
buildGradle,
|
|
containsAll(<Matcher>[
|
|
contains('This is the legacy file'),
|
|
contains('compileSdk 36'),
|
|
]),
|
|
);
|
|
});
|
|
|
|
test('pubspec preserves existing Dart SDK version', () async {
|
|
const existingSdkConstraint = '>=1.0.0 <99.0.0';
|
|
writeFakeFlutterCreateOutput(
|
|
testRoot,
|
|
dartSdkConstraint: existingSdkConstraint,
|
|
);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
final Pubspec generatedPubspec = command.app.parsePubspec();
|
|
|
|
const dartSdkKey = 'sdk';
|
|
expect(
|
|
generatedPubspec.environment[dartSdkKey].toString(),
|
|
existingSdkConstraint,
|
|
);
|
|
});
|
|
|
|
test('Android app gradle is modified as expected', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
|
|
final List<String> buildGradle = command.app
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childDirectory('app')
|
|
.childFile('build.gradle')
|
|
.readAsLinesSync();
|
|
|
|
expect(
|
|
buildGradle,
|
|
containsAll(<Matcher>[
|
|
contains('compileSdk 36'),
|
|
contains('androidx.lifecycle:lifecycle-runtime'),
|
|
]),
|
|
);
|
|
});
|
|
|
|
// The template's app/build.gradle does not always have a dependencies
|
|
// section; ensure that the dependency is added if there is not one.
|
|
test('Android lifecyle dependency is added with no dependencies', () async {
|
|
writeFakeFlutterCreateOutput(testRoot, appBuildGradleDependencies: '');
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
|
|
final List<String> buildGradle = command.app
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childDirectory('app')
|
|
.childFile('build.gradle')
|
|
.readAsLinesSync();
|
|
|
|
expect(
|
|
buildGradle,
|
|
containsAllInOrder(<Matcher>[
|
|
equals('dependencies {'),
|
|
contains('androidx.lifecycle:lifecycle-runtime'),
|
|
equals('}'),
|
|
]),
|
|
);
|
|
});
|
|
|
|
// Some versions of the template's app/build.gradle has an empty
|
|
// dependencies section; ensure that the dependency is added in that case.
|
|
test(
|
|
'Android lifecyle dependency is added with empty dependencies',
|
|
() async {
|
|
writeFakeFlutterCreateOutput(
|
|
testRoot,
|
|
appBuildGradleDependencies: 'dependencies {}',
|
|
);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
|
|
final List<String> buildGradle = command.app
|
|
.platformDirectory(FlutterPlatform.android)
|
|
.childDirectory('app')
|
|
.childFile('build.gradle')
|
|
.readAsLinesSync();
|
|
|
|
expect(
|
|
buildGradle,
|
|
containsAllInOrder(<Matcher>[
|
|
equals('dependencies {'),
|
|
contains('androidx.lifecycle:lifecycle-runtime'),
|
|
equals('}'),
|
|
]),
|
|
);
|
|
},
|
|
);
|
|
|
|
test('macOS deployment target is modified in pbxproj', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-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('iOS deployment target is modified in pbxproj', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
final List<String> pbxproj = command.app
|
|
.platformDirectory(FlutterPlatform.ios)
|
|
.childDirectory('Runner.xcodeproj')
|
|
.childFile('project.pbxproj')
|
|
.readAsLinesSync();
|
|
|
|
expect(
|
|
pbxproj,
|
|
everyElement(
|
|
(String line) =>
|
|
!line.contains('IPHONEOS_DEPLOYMENT_TARGET') ||
|
|
line.contains('15.0'),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('calls flutter pub get', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-app']);
|
|
|
|
expect(
|
|
processRunner.recordedCalls,
|
|
contains(
|
|
ProcessCall(
|
|
getFlutterCommand(mockPlatform),
|
|
const <String>['pub', 'get'],
|
|
testRoot.childDirectory(allPackagesProjectName).path,
|
|
),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('fails if flutter create fails', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
processRunner.mockProcessesForExecutable[getFlutterCommand(
|
|
mockPlatform,
|
|
)] = <FakeProcessInfo>[
|
|
FakeProcessInfo(MockProcess(exitCode: 1), <String>['create']),
|
|
];
|
|
Error? commandError;
|
|
final List<String> output = await runCapturingPrint(
|
|
runner,
|
|
<String>['create-all-packages-app'],
|
|
errorHandler: (Error e) {
|
|
commandError = e;
|
|
},
|
|
);
|
|
|
|
expect(commandError, isA<ToolExit>());
|
|
expect(
|
|
output,
|
|
containsAllInOrder(<Matcher>[contains('Failed to `flutter create`')]),
|
|
);
|
|
});
|
|
|
|
test(
|
|
'fails if flutter pub get fails',
|
|
() async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
processRunner.mockProcessesForExecutable[getFlutterCommand(
|
|
mockPlatform,
|
|
)] = <FakeProcessInfo>[
|
|
FakeProcessInfo(MockProcess(), <String>['create']),
|
|
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get']),
|
|
];
|
|
Error? commandError;
|
|
final List<String> output = await runCapturingPrint(
|
|
runner,
|
|
<String>['create-all-packages-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_packages_app_command.dart
|
|
skip: io.Platform.isWindows,
|
|
);
|
|
|
|
test('handles --output-dir', () async {
|
|
final Directory customOutputDir = testRoot.fileSystem.systemTempDirectory
|
|
.createTempSync();
|
|
writeFakeFlutterCreateOutput(customOutputDir);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
await runCapturingPrint(runner, <String>[
|
|
'create-all-packages-app',
|
|
'--output-dir=${customOutputDir.path}',
|
|
]);
|
|
|
|
expect(
|
|
command.app.path,
|
|
customOutputDir.childDirectory(allPackagesProjectName).path,
|
|
);
|
|
});
|
|
|
|
test('logs exclusions', () async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
createFakePlugin('pluginb', packagesDir);
|
|
createFakePlugin('pluginc', packagesDir);
|
|
|
|
final List<String> output = await runCapturingPrint(runner, <String>[
|
|
'create-all-packages-app',
|
|
'--exclude=pluginb,pluginc',
|
|
]);
|
|
|
|
expect(
|
|
output,
|
|
containsAllInOrder(<String>[
|
|
'Exluding the following plugins from the combined build:',
|
|
' pluginb',
|
|
' pluginc',
|
|
]),
|
|
);
|
|
});
|
|
});
|
|
|
|
group('macOS host', () {
|
|
setUp(() {
|
|
command = CreateAllPackagesAppCommand(
|
|
packagesDir,
|
|
processRunner: processRunner,
|
|
platform: MockPlatform(isMacOS: true),
|
|
);
|
|
runner = CommandRunner<void>(
|
|
'create_all_test',
|
|
'Test for $CreateAllPackagesAppCommand',
|
|
);
|
|
runner.addCommand(command);
|
|
});
|
|
|
|
test(
|
|
'macOS deployment target is modified in Podfile',
|
|
() async {
|
|
writeFakeFlutterCreateOutput(testRoot);
|
|
createFakePlugin('plugina', packagesDir);
|
|
|
|
final File podfileFile = RepositoryPackage(
|
|
command.packagesDir.parent.childDirectory(allPackagesProjectName),
|
|
).platformDirectory(FlutterPlatform.macos).childFile('Podfile');
|
|
podfileFile.createSync(recursive: true);
|
|
podfileFile.writeAsStringSync("""
|
|
platform :osx, '10.11'
|
|
# some other line
|
|
""");
|
|
|
|
await runCapturingPrint(runner, <String>['create-all-packages-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,
|
|
);
|
|
});
|
|
}
|