Unverified Commit 082ae838 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Fall back to global cache and platform if null when injected into constructor (#50370)

parent ef74572e
......@@ -298,6 +298,56 @@ Future<void> main() async {
}
}
// This builds all build modes' frameworks by default
section('Build podspec');
const String cocoapodsOutputDirectoryName = 'flutter-frameworks-cocoapods';
await inDirectory(projectDir, () async {
await flutter(
'build',
options: <String>[
'ios-framework',
'--cocoapods',
'--force', // Allow podspec creation on master.
'--output=$cocoapodsOutputDirectoryName'
],
);
});
final String cocoapodsOutputPath = path.join(projectDir.path, cocoapodsOutputDirectoryName);
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
checkFileExists(path.join(
cocoapodsOutputPath,
mode,
'Flutter.podspec',
));
checkDirectoryExists(path.join(
cocoapodsOutputPath,
mode,
'App.framework',
));
checkDirectoryExists(path.join(
cocoapodsOutputPath,
mode,
'FlutterPluginRegistrant.framework',
));
checkDirectoryExists(path.join(
cocoapodsOutputPath,
mode,
'device_info.framework',
));
checkDirectoryExists(path.join(
cocoapodsOutputPath,
mode,
'package_info.framework',
));
}
return TaskResult.success(null);
} on TaskResult catch (taskResult) {
return taskResult;
......
......@@ -641,6 +641,13 @@ void checkFileNotExists(String file) {
}
}
/// Checks that the directory exists, otherwise throws a [FileSystemException].
void checkDirectoryExists(String directory) {
if (!exists(Directory(directory))) {
throw FileSystemException('Expected directory to exist.', directory);
}
}
/// Check that `collection` contains all entries in `values`.
void checkCollectionContains<T>(Iterable<T> values, Iterable<T> collection) {
for (final T value in values) {
......
......@@ -9,7 +9,6 @@ import '../bundle.dart';
import '../commands/build_linux.dart';
import '../commands/build_macos.dart';
import '../commands/build_windows.dart';
import '../globals.dart' as globals;
import '../runner/flutter_command.dart';
import 'build_aar.dart';
import 'build_aot.dart';
......@@ -31,8 +30,6 @@ class BuildCommand extends FlutterCommand {
addSubcommand(BuildIOSFrameworkCommand(
aotBuilder: AotBuilder(),
bundleBuilder: BundleBuilder(),
cache: globals.cache,
platform: globals.platform,
));
addSubcommand(BuildBundleCommand(verboseHelp: verboseHelp));
addSubcommand(BuildWebCommand());
......
......@@ -37,13 +37,13 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
FlutterVersion flutterVersion, // Instantiating FlutterVersion kicks off networking, so delay until it's needed, but allow test injection.
@required AotBuilder aotBuilder,
@required BundleBuilder bundleBuilder,
@required Cache cache,
@required Platform platform
Cache cache,
Platform platform
}) : _flutterVersion = flutterVersion,
_aotBuilder = aotBuilder,
_bundleBuilder = bundleBuilder,
_cache = cache,
_platform = platform {
_injectedCache = cache,
_injectedPlatform = platform {
addTreeShakeIconsFlag();
usesTargetOption();
usesFlavorOption();
......@@ -84,13 +84,22 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
abbr: 'o',
valueHelp: 'path/to/directory/',
help: 'Location to write the frameworks.',
)
..addFlag('force',
abbr: 'f',
help: 'Force Flutter.podspec creation on the master channel. For testing only.',
hide: true
);
}
final AotBuilder _aotBuilder;
final BundleBuilder _bundleBuilder;
final Cache _cache;
final Platform _platform;
Cache get _cache => _injectedCache ?? globals.cache;
final Cache _injectedCache;
Platform get _platform => _injectedPlatform ?? globals.platform;
final Platform _injectedPlatform;
FlutterVersion _flutterVersion;
......@@ -180,7 +189,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
if (boolArg('cocoapods')) {
// FlutterVersion.instance kicks off git processing which can sometimes fail, so don't try it until needed.
_flutterVersion ??= globals.flutterVersion;
produceFlutterPodspec(mode, modeDirectory);
produceFlutterPodspec(mode, modeDirectory, force: boolArg('force'));
} else {
// Copy Flutter.framework.
await _produceFlutterFramework(mode, modeDirectory);
......@@ -218,11 +227,11 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
/// Create podspec that will download and unzip remote engine assets so host apps can leverage CocoaPods
/// vendored framework caching.
@visibleForTesting
void produceFlutterPodspec(BuildMode mode, Directory modeDirectory) {
void produceFlutterPodspec(BuildMode mode, Directory modeDirectory, { bool force = false }) {
final Status status = globals.logger.startProgress(' ├─Creating Flutter.podspec...', timeout: timeoutConfiguration.fastOperation);
try {
final GitTagVersion gitTagVersion = _flutterVersion.gitTagVersion;
if (gitTagVersion.x == null || gitTagVersion.y == null || gitTagVersion.z == null || gitTagVersion.commits != 0) {
if (!force && (gitTagVersion.x == null || gitTagVersion.y == null || gitTagVersion.z == null || gitTagVersion.commits != 0)) {
throwToolExit(
'--cocoapods is only supported on the dev, beta, or stable channels. Detected version is ${_flutterVersion.frameworkVersion}');
}
......
......@@ -134,7 +134,6 @@ void main() {
when(mockGitTagVersion.y).thenReturn(13);
when(mockGitTagVersion.z).thenReturn(11);
when(mockGitTagVersion.hotfix).thenReturn(13);
when(mockGitTagVersion.commits).thenReturn(0);
when(mockFlutterVersion.frameworkVersion).thenReturn(frameworkVersion);
......@@ -143,78 +142,107 @@ void main() {
..writeAsStringSync(licenseText);
});
testUsingContext('contains license and version', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.debug, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'1.13.1113\''));
expect(podspecContents, contains('# $frameworkVersion'));
expect(podspecContents, contains(licenseText));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
group('on master channel', () {
setUp(() {
when(mockGitTagVersion.commits).thenReturn(100);
});
testUsingContext('created when forced', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.debug, outputDirectory, force: true);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
expect(expectedPodspec.existsSync(), isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
});
testUsingContext('debug URL', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.debug, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'$storageBaseUrl/flutter_infra/flutter/$engineRevision/ios/artifacts.zip\''));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('profile URL', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.profile, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'$storageBaseUrl/flutter_infra/flutter/$engineRevision/ios-profile/artifacts.zip\''));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('release URL', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.release, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'$storageBaseUrl/flutter_infra/flutter/$engineRevision/ios-release/artifacts.zip\''));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
group('not on master channel', () {
setUp(() {
when(mockGitTagVersion.commits).thenReturn(0);
});
testUsingContext('contains license and version', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.debug, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'1.13.1113\''));
expect(podspecContents, contains('# $frameworkVersion'));
expect(podspecContents, contains(licenseText));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('debug URL', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.debug, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'$storageBaseUrl/flutter_infra/flutter/$engineRevision/ios/artifacts.zip\''));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('profile URL', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.profile, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'$storageBaseUrl/flutter_infra/flutter/$engineRevision/ios-profile/artifacts.zip\''));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('release URL', () async {
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
aotBuilder: MockAotBuilder(),
bundleBuilder: MockBundleBuilder(),
platform: fakePlatform,
flutterVersion: mockFlutterVersion,
cache: mockCache
);
command.produceFlutterPodspec(BuildMode.release, outputDirectory);
final File expectedPodspec = outputDirectory.childFile('Flutter.podspec');
final String podspecContents = expectedPodspec.readAsStringSync();
expect(podspecContents, contains('\'$storageBaseUrl/flutter_infra/flutter/$engineRevision/ios-release/artifacts.zip\''));
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
});
});
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment