mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

This PR symlinks SwiftPM plugins in the same directory so that they're relative to each other and the `FlutterGeneratedPluginSwiftPackage`. This allows plugins to depend on each other via relative paths. For example, > Flutter/ephemeral/Packages/.packages/plugin_a --> symlink --> /local/path/to/plugin_a > Flutter/ephemeral/Packages/.packages/plugin_b --> symlink --> /path/to/.pub-cache/plugin_b Then in plugin_b's Package.swift, you can do the following to add a dependency on plugin_a: ```swift dependencies: [ .package(name: "plugin_a", path: "../plugin_a"), ], ``` Addresses https://github.com/flutter/flutter/issues/166528 and incremental change toward https://github.com/flutter/flutter/issues/166489. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
634 lines
20 KiB
Dart
634 lines
20 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:file/file.dart';
|
|
import 'package:file/memory.dart';
|
|
import 'package:file_testing/file_testing.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/dart/pub.dart';
|
|
import 'package:flutter_tools/src/flutter_manifest.dart';
|
|
import 'package:flutter_tools/src/macos/cocoapod_utils.dart';
|
|
import 'package:flutter_tools/src/macos/cocoapods.dart';
|
|
import 'package:flutter_tools/src/project.dart';
|
|
import 'package:test/fake.dart';
|
|
import 'package:yaml/yaml.dart';
|
|
|
|
import '../../src/common.dart';
|
|
import '../../src/context.dart';
|
|
import '../../src/package_config.dart';
|
|
import '../../src/throwing_pub.dart';
|
|
|
|
void main() {
|
|
group('processPodsIfNeeded', () {
|
|
late MemoryFileSystem fs;
|
|
late FakeCocoaPods cocoaPods;
|
|
late BufferLogger logger;
|
|
|
|
// Adds basic properties to the flutterProject and its subprojects.
|
|
void setUpProject(
|
|
FakeFlutterProject flutterProject,
|
|
MemoryFileSystem fileSystem, {
|
|
List<String> pluginNames = const <String>[],
|
|
}) {
|
|
flutterProject
|
|
..manifest = FakeFlutterManifest()
|
|
..directory = fileSystem.systemTempDirectory.childDirectory('app')
|
|
..flutterPluginsFile = flutterProject.directory.childFile('.flutter-plugins')
|
|
..flutterPluginsDependenciesFile = flutterProject.directory.childFile(
|
|
'.flutter-plugins-dependencies',
|
|
)
|
|
..ios = FakeIosProject(fileSystem: fileSystem, parent: flutterProject)
|
|
..macos = FakeMacOSProject(fileSystem: fileSystem, parent: flutterProject)
|
|
..android = FakeAndroidProject()
|
|
..web = FakeWebProject()
|
|
..windows = FakeWindowsProject()
|
|
..linux = FakeLinuxProject()
|
|
..packageConfig = flutterProject.directory
|
|
.childDirectory('.dart_tool')
|
|
.childFile('package_config.json');
|
|
|
|
const String pluginYamlTemplate = '''
|
|
flutter:
|
|
plugin:
|
|
platforms:
|
|
ios:
|
|
pluginClass: PLUGIN_CLASS
|
|
macos:
|
|
pluginClass: PLUGIN_CLASS
|
|
''';
|
|
|
|
final Directory fakePubCache = fileSystem.systemTempDirectory.childDirectory('cache');
|
|
|
|
writePackageConfigFiles(
|
|
directory: flutterProject.directory,
|
|
mainLibName: 'my_app',
|
|
packages: <String, String>{
|
|
for (final String plugin in pluginNames)
|
|
plugin: fakePubCache.childDirectory(plugin).uri.toString(),
|
|
},
|
|
);
|
|
|
|
for (final String name in pluginNames) {
|
|
flutterProject.manifest.dependencies.add(name);
|
|
final Directory pluginDirectory = fakePubCache.childDirectory(name);
|
|
pluginDirectory.childFile('pubspec.yaml')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync(pluginYamlTemplate.replaceAll('PLUGIN_CLASS', name));
|
|
}
|
|
}
|
|
|
|
setUp(() async {
|
|
fs = MemoryFileSystem.test();
|
|
cocoaPods = FakeCocoaPods();
|
|
logger = BufferLogger.test();
|
|
});
|
|
|
|
group('for iOS', () {
|
|
group('using CocoaPods only', () {
|
|
testUsingContext(
|
|
'processes when there are plugins',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'processes when no plugins but the project is a module and podfile exists',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs);
|
|
flutterProject.isModule = true;
|
|
flutterProject.ios.podfile.createSync(recursive: true);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
"skips when no plugins and the project is a module but podfile doesn't exist",
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs);
|
|
flutterProject.isModule = true;
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'skips when no plugins and project is not a module',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
});
|
|
|
|
group('using Swift Package Manager', () {
|
|
testUsingContext(
|
|
'processes if podfile exists',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
flutterProject.ios.usesSwiftPackageManager = true;
|
|
flutterProject.ios.podfile.createSync(recursive: true);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'skip if podfile does not exists',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
flutterProject.ios.usesSwiftPackageManager = true;
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'process if podfile does not exists but forceCocoaPodsOnly is true',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
flutterProject.ios.usesSwiftPackageManager = true;
|
|
final File generatedManifestFile = flutterProject.ios.flutterPluginSwiftPackageManifest;
|
|
generatedManifestFile.createSync(recursive: true);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.ios,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
forceCocoaPodsOnly: true,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
expect(cocoaPods.podfileSetup, isTrue);
|
|
expect(
|
|
logger.warningText,
|
|
'Swift Package Manager does not yet support this command. '
|
|
'CocoaPods will be used instead.\n',
|
|
);
|
|
expect(generatedManifestFile, exists);
|
|
const String emptyDependencies = 'dependencies: [\n \n ],\n';
|
|
expect(generatedManifestFile.readAsStringSync(), contains(emptyDependencies));
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
Logger: () => logger,
|
|
},
|
|
);
|
|
});
|
|
});
|
|
|
|
group('for macOS', () {
|
|
group('using CocoaPods only', () {
|
|
testUsingContext(
|
|
'processes when there are plugins',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'processes when no plugins but the project is a module and podfile exists',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs);
|
|
flutterProject.isModule = true;
|
|
flutterProject.macos.podfile.createSync(recursive: true);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
"skips when no plugins and the project is a module but podfile doesn't exist",
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs);
|
|
flutterProject.isModule = true;
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'skips when no plugins and project is not a module',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
});
|
|
|
|
group('using Swift Package Manager', () {
|
|
testUsingContext(
|
|
'processes if podfile exists',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
flutterProject.macos.usesSwiftPackageManager = true;
|
|
flutterProject.macos.podfile.createSync(recursive: true);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'skip if podfile does not exists',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
flutterProject.macos.usesSwiftPackageManager = true;
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
);
|
|
expect(cocoaPods.processedPods, isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
CocoaPods: () => cocoaPods,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'process if podfile does not exists but forceCocoaPodsOnly is true',
|
|
() async {
|
|
final FakeFlutterProject flutterProject = FakeFlutterProject();
|
|
setUpProject(flutterProject, fs, pluginNames: <String>['plugin_one', 'plugin_two']);
|
|
flutterProject.macos.usesSwiftPackageManager = true;
|
|
final File generatedManifestFile =
|
|
flutterProject.macos.flutterPluginSwiftPackageManifest;
|
|
generatedManifestFile.createSync(recursive: true);
|
|
|
|
await processPodsIfNeeded(
|
|
flutterProject.macos,
|
|
fs.currentDirectory.childDirectory('build').path,
|
|
BuildMode.debug,
|
|
forceCocoaPodsOnly: true,
|
|
);
|
|
expect(cocoaPods.processedPods, isTrue);
|
|
expect(cocoaPods.podfileSetup, isTrue);
|
|
expect(
|
|
logger.warningText,
|
|
'Swift Package Manager does not yet support this command. '
|
|
'CocoaPods will be used instead.\n',
|
|
);
|
|
|
|
expect(generatedManifestFile, exists);
|
|
const String emptyDependencies = 'dependencies: [\n \n ],\n';
|
|
expect(generatedManifestFile.readAsStringSync(), contains(emptyDependencies));
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: FakeProcessManager.empty,
|
|
Pub: ThrowingPub.new,
|
|
CocoaPods: () => cocoaPods,
|
|
Logger: () => logger,
|
|
},
|
|
);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
class FakeFlutterManifest extends Fake implements FlutterManifest {
|
|
@override
|
|
late Set<String> dependencies = <String>{};
|
|
@override
|
|
String get appName => 'my_app';
|
|
@override
|
|
YamlMap toYaml() => YamlMap.wrap(<String, String>{});
|
|
}
|
|
|
|
class FakeFlutterProject extends Fake implements FlutterProject {
|
|
@override
|
|
bool isModule = false;
|
|
|
|
@override
|
|
late FlutterManifest manifest;
|
|
|
|
@override
|
|
late Directory directory;
|
|
|
|
@override
|
|
late File flutterPluginsFile;
|
|
|
|
@override
|
|
late File flutterPluginsDependenciesFile;
|
|
|
|
@override
|
|
late FakeIosProject ios;
|
|
|
|
@override
|
|
late FakeMacOSProject macos;
|
|
|
|
@override
|
|
late AndroidProject android;
|
|
|
|
@override
|
|
late WebProject web;
|
|
|
|
@override
|
|
late LinuxProject linux;
|
|
|
|
@override
|
|
late WindowsProject windows;
|
|
|
|
@override
|
|
late File packageConfig;
|
|
}
|
|
|
|
class FakeMacOSProject extends Fake implements MacOSProject {
|
|
FakeMacOSProject({required MemoryFileSystem fileSystem, required this.parent})
|
|
: hostAppRoot = fileSystem.directory('app_name').childDirectory('ios');
|
|
|
|
@override
|
|
String pluginConfigKey = 'macos';
|
|
|
|
@override
|
|
final FlutterProject parent;
|
|
|
|
@override
|
|
Directory hostAppRoot;
|
|
|
|
bool exists = true;
|
|
|
|
@override
|
|
bool existsSync() => exists;
|
|
|
|
@override
|
|
File get podfile => hostAppRoot.childFile('Podfile');
|
|
|
|
@override
|
|
File get xcodeProjectInfoFile =>
|
|
hostAppRoot.childDirectory('Runner.xcodeproj').childFile('project.pbxproj');
|
|
|
|
@override
|
|
Directory get flutterSwiftPackagesDirectory =>
|
|
hostAppRoot.childDirectory('Flutter').childDirectory('ephemeral').childDirectory('Packages');
|
|
|
|
@override
|
|
Directory get relativeSwiftPackagesDirectory =>
|
|
flutterSwiftPackagesDirectory.childDirectory('.packages');
|
|
|
|
@override
|
|
Directory get flutterPluginSwiftPackageDirectory =>
|
|
flutterSwiftPackagesDirectory.childDirectory('FlutterGeneratedPluginSwiftPackage');
|
|
|
|
@override
|
|
File get flutterPluginSwiftPackageManifest =>
|
|
flutterPluginSwiftPackageDirectory.childFile('Package.swift');
|
|
|
|
@override
|
|
bool usesSwiftPackageManager = false;
|
|
|
|
@override
|
|
bool get flutterPluginSwiftPackageInProjectSettings => usesSwiftPackageManager;
|
|
}
|
|
|
|
class FakeIosProject extends Fake implements IosProject {
|
|
FakeIosProject({required MemoryFileSystem fileSystem, required this.parent})
|
|
: hostAppRoot = fileSystem.directory('app_name').childDirectory('ios');
|
|
|
|
@override
|
|
String pluginConfigKey = 'ios';
|
|
|
|
@override
|
|
final FlutterProject parent;
|
|
|
|
@override
|
|
Directory hostAppRoot;
|
|
|
|
@override
|
|
bool exists = true;
|
|
|
|
@override
|
|
bool existsSync() => exists;
|
|
|
|
@override
|
|
File get podfile => hostAppRoot.childFile('Podfile');
|
|
|
|
@override
|
|
File get xcodeProjectInfoFile =>
|
|
hostAppRoot.childDirectory('Runner.xcodeproj').childFile('project.pbxproj');
|
|
|
|
@override
|
|
Directory get flutterSwiftPackagesDirectory =>
|
|
hostAppRoot.childDirectory('Flutter').childDirectory('ephemeral').childDirectory('Packages');
|
|
|
|
@override
|
|
Directory get relativeSwiftPackagesDirectory =>
|
|
flutterSwiftPackagesDirectory.childDirectory('.packages');
|
|
|
|
@override
|
|
Directory get flutterPluginSwiftPackageDirectory =>
|
|
flutterSwiftPackagesDirectory.childDirectory('FlutterGeneratedPluginSwiftPackage');
|
|
|
|
@override
|
|
File get flutterPluginSwiftPackageManifest =>
|
|
flutterPluginSwiftPackageDirectory.childFile('Package.swift');
|
|
|
|
@override
|
|
bool usesSwiftPackageManager = false;
|
|
|
|
@override
|
|
bool get flutterPluginSwiftPackageInProjectSettings => usesSwiftPackageManager;
|
|
}
|
|
|
|
class FakeAndroidProject extends Fake implements AndroidProject {
|
|
@override
|
|
String pluginConfigKey = 'android';
|
|
|
|
@override
|
|
bool existsSync() => false;
|
|
}
|
|
|
|
class FakeWebProject extends Fake implements WebProject {
|
|
@override
|
|
String pluginConfigKey = 'web';
|
|
|
|
@override
|
|
bool existsSync() => false;
|
|
}
|
|
|
|
class FakeWindowsProject extends Fake implements WindowsProject {
|
|
@override
|
|
String pluginConfigKey = 'windows';
|
|
|
|
@override
|
|
bool existsSync() => false;
|
|
}
|
|
|
|
class FakeLinuxProject extends Fake implements LinuxProject {
|
|
@override
|
|
String pluginConfigKey = 'linux';
|
|
|
|
@override
|
|
bool existsSync() => false;
|
|
}
|
|
|
|
class FakeCocoaPods extends Fake implements CocoaPods {
|
|
bool podfileSetup = false;
|
|
bool processedPods = false;
|
|
|
|
@override
|
|
Future<bool> processPods({
|
|
required XcodeBasedProject xcodeProject,
|
|
required BuildMode buildMode,
|
|
bool dependenciesChanged = true,
|
|
}) async {
|
|
processedPods = true;
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
Future<void> setupPodfile(XcodeBasedProject xcodeProject) async {
|
|
podfileSetup = true;
|
|
}
|
|
|
|
@override
|
|
void invalidatePodInstallOutput(XcodeBasedProject xcodeProject) {}
|
|
}
|