Plugin.isDevDependency if exclusively in dev_dependencies (#157462)

Work towards https://github.com/flutter/flutter/issues/56591.

I explicitly want an LGTM from @andrewkolos @jmagman @jonahwilliams before merging.

---

After this PR, `<Plugin>.isDevDependency` is resolved based on the following logic, IFF:

- The plugin comes from a package _A_ listed in the app's package's `dev_dependencies: ...`
- The package _A_ is not a normal dependency of any transitive non-dev dependency of the app

See [`compute_dev_dependencies_test.dart`](51676093a3/packages/flutter_tools/test/general.shard/compute_dev_dependencies_test.dart) for probably the best specification of this behavior.

We (still) do not write the property to disk (i.e. it never makes it to `.flutter-plugins-dependencies`), so there is no impact to build artifacts at this time; that would come in a follow-up PR (and then follow-up follow-up PRs for the various build systems in both Gradle and Xcode to actually use that value to omit dependencies).

Some tests had to be updated; for the most part it was updating the default `ProcessManager` because a call to `dart pub deps --json` is now made in code that computes what plugins are available, but there should be no change in behavior.

_/cc @jonasfj @sigurdm for FYI only (we talked on an internal thread about this; see https://github.com/dart-lang/sdk/issues/56968)._

_/cc @camsim99 @cbracken @johnmccutchan for visibility on the change._
This commit is contained in:
Matan Lurey 2024-11-07 10:09:22 -08:00 committed by GitHub
parent bd65732cd2
commit 78cfc1ae9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 959 additions and 153 deletions

View File

@ -459,7 +459,7 @@ class CreateCommand extends CreateBase {
macOSPlatform: includeMacos,
windowsPlatform: includeWindows,
webPlatform: includeWeb,
writeLegacyPluginsList: boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true),
useImplicitPubspecResolution: boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true),
);
}
}

View File

@ -386,14 +386,14 @@ class PackagesGetCommand extends FlutterCommand {
if (rootProject != null) {
// We need to regenerate the platform specific tooling for both the project
// itself and example(if present).
final bool writeLegacyPluginsList = boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true);
final bool useImplicitPubspecResolution = boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true);
await rootProject.regeneratePlatformSpecificTooling(
writeLegacyPluginsList: writeLegacyPluginsList,
useImplicitPubspecResolution: useImplicitPubspecResolution,
);
if (example && rootProject.hasExampleApp && rootProject.example.pubspecFile.existsSync()) {
final FlutterProject exampleProject = rootProject.example;
await exampleProject.regeneratePlatformSpecificTooling(
writeLegacyPluginsList: writeLegacyPluginsList,
useImplicitPubspecResolution: useImplicitPubspecResolution,
);
}
}
@ -407,7 +407,7 @@ class PackagesGetCommand extends FlutterCommand {
return <Plugin>[];
}
return findPlugins(rootProject, throwOnError: false);
return findPlugins(rootProject, throwOnError: false, useImplicitPubspecResolution: boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true));
})();
late final String? _androidEmbeddingVersion = _rootProject?.android.getEmbeddingVersion().toString().split('.').last;

View File

@ -0,0 +1,164 @@
// 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:process/process.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'convert.dart';
/// Returns dependencies of [project] that are _only_ used as `dev_dependency`.
///
/// That is, computes and returns a subset of dependencies, where the original
/// set is based on packages listed as [`dev_dependency`][dev_deps] in the
/// `pubspec.yaml` file, and removing packages from that set that appear as
/// dependencies (implicitly non-dev) in any non-dev package depended on.
Future<Set<String>> computeExclusiveDevDependencies(
ProcessManager processes, {
required Logger logger,
required String projectPath,
}) async {
final ProcessResult processResult = await processes.run(
<String>['dart', 'pub', 'deps', '--json'],
workingDirectory: projectPath,
);
Never fail([String? reason]) {
final Object? stdout = processResult.stdout;
if (stdout is String && stdout.isNotEmpty) {
logger.printTrace(stdout);
}
final String stderr = processResult.stderr.toString();
throw StateError(
'dart pub deps --json ${reason != null ? 'had unexpected output: $reason' : 'failed'}'
'${stderr.isNotEmpty ? '\n$stderr' : ''}',
);
}
// Guard against dart pub deps crashing.
final Map<String, Object?> jsonResult;
if (processResult.exitCode != 0 || processResult.stdout is! String) {
fail();
}
// Guard against dart pub deps having explicitly invalid output.
final String stdout;
try {
stdout = processResult.stdout as String;
// This is an indication that `FakeProcessManager.any` was used, which by
// contract emits exit code 0 and no output on either stdout or stderr. To
// avoid this code, we'd have to go and make this function injectable into
// every callsite and mock-it out manually, which at the time of this
// writing was 130+ unit test cases alone.
//
// So, this is the lesser of two evils.
if (stdout.isEmpty && processResult.stderr == '') {
return <String>{};
}
jsonResult = json.decode(stdout) as Map<String, Object?>;
} on FormatException catch (e) {
fail('$e');
}
List<T> asListOrFail<T>(Object? value, String name) {
if (value is! List<Object?>) {
fail('Expected field "$name" to be a list, got "$value"');
}
return <T>[
for (final Object? any in value)
if (any is T) any else fail('Expected element to be a $T, got "$any"')
];
}
// Parse the JSON roughly in the following format:
//
// ```json
// {
// "root": "my_app",
// "packages": [
// {
// "name": "my_app",
// "kind": "root",
// "dependencies": [
// "foo_plugin",
// "bar_plugin"
// ],
// "directDependencies": [
// "foo_plugin"
// ],
// "devDependencies": [
// "bar_plugin"
// ]
// }
// ]
// }
// ```
final List<Map<String, Object?>> packages = asListOrFail(
jsonResult['packages'],
'packages',
);
Map<String, Object?> packageWhere(
bool Function(Map<String, Object?>) test, {
required String reason,
}) {
return packages.firstWhere(test, orElse: () => fail(reason));
}
final Map<String, Object?> rootPackage = packageWhere(
(Map<String, Object?> package) => package['kind'] == 'root',
reason: 'A package with kind "root" was not found.',
);
// Start initially with every `devDependency` listed.
final Set<String> devDependencies = asListOrFail<String>(
rootPackage['devDependencies'],
'devDependencies',
).toSet();
// Then traverse and exclude non-dev dependencies that list that dependency.
//
// This avoids the pathalogical problem of using, say, `path_provider` in a
// package's dev_dependencies:, but a (non-dev) dependency using it as a
// standard dependency - in that case we would not want to report it is used
// as a dev dependency.
final Set<String> visited = <String>{};
void visitPackage(String packageName) {
final bool wasAlreadyVisited = !visited.add(packageName);
if (wasAlreadyVisited) {
return;
}
final Map<String, Object?> package = packageWhere(
(Map<String, Object?> package) => package['name'] == packageName,
reason: 'A package with name "$packageName" was not found',
);
// Do not traverse packages that themselves are dev dependencies.
if (package['kind'] == 'dev') {
return;
}
final List<String> directDependencies = asListOrFail(
package['directDependencies'],
'directDependencies',
);
// Remove any listed dependency from dev dependencies; it might have been
// a dev dependency for the app (root) package, but it is being used as a
// real dependency for a dependend on package, so we would not want to send
// a signal that the package can be ignored/removed.
devDependencies.removeAll(directDependencies);
// And continue visiting (visitPackage checks for circular loops).
directDependencies.forEach(visitPackage);
}
// Start with the root package.
visitPackage(rootPackage['name']! as String);
return devDependencies;
}

View File

@ -1,63 +0,0 @@
// 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 'dart:collection';
/// Parsing the output of "dart pub deps --json"
///
/// expected structure: {"name": "package name", "source": "hosted", "dependencies": [...]}
class DartDependencyPackage {
DartDependencyPackage({
required this.name,
required this.version,
required this.source,
required this.dependencies,
});
factory DartDependencyPackage.fromHashMap(dynamic packageInfo) {
if (packageInfo is! LinkedHashMap) {
return DartDependencyPackage(
name: '',
version: '',
source: '',
dependencies: <String>[],
);
}
return DartDependencyPackage(
name: packageInfo['name'] as String? ?? '',
version: packageInfo['version'] as String? ?? '',
source: packageInfo['source'] as String? ?? '',
dependencies: switch (packageInfo['dependencies'] as List<Object?>?) {
final List<Object?> list => list.map((Object? e) => '$e').toList(),
null => <String>[],
},
);
}
final String name;
final String version;
final String source;
final List<String> dependencies;
}
class DartPubJson {
DartPubJson(this._json);
final LinkedHashMap<String, dynamic> _json;
final List<DartDependencyPackage> _packages = <DartDependencyPackage>[];
List<DartDependencyPackage> get packages {
if (_packages.isNotEmpty) {
return _packages;
}
if (_json.containsKey('packages')) {
final List<dynamic> packagesInfo = _json['packages'] as List<dynamic>;
for (final dynamic info in packagesInfo) {
_packages.add(DartDependencyPackage.fromHashMap(info));
}
}
return _packages;
}
}

View File

@ -17,6 +17,7 @@ import 'base/platform.dart';
import 'base/template.dart';
import 'base/version.dart';
import 'cache.dart';
import 'compute_dev_dependencies.dart';
import 'convert.dart';
import 'dart/language_version.dart';
import 'dart/package_map.dart';
@ -40,8 +41,13 @@ Future<void> _renderTemplateToFile(
await file.writeAsString(renderedTemplate);
}
Future<Plugin?> _pluginFromPackage(String name, Uri packageRoot, Set<String> appDependencies,
{FileSystem? fileSystem}) async {
Future<Plugin?> _pluginFromPackage(
String name,
Uri packageRoot,
Set<String> appDependencies, {
required Set<String> devDependencies,
FileSystem? fileSystem,
}) async {
final FileSystem fs = fileSystem ?? globals.fs;
final File pubspecFile = fs.file(packageRoot.resolve('pubspec.yaml'));
if (!pubspecFile.existsSync()) {
@ -76,10 +82,36 @@ Future<Plugin?> _pluginFromPackage(String name, Uri packageRoot, Set<String> app
dependencies == null ? <String>[] : <String>[...dependencies.keys.cast<String>()],
fileSystem: fs,
appDependencies: appDependencies,
isDevDependency: devDependencies.contains(name),
);
}
Future<List<Plugin>> findPlugins(FlutterProject project, { bool throwOnError = true}) async {
/// Returns a list of all plugins to be registered with the provided [project].
///
/// [useImplicitPubspecResolution] defines if legacy rules for traversing the
/// pub dependencies of a package implies, namely, that if `true`, all plugins
/// are assumed to be non-dev dependencies. Code that calls [findPlugins] in
/// order to obtain _other_ information about the plugins, such as whether a
/// plugin uses a specific language or platform can safely pass either `true`
/// or `false`; however a value of `false` _will_ cause `dart pub deps --json`
/// to trigger, which in turn could have other side-effects.
///
/// Please reach out to matanlurey@ if you find you need:
/// ```dart
/// useImplicitPubspecResolution: true
/// ```
///
/// ... in order for your code to function, as that path is being deprecated:
/// <https://flutter.dev/to/flutter-gen-deprecation>.
///
/// ---
///
/// If [throwOnError] is `true`, an empty package configuration is an error.
Future<List<Plugin>> findPlugins(
FlutterProject project, {
required bool useImplicitPubspecResolution,
bool throwOnError = true,
}) async {
final List<Plugin> plugins = <Plugin>[];
final FileSystem fs = project.directory.fileSystem;
final File packageConfigFile = findPackageConfigFileOrDefault(project.directory);
@ -88,12 +120,26 @@ Future<List<Plugin>> findPlugins(FlutterProject project, { bool throwOnError = t
logger: globals.logger,
throwOnError: throwOnError,
);
final Set<String> devDependencies;
if (useImplicitPubspecResolution) {
// With --implicit-pubspec-resolution, we do not want to check for what
// plugins are dev dependencies and instead continue to assume the previous
// behavior (all plugins are non-dev dependencies).
devDependencies = <String>{};
} else {
devDependencies = await computeExclusiveDevDependencies(
globals.processManager,
logger: globals.logger,
projectPath: project.directory.path,
);
}
for (final Package package in packageConfig.packages) {
final Uri packageRoot = package.packageUriRoot.resolve('..');
final Plugin? plugin = await _pluginFromPackage(
package.name,
packageRoot,
project.manifest.dependencies,
devDependencies: devDependencies,
fileSystem: fs,
);
if (plugin != null) {
@ -1010,14 +1056,14 @@ Future<void> refreshPluginsList(
bool iosPlatform = false,
bool macOSPlatform = false,
bool forceCocoaPodsOnly = false,
required bool writeLegacyPluginsList,
required bool useImplicitPubspecResolution,
}) async {
final List<Plugin> plugins = await findPlugins(project);
final List<Plugin> plugins = await findPlugins(project, useImplicitPubspecResolution: useImplicitPubspecResolution);
// Sort the plugins by name to keep ordering stable in generated files.
plugins.sort((Plugin left, Plugin right) => left.name.compareTo(right.name));
// TODO(matanlurey): Remove once migration is complete.
// Write the legacy plugin files to avoid breaking existing apps.
final bool legacyChanged = writeLegacyPluginsList && _writeFlutterPluginsListLegacy(project, plugins);
final bool legacyChanged = useImplicitPubspecResolution && _writeFlutterPluginsListLegacy(project, plugins);
final bool changed = _writeFlutterPluginsList(
project,
@ -1055,7 +1101,7 @@ Future<void> injectBuildTimePluginFilesForWebPlatform(
FlutterProject project, {
required Directory destination,
}) async {
final List<Plugin> plugins = await findPlugins(project);
final List<Plugin> plugins = await findPlugins(project, useImplicitPubspecResolution: true);
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(plugins, pluginResolutionType: _PluginResolutionType.nativeOrDart);
await _writeWebPluginRegistrant(project, pluginsByPlatform[WebPlugin.kConfigKey]!, destination);
}
@ -1074,6 +1120,7 @@ Future<void> injectBuildTimePluginFilesForWebPlatform(
/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`.
Future<void> injectPlugins(
FlutterProject project, {
required bool useImplicitPubspecResolution,
bool androidPlatform = false,
bool iosPlatform = false,
bool linuxPlatform = false,
@ -1082,7 +1129,7 @@ Future<void> injectPlugins(
Iterable<String>? allowedPlugins,
DarwinDependencyManagement? darwinDependencyManagement,
}) async {
final List<Plugin> plugins = await findPlugins(project);
final List<Plugin> plugins = await findPlugins(project, useImplicitPubspecResolution: useImplicitPubspecResolution);
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(plugins, pluginResolutionType: _PluginResolutionType.nativeOrDart);
if (androidPlatform) {
@ -1510,7 +1557,7 @@ Future<void> generateMainDartWithPluginRegistrant(
String currentMainUri,
File mainFile,
) async {
final List<Plugin> plugins = await findPlugins(rootProject);
final List<Plugin> plugins = await findPlugins(rootProject, useImplicitPubspecResolution: true);
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
plugins,
selectDartPluginsOnly: true,

View File

@ -938,7 +938,7 @@ Future<bool> _isPluginSwiftPackageOnly({
required String pluginName,
required FileSystem fileSystem,
}) async {
final List<Plugin> plugins = await findPlugins(project);
final List<Plugin> plugins = await findPlugins(project, useImplicitPubspecResolution: true);
final Plugin? matched = plugins
.where((Plugin plugin) =>
plugin.name.toLowerCase() == pluginName.toLowerCase() &&

View File

@ -22,7 +22,9 @@ Future<void> processPodsIfNeeded(
// When using Swift Package Manager, the Podfile may not exist so if there
// isn't a Podfile, skip processing pods.
if (project.usesSwiftPackageManager && !xcodeProject.podfile.existsSync() && !forceCocoaPodsOnly) {
if (project.usesSwiftPackageManager &&
!xcodeProject.podfile.existsSync() &&
!forceCocoaPodsOnly) {
return;
}
// Ensure that the plugin list is up to date, since hasPlugins relies on it.
@ -36,12 +38,13 @@ Future<void> processPodsIfNeeded(
// file being generated. A better long-term fix would be not to have a call to refreshPluginsList
// at all, and instead have it implicitly run by the FlutterCommand instead. See
// https://github.com/flutter/flutter/issues/157391 for details.
writeLegacyPluginsList: false,
useImplicitPubspecResolution: false,
);
// If there are no plugins and if the project is a not module with an existing
// podfile, skip processing pods
if (!hasPlugins(project) && !(project.isModule && xcodeProject.podfile.existsSync())) {
if (!hasPlugins(project) &&
!(project.isModule && xcodeProject.podfile.existsSync())) {
return;
}
@ -66,7 +69,8 @@ Future<void> processPodsIfNeeded(
// If the Xcode project, Podfile, generated plugin Swift Package, or podhelper
// have changed since last run, pods should be updated.
final Fingerprinter fingerprinter = Fingerprinter(
fingerprintPath: globals.fs.path.join(buildDirectory, 'pod_inputs.fingerprint'),
fingerprintPath:
globals.fs.path.join(buildDirectory, 'pod_inputs.fingerprint'),
paths: <String>[
xcodeProject.xcodeProjectInfoFile.path,
xcodeProject.podfile.path,
@ -85,10 +89,11 @@ Future<void> processPodsIfNeeded(
);
final bool didPodInstall = await globals.cocoaPods?.processPods(
xcodeProject: xcodeProject,
buildMode: buildMode,
dependenciesChanged: !fingerprinter.doesFingerprintMatch(),
) ?? false;
xcodeProject: xcodeProject,
buildMode: buildMode,
dependenciesChanged: !fingerprinter.doesFingerprintMatch(),
) ??
false;
if (didPodInstall) {
fingerprinter.writeFingerprint();
}

View File

@ -19,6 +19,7 @@ class Plugin {
this.flutterConstraint,
required this.dependencies,
required this.isDirectDependency,
required this.isDevDependency,
this.implementsPackage,
});
@ -68,6 +69,7 @@ class Plugin {
VersionConstraint? flutterConstraint,
List<String> dependencies, {
required FileSystem fileSystem,
required bool isDevDependency,
Set<String>? appDependencies,
}) {
final List<String> errors = validatePluginYaml(pluginYaml);
@ -82,6 +84,7 @@ class Plugin {
flutterConstraint,
dependencies,
fileSystem,
isDevDependency: isDevDependency,
appDependencies != null && appDependencies.contains(name),
);
}
@ -92,6 +95,7 @@ class Plugin {
flutterConstraint,
dependencies,
fileSystem,
isDevDependency: isDevDependency,
appDependencies != null && appDependencies.contains(name),
);
}
@ -103,8 +107,9 @@ class Plugin {
VersionConstraint? flutterConstraint,
List<String> dependencies,
FileSystem fileSystem,
bool isDirectDependency,
) {
bool isDirectDependency, {
required bool isDevDependency,
}) {
assert (pluginYaml['platforms'] != null, 'Invalid multi-platform plugin specification $name.');
final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
@ -184,6 +189,7 @@ class Plugin {
dependencies: dependencies,
isDirectDependency: isDirectDependency,
implementsPackage: pluginYaml['implements'] != null ? pluginYaml['implements'] as String : '',
isDevDependency: isDevDependency,
);
}
@ -194,8 +200,9 @@ class Plugin {
VersionConstraint? flutterConstraint,
List<String> dependencies,
FileSystem fileSystem,
bool isDirectDependency,
) {
bool isDirectDependency, {
required bool isDevDependency,
}) {
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
final String? pluginClass = (pluginYaml as Map<dynamic, dynamic>)['pluginClass'] as String?;
if (pluginClass != null) {
@ -227,6 +234,7 @@ class Plugin {
flutterConstraint: flutterConstraint,
dependencies: dependencies,
isDirectDependency: isDirectDependency,
isDevDependency: isDevDependency,
);
}
@ -407,6 +415,16 @@ class Plugin {
/// If [false], the plugin is a dependency of another plugin.
final bool isDirectDependency;
/// Whether this plugin is exclusively used as a dev dependency of the app.
///
/// If [false], the plugin is either:
/// - _Not_ a dev dependency
/// - _Not_ a dev dependency of some dependency that itself is not a dev
/// dependency
///
/// Dev dependencies are intended to be stripped out in release builds.
final bool isDevDependency;
/// Expected path to the plugin's Package.swift. Returns null if the plugin
/// does not support the [platform] or the [platform] is not iOS or macOS.
String? pluginSwiftPackageManifestPath(

View File

@ -340,7 +340,7 @@ class FlutterProject {
Future<void> regeneratePlatformSpecificTooling({
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
Iterable<String>? allowedPlugins,
required bool writeLegacyPluginsList,
required bool useImplicitPubspecResolution,
}) async {
return ensureReadyForPlatformSpecificTooling(
androidPlatform: android.existsSync(),
@ -353,7 +353,7 @@ class FlutterProject {
webPlatform: featureFlags.isWebEnabled && web.existsSync(),
deprecationBehavior: deprecationBehavior,
allowedPlugins: allowedPlugins,
writeLegacyPluginsList: writeLegacyPluginsList,
useImplicitPubspecResolution: useImplicitPubspecResolution,
);
}
@ -368,7 +368,7 @@ class FlutterProject {
bool webPlatform = false,
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
Iterable<String>? allowedPlugins,
required bool writeLegacyPluginsList,
required bool useImplicitPubspecResolution,
}) async {
if (!directory.existsSync() || isPlugin) {
return;
@ -377,7 +377,7 @@ class FlutterProject {
this,
iosPlatform: iosPlatform,
macOSPlatform: macOSPlatform,
writeLegacyPluginsList: writeLegacyPluginsList,
useImplicitPubspecResolution: useImplicitPubspecResolution,
);
if (androidPlatform) {
await android.ensureReadyForPlatformSpecificTooling(deprecationBehavior: deprecationBehavior);
@ -405,6 +405,7 @@ class FlutterProject {
macOSPlatform: macOSPlatform,
windowsPlatform: windowsPlatform,
allowedPlugins: allowedPlugins,
useImplicitPubspecResolution: useImplicitPubspecResolution,
);
}

View File

@ -1793,7 +1793,7 @@ Run 'flutter -h' (or 'flutter <command> -h') for available flutter commands and
}
await project.regeneratePlatformSpecificTooling(
allowedPlugins: allowedPlugins,
writeLegacyPluginsList: boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true),
useImplicitPubspecResolution: boolArg(FlutterGlobalOptions.kImplicitPubspecResolution, global: true),
);
if (reportNullSafety) {
await _sendNullSafetyAnalyticsEvents(project);

View File

@ -75,7 +75,7 @@ class WebBuilder {
String? outputDirectoryPath,
}) async {
final bool hasWebPlugins =
(await findPlugins(flutterProject)).any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
(await findPlugins(flutterProject, useImplicitPubspecResolution: true)).any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
final Directory outputDirectory = outputDirectoryPath == null
? _fileSystem.directory(getWebBuildDirectory())
: _fileSystem.directory(outputDirectoryPath);

View File

@ -114,6 +114,13 @@ void main() {
'xattr', '-r', '-d', 'com.apple.FinderInfo', '/',
]);
const FakeCommand dartPubDepsCommand = FakeCommand(command: <String>[
'dart',
'pub',
'deps',
'--json',
]);
FakeCommand setUpRsyncCommand({void Function(List<String> command)? onRun}) {
return FakeCommand(
command: const <String>[
@ -300,6 +307,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
}),
@ -323,6 +331,7 @@ void main() {
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
}),
@ -360,6 +369,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
disablePortPublication: true,
onRun: (_) {
@ -392,6 +402,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
@ -416,6 +427,7 @@ void main() {
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(customNaming: true, onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
}),
@ -450,6 +462,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(deviceId: '1234', onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
}),
@ -480,6 +493,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(simulator: true, onRun: (_) {
fileSystem.directory('build/ios/Debug-iphonesimulator/Runner.app').createSync(recursive: true);
}),
@ -510,6 +524,7 @@ void main() {
createMinimalMockProjectFiles();
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(verbose: true, onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
}),
@ -538,6 +553,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
fileSystem.file('build/flutter_size_01/snapshot.arm64.json')
@ -624,6 +640,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app')
.createSync(recursive: true);
@ -678,6 +695,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.directory('build/ios/Release-iphoneos/Runner.app')
.createSync(recursive: true);
@ -721,6 +739,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
@ -756,6 +775,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}, stdout: 'Lots of spew from Xcode',
@ -795,6 +815,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
@ -833,6 +854,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1),
setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
setUpRsyncCommand(),
@ -865,6 +887,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
@ -904,6 +927,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: (_) {
@ -943,6 +967,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
@ -978,6 +1003,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
// Intentionally fail the first xcodebuild command with concurrent run failure message.
setUpFakeXcodeBuildHandler(
exitCode: 1,
@ -1025,6 +1051,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
stdout: '''
@ -1066,6 +1093,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: (_) {
@ -1115,6 +1143,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
stdout: '''
@ -1144,6 +1173,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: (_) {
@ -1181,6 +1211,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: (_) {
@ -1220,6 +1251,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: (_) {
@ -1261,6 +1293,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
@ -1300,6 +1333,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
@ -1341,6 +1375,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
@ -1383,6 +1418,7 @@ Runner requires a provisioning profile. Select a provisioning profile in the Sig
);
processManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,

View File

@ -140,6 +140,13 @@ void main() {
'xattr', '-r', '-d', 'com.apple.FinderInfo', '/',
]);
const FakeCommand dartPubDepsCommand = FakeCommand(command: <String>[
'dart',
'pub',
'deps',
'--json',
]);
FakeCommand setUpXCResultCommand({String stdout = '', void Function(List<String> command)? onRun}) {
return FakeCommand(
command: const <String>[
@ -398,6 +405,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
@ -429,6 +437,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -475,6 +484,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -521,6 +531,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -566,6 +577,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
@ -595,6 +607,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -640,6 +653,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
@ -668,6 +682,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: exportOptions.path),
]);
@ -707,6 +722,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
const FakeCommand(
command: <String>[
@ -762,6 +778,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(
exportOptionsPlist: _exportOptionsPlist,
@ -796,6 +813,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -848,6 +866,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -900,6 +919,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
@ -951,6 +971,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(verbose: true),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
@ -980,6 +1001,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
@ -1008,6 +1030,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
const FakeCommand(
command: <String>[
'xcrun',
@ -1060,6 +1083,7 @@ void main() {
);
createMinimalMockProjectFiles();
fakeProcessManager.addCommand(dartPubDepsCommand);
fakeProcessManager.addCommand(setUpFakeXcodeBuildHandler());
await expectToolExitLater(
createTestCommandRunner(command).run(
@ -1091,6 +1115,7 @@ void main() {
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0));
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file('build/flutter_size_01/snapshot.arm64.json')
..createSync(recursive: true)
@ -1146,6 +1171,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(),
exportArchiveCommand(),
]);
@ -1183,6 +1209,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
@ -1217,6 +1244,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
@ -1252,6 +1280,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
@ -1289,6 +1318,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1),
]);
createMinimalMockProjectFiles();
@ -1321,6 +1351,7 @@ void main() {
);
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: (_) {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
@ -1353,6 +1384,7 @@ void main() {
const String plistPath = 'build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Info.plist';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(plistPath).createSync(recursive: true);
}),
@ -1406,6 +1438,7 @@ void main() {
const String plistPath = 'build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Info.plist';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(plistPath).createSync(recursive: true);
}),
@ -1465,6 +1498,7 @@ void main() {
const String plistPath = 'build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Info.plist';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(plistPath).createSync(recursive: true);
}),
@ -1524,6 +1558,7 @@ void main() {
const String plistPath = 'build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Info.plist';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(plistPath).createSync(recursive: true);
}),
@ -1567,6 +1602,7 @@ void main() {
const String plistPath = 'build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Info.plist';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(plistPath).createSync(recursive: true);
}),
@ -1613,6 +1649,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(templateIconContentsJsonPath)
..createSync(recursive: true)
@ -1695,6 +1732,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(templateIconContentsJsonPath)
..createSync(recursive: true)
@ -1775,6 +1813,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(projectIconContentsJsonPath)
..createSync(recursive: true)
@ -1837,6 +1876,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(projectIconContentsJsonPath)
..createSync(recursive: true)
@ -1900,6 +1940,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(projectIconContentsJsonPath)
..createSync(recursive: true)
@ -1962,6 +2003,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
// Uses unknown format version 123.
fileSystem.file(projectIconContentsJsonPath)
@ -2034,6 +2076,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
// The following json contains examples of:
// - invalid size
@ -2139,6 +2182,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(templateLaunchImageContentsJsonPath)
..createSync(recursive: true)
@ -2220,6 +2264,7 @@ void main() {
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(onRun: (_) {
fileSystem.file(templateLaunchImageContentsJsonPath)
..createSync(recursive: true)

View File

@ -105,6 +105,13 @@ void main() {
createCoreMockProjectFiles();
}
const FakeCommand dartPubDepsCommand = FakeCommand(command: <String>[
'dart',
'pub',
'deps',
'--json',
]);
// Creates a FakeCommand for the xcodebuild call to build the app
// in the given configuration.
FakeCommand setUpFakeXcodeBuildHandler(
@ -300,6 +307,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Debug'),
]),
Platform: () => macosPlatform,
@ -325,6 +333,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Release'),
]),
Platform: () => macosPlatform,
@ -349,6 +358,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Debug'),
]),
Platform: () => macosPlatform,
@ -373,6 +383,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Debug', verbose: true),
]),
Platform: () => macosPlatform,
@ -398,6 +409,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Profile'),
]),
Platform: () => macosPlatform,
@ -423,6 +435,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Release'),
]),
Platform: () => macosPlatform,
@ -486,6 +499,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Release'),
]),
Platform: () => macosPlatform,
@ -504,6 +518,7 @@ STDERR STUFF
createMinimalMockProjectFiles();
fakeProcessManager.addCommands(<FakeCommand>[
dartPubDepsCommand,
FakeCommand(
command: <String>[
'/usr/bin/env',
@ -577,6 +592,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler('Debug'),
]),
Platform: () => macosPlatform,
@ -648,6 +664,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
// we never generate code size snapshot here
setUpFakeXcodeBuildHandler('Release'),
]),
@ -682,6 +699,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
// These are generated by gen_snapshot because flutter assemble passes
// extra flags specifying this output path
setUpFakeXcodeBuildHandler('Release', onRun: (_) {
@ -753,6 +771,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
'Debug',
additionalCommandArguements: <String>[
@ -821,6 +840,7 @@ STDERR STUFF
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
dartPubDepsCommand,
setUpFakeXcodeBuildHandler(
'Release',
additionalCommandArguements: <String>[

View File

@ -53,7 +53,7 @@ void main() {
fileSystem.file(fileSystem.path.join('lib', 'main.dart')).createSync(recursive: true);
artifacts = Artifacts.test(fileSystem: fileSystem);
logger = BufferLogger.test();
processManager = FakeProcessManager.empty();
processManager = FakeProcessManager.any();
processUtils = ProcessUtils(
logger: logger,
processManager: processManager,
@ -170,7 +170,7 @@ void main() {
Platform: () => fakePlatform,
FileSystem: () => fileSystem,
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
ProcessManager: () => FakeProcessManager.any(),
ProcessManager: () => processManager,
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
expect(environment.defines, <String, String>{
'TargetFile': 'lib/main.dart',

View File

@ -180,6 +180,8 @@ void main() {
.childDirectory('flutter_build')
.childFile('dart_plugin_registrant.dart');
expect(generatedMain.existsSync(), isFalse);
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('regenerates dart_plugin_registrant.dart', () async {
@ -257,6 +259,8 @@ void main() {
'}\n'
),
);
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('removes dart_plugin_registrant.dart if plugins are removed from pubspec.yaml', () async {
@ -301,6 +305,8 @@ void main() {
await DartPluginRegistrantTarget.test(testProject).build(environment);
expect(generatedMain.existsSync(), isFalse);
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('target file is outside the current project package', () async {
@ -379,6 +385,8 @@ void main() {
'}\n'
),
);
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
});
}

View File

@ -0,0 +1,426 @@
// 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:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/compute_dev_dependencies.dart';
import '../src/common.dart';
import '../src/fake_process_manager.dart';
// For all of these examples, imagine the following package structure:
//
// /
// /my_app
// pubspec.yaml
// /package_a
// pubspec.yaml
// /pacakge_b
// pubspec.yaml
// /package_c
// pubspec.yaml
void main() {
late BufferLogger logger;
setUp(() {
logger = BufferLogger.test();
});
test('no dev dependencies at all', () async {
// Simulates the following:
//
// # /my_app/pubspec.yaml
// name: my_app
// dependencies:
// package_a:
//
// # /package_a/pubspec.yaml
// name: package_a
// dependencies:
// package_b:
final ProcessManager processes = _dartPubDepsReturns('''
{
"root": "my_app",
"packages": [
{
"name": "my_app",
"kind": "root",
"dependencies": [
"package_a",
"package_b"
],
"directDependencies": [
"package_a"
],
"devDependencies": []
},
{
"name": "package_a",
"kind": "direct",
"dependencies": [
"package_b"
],
"directDependencies": [
"package_b"
]
},
{
"name": "package_b",
"kind": "transitive",
"dependencies": [],
"directDependencies": []
}
]
}''');
final Set<String> dependencies = await computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
);
expect(
dependencies,
isEmpty,
reason: 'There are no dev_dependencies of "my_app".',
);
});
test('dev dependency', () async {
// Simulates the following:
//
// # /my_app/pubspec.yaml
// name: my_app
// dependencies:
// package_a:
//
// dev_dependencies:
// package_b:
//
// # /package_a/pubspec.yaml
// name: package_a
final ProcessManager processes = _dartPubDepsReturns('''
{
"root": "my_app",
"packages": [
{
"name": "my_app",
"kind": "root",
"dependencies": [
"package_a",
"package_b"
],
"directDependencies": [
"package_a"
],
"devDependencies": [
"package_b"
]
},
{
"name": "package_a",
"kind": "direct",
"dependencies": [],
"directDependencies": []
},
{
"name": "package_b",
"kind": "dev",
"dependencies": [],
"directDependencies": []
}
]
}''');
final Set<String> dependencies = await computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
);
expect(
dependencies,
<String>{'package_b'},
reason: 'There is a single dev_dependency of my_app: package_b.',
);
});
test('dev used as a non-dev dependency transitively', () async {
// Simulates the following:
//
// # /my_app/pubspec.yaml
// name: my_app
// dependencies:
// package_a:
//
// dev_dependencies:
// package_b:
//
// # /package_a/pubspec.yaml
// name: package_a
// dependencies:
// package_b:
final ProcessManager processes = _dartPubDepsReturns('''
{
"root": "my_app",
"packages": [
{
"name": "my_app",
"kind": "root",
"dependencies": [
"package_a",
"package_b"
],
"directDependencies": [
"package_a"
],
"devDependencies": [
"package_b"
]
},
{
"name": "package_a",
"kind": "direct",
"dependencies": [
"package_b"
],
"directDependencies": [
"package_b"
]
},
{
"name": "package_b",
"kind": "dev",
"dependencies": [],
"directDependencies": []
}
]
}''');
final Set<String> dependencies = await computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
);
expect(
dependencies,
isEmpty,
reason: 'There is a dev_dependency also used as a standard dependency',
);
});
test('combination of an included and excluded dev_dependency', () async {
// Simulates the following:
//
// # /my_app/pubspec.yaml
// name: my_app
// dependencies:
// package_a:
//
// dev_dependencies:
// package_b:
// package_c:
//
// # /package_a/pubspec.yaml
// name: package_a
// dependencies:
// package_b:
//
// # /package_b/pubspec.yaml
// name: package_b
//
// # /package_c/pubspec.yaml
// name: package_c
final ProcessManager processes = _dartPubDepsReturns('''
{
"root": "my_app",
"packages": [
{
"name": "my_app",
"kind": "root",
"dependencies": [
"package_a",
"package_b"
],
"directDependencies": [
"package_a"
],
"devDependencies": [
"package_b",
"package_c"
]
},
{
"name": "package_a",
"kind": "direct",
"dependencies": [
"package_b"
],
"directDependencies": [
"package_b"
]
},
{
"name": "package_b",
"kind": "dev",
"dependencies": [
"package_c"
],
"directDependencies": [
"package_c"
]
},
{
"name": "package_c",
"kind": "dev",
"dependencies": [],
"directDependencies": []
}
]
}''');
final Set<String> dependencies = await computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
);
expect(
dependencies,
<String>{'package_c'},
reason: 'package_b is excluded but package_c should not',
);
});
test('throws and logs on non-zero exit code', () async {
final ProcessManager processes = _dartPubDepsFails(
'Bad thing',
exitCode: 1,
);
await expectLater(
computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
),
throwsA(
isA<StateError>().having(
(StateError e) => e.message,
'message',
contains('dart pub deps --json failed'),
),
),
);
expect(logger.traceText, isEmpty);
});
test('throws and logs on unexpected output type', () async {
final ProcessManager processes = _dartPubDepsReturns(
'Not JSON haha!',
);
await expectLater(
computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
),
throwsA(
isA<StateError>().having(
(StateError e) => e.message,
'message',
contains('dart pub deps --json had unexpected output'),
),
),
);
expect(logger.traceText, contains('Not JSON haha'));
});
test('throws and logs on invalid JSON', () async {
final ProcessManager processes = _dartPubDepsReturns('''
{
"root": "my_app",
"packages": [
{
"name": "my_app",
"kind": "root",
"dependencies": [
"package_a",
"package_b"
],
"directDependencies": [
1
],
"devDependencies": []
},
{
"name": "package_a",
"kind": "direct",
"dependencies": [
"package_b"
],
"directDependencies": [
"package_b"
]
},
{
"name": "package_b",
"kind": "transitive",
"dependencies": [],
"directDependencies": []
}
]
}''');
await expectLater(
computeExclusiveDevDependencies(
processes,
projectPath: _fakeProjectPath,
logger: logger,
),
throwsA(
isA<StateError>().having(
(StateError e) => e.message,
'message',
contains('dart pub deps --json had unexpected output'),
),
),
);
expect(
logger.traceText,
contains('"root": "my_app"'),
reason: 'Stdout should include the JSON blob',
);
});
}
const String _fakeProjectPath = '/path/to/project';
ProcessManager _dartPubDepsReturns(String dartPubDepsOutput) {
return FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: const <String>['dart', 'pub', 'deps', '--json'],
stdout: dartPubDepsOutput,
workingDirectory: _fakeProjectPath,
),
]);
}
ProcessManager _dartPubDepsFails(
String dartPubDepsError, {
required int exitCode,
}) {
return FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: const <String>['dart', 'pub', 'deps', '--json'],
exitCode: exitCode,
stderr: dartPubDepsError,
workingDirectory: _fakeProjectPath,
),
]);
}

View File

@ -64,6 +64,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -80,6 +81,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -130,6 +132,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -146,6 +149,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -183,6 +187,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -199,6 +204,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -245,6 +251,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -295,6 +302,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -329,6 +337,7 @@ void main() {
VersionConstraint.parse('>=2.10.0'),
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -362,6 +371,7 @@ void main() {
VersionConstraint.parse('>=2.11.0'),
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -411,6 +421,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
// Include three possible implementations, one before and one after
@ -430,6 +441,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -446,6 +458,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -462,6 +475,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -496,6 +510,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -512,6 +527,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -549,6 +565,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -565,6 +582,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -581,6 +599,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -621,6 +640,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -637,6 +657,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -683,6 +704,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -699,6 +721,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -715,6 +738,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -757,6 +781,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -773,6 +798,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -810,6 +836,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -822,6 +849,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -856,6 +884,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -872,6 +901,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -899,6 +929,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -915,6 +946,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -952,6 +984,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -990,6 +1023,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -1006,6 +1040,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -1050,6 +1085,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -1066,6 +1102,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -1082,6 +1119,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -1098,6 +1136,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],
@ -1142,6 +1181,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
Plugin.fromYaml(
@ -1158,6 +1198,7 @@ void main() {
null,
<String>[],
fileSystem: fs,
isDevDependency: false,
appDependencies: directDependencies,
),
],

View File

@ -69,6 +69,18 @@ const List<String> kRunReleaseArgs = <String>[
'COMPILER_INDEX_STORE_ENABLE=NO',
];
// TODO(matanlurey): XCode builds call processPodsIfNeeded -> refreshPluginsList
// ... which in turn requires that `dart pub deps --json` is called in order to
// label which plugins are dependency plugins.
//
// Ideally processPodsIfNeeded should rely on the command (removing this call).
const List<String> kCheckDartPubDeps = <String> [
'dart',
'pub',
'deps',
'--json',
];
const String kConcurrentBuildErrorMessage = '''
"/Developer/Xcode/DerivedData/foo/XCBuildData/build.db":
database is locked
@ -132,6 +144,7 @@ void main() {
final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter', 'My Super Awesome App');
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
processManager.addCommand(const FakeCommand(command: kCheckDartPubDeps));
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
final LaunchResult launchResult = await iosDevice.startApp(
@ -206,6 +219,7 @@ void main() {
fileSystem.directory('build/ios/Release-iphoneos/My Super Awesome App.app').createSync(recursive: true);
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
processManager.addCommand(const FakeCommand(command: kCheckDartPubDeps));
processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
processManager.addCommand(const FakeCommand(command: <String>[
'rsync',
@ -266,6 +280,7 @@ void main() {
fileSystem.directory('build/ios/Release-iphoneos/My Super Awesome App.app').createSync(recursive: true);
processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
processManager.addCommand(const FakeCommand(command: kCheckDartPubDeps));
processManager.addCommand(const FakeCommand(command: <String>[
'xcrun',
'xcodebuild',

View File

@ -626,7 +626,7 @@ duplicate symbol '_$s29plugin_1_name23PluginNamePluginC9setDouble3key5valueySS_S
));
});
testUsingContext('parses missing module error', () async{
testUsingContext('parses missing module error', () async {
const List<String> buildCommands = <String>['xcrun', 'cc', 'blah'];
final XcodeBuildResult buildResult = XcodeBuildResult(
success: false,
@ -663,6 +663,8 @@ duplicate symbol '_$s29plugin_1_name23PluginNamePluginC9setDouble3key5valueySS_S
'Your project uses CocoaPods as a dependency manager, but the following plugin(s) '
'only support Swift Package Manager: plugin_1_name, plugin_2_name.'
));
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
});

View File

@ -345,7 +345,7 @@ void main() {
..writeAsStringSync('Existing release config');
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.directory('project'));
await injectPlugins(project, iosPlatform: true);
await injectPlugins(project, iosPlatform: true, useImplicitPubspecResolution: true);
final String debugContents = projectUnderTest.ios.xcodeConfigFor('Debug').readAsStringSync();
expect(debugContents, contains(

View File

@ -27,6 +27,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -67,6 +68,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -117,6 +119,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -162,6 +165,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -210,6 +214,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -239,6 +244,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(
@ -263,6 +269,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(
@ -287,6 +294,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(
@ -311,6 +319,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(
@ -336,6 +345,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(
@ -361,6 +371,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(message: _kTestPluginName),
@ -391,6 +402,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -423,6 +435,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -449,6 +462,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -473,6 +487,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(
@ -495,6 +510,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -520,6 +536,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
);
@ -538,6 +555,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(message: 'Invalid "plugin" specification.'),
@ -556,6 +574,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(message: 'Invalid "platforms" specification.'),
@ -576,6 +595,7 @@ void main() {
pluginYaml,
null,
const <String>[],
isDevDependency: false,
fileSystem: fileSystem,
),
throwsToolExit(message: 'Invalid "android" plugin specification.'),

View File

@ -402,7 +402,7 @@ dependencies:
group('refreshPlugins', () {
testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () async {
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(flutterProject.flutterPluginsFile.existsSync(), false);
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), false);
@ -415,7 +415,7 @@ dependencies:
flutterProject.flutterPluginsFile.createSync();
flutterProject.flutterPluginsDependenciesFile.createSync();
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(flutterProject.flutterPluginsFile.existsSync(), false);
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), false);
@ -434,7 +434,7 @@ dependencies:
iosProject.testExists = true;
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(flutterProject.flutterPluginsFile.existsSync(), true);
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true);
@ -448,7 +448,7 @@ dependencies:
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('Opting out of writeLegacyPluginsList omits .flutter-plugins', () async {
testUsingContext('Opting out of useImplicitPubspecResolution omits .flutter-plugins', () async {
createFakePlugins(fs, <String>[
'plugin_d',
'plugin_a',
@ -456,10 +456,13 @@ dependencies:
'/local_plugins/plugin_b',
]);
await refreshPluginsList(flutterProject, writeLegacyPluginsList: false);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: false);
expect(flutterProject.flutterPluginsFile, isNot(exists));
expect(flutterProject.flutterPluginsDependenciesFile, exists);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext(
@ -473,7 +476,7 @@ dependencies:
final DateTime dateCreated = DateTime(1970);
systemClock.currentTime = dateCreated;
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
// Verify .flutter-plugins-dependencies is configured correctly.
expect(flutterProject.flutterPluginsFile.existsSync(), true);
@ -583,7 +586,7 @@ dependencies:
final DateTime dateCreated = DateTime(1970);
systemClock.currentTime = dateCreated;
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true);
final String pluginsString = flutterProject.flutterPluginsDependenciesFile.readAsStringSync();
@ -655,7 +658,7 @@ dependencies:
flutterProject.usesSwiftPackageManager = true;
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true);
final String pluginsString = flutterProject.flutterPluginsDependenciesFile
@ -692,7 +695,7 @@ dependencies:
flutterProject.usesSwiftPackageManager = true;
await refreshPluginsList(flutterProject, forceCocoaPodsOnly: true, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, forceCocoaPodsOnly: true, useImplicitPubspecResolution: true);
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true);
final String pluginsString = flutterProject.flutterPluginsDependenciesFile
@ -714,7 +717,7 @@ dependencies:
iosProject.testExists = true;
macosProject.exists = true;
await refreshPluginsList(flutterProject, iosPlatform: true, macOSPlatform: true, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, iosPlatform: true, macOSPlatform: true, useImplicitPubspecResolution: true);
expect(iosProject.podManifestLock.existsSync(), false);
expect(macosProject.podManifestLock.existsSync(), false);
}, overrides: <Type, Generator>{
@ -733,11 +736,11 @@ dependencies:
// Since there was no plugins list, the lock files will be invalidated.
// The second call is where the plugins list is compared to the existing one, and if there is no change,
// the podfiles shouldn't be invalidated.
await refreshPluginsList(flutterProject, iosPlatform: true, macOSPlatform: true, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, iosPlatform: true, macOSPlatform: true, useImplicitPubspecResolution: true);
simulatePodInstallRun(iosProject);
simulatePodInstallRun(macosProject);
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(iosProject.podManifestLock.existsSync(), true);
expect(macosProject.podManifestLock.existsSync(), true);
}, overrides: <Type, Generator>{
@ -758,7 +761,7 @@ dependencies:
testUsingContext('Registrant uses new embedding if app uses new embedding', () async {
androidProject.embeddingVersion = AndroidEmbeddingVersion.v2;
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrant = flutterProject.directory
.childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -781,7 +784,7 @@ dependencies:
await expectLater(
() async {
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
},
throwsToolExit(
message: "The plugin `plugin1` doesn't have a main class defined in "
@ -803,7 +806,7 @@ dependencies:
createDualSupportJavaPlugin4();
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrant = flutterProject.directory
.childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -824,7 +827,7 @@ dependencies:
flutterProject.isModule = true;
androidProject.embeddingVersion = AndroidEmbeddingVersion.v2;
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrant = flutterProject.directory
.childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -845,7 +848,7 @@ dependencies:
createNewJavaPlugin1();
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrant = flutterProject.directory
.childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -866,7 +869,7 @@ dependencies:
createDualSupportJavaPlugin4();
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrant = flutterProject.directory
.childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -887,7 +890,7 @@ dependencies:
createDualSupportJavaPlugin4();
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrant = flutterProject.directory
.childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -905,7 +908,7 @@ dependencies:
testUsingContext('Does not throw when AndroidManifest.xml is not found', () async {
final File manifest = fs.file('AndroidManifest.xml');
androidProject.appManifestFile = manifest;
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
@ -1015,7 +1018,7 @@ flutter:
dartPluginClass: SomePlugin
''');
await injectPlugins(flutterProject, androidPlatform: true);
await injectPlugins(flutterProject, androidPlatform: true, useImplicitPubspecResolution: true);
final File registrantFile = androidProject.pluginRegistrantHost
.childDirectory(fs.path.join('src', 'main', 'java', 'io', 'flutter', 'plugins'))
@ -1044,6 +1047,7 @@ flutter:
flutterProject,
iosPlatform: true,
darwinDependencyManagement: dependencyManagement,
useImplicitPubspecResolution: true,
);
final File registrantFile = iosProject.pluginRegistrantImplementation;
@ -1071,6 +1075,7 @@ flutter:
flutterProject,
macOSPlatform: true,
darwinDependencyManagement: dependencyManagement,
useImplicitPubspecResolution: true,
);
final File registrantFile = macosProject.managedDirectory.childFile('GeneratedPluginRegistrant.swift');
@ -1099,6 +1104,7 @@ flutter:
flutterProject,
macOSPlatform: true,
darwinDependencyManagement: dependencyManagement,
useImplicitPubspecResolution: true,
);
final File registrantFile = macosProject.managedDirectory.childFile('GeneratedPluginRegistrant.swift');
@ -1123,6 +1129,7 @@ flutter:
flutterProject,
macOSPlatform: true,
darwinDependencyManagement: dependencyManagement,
useImplicitPubspecResolution: true,
);
final File registrantFile = macosProject.managedDirectory.childFile('GeneratedPluginRegistrant.swift');
@ -1136,7 +1143,7 @@ flutter:
testUsingContext('Injecting creates generated Linux registrant', () async {
createFakePlugin(fs);
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File registrantHeader = linuxProject.managedDirectory.childFile('generated_plugin_registrant.h');
final File registrantImpl = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1185,7 +1192,7 @@ dependencies:
flutterProject.manifest = manifest;
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File registrantImpl = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1243,7 +1250,7 @@ dependencies:
flutterProject.manifest = manifest;
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File registrantImpl = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1266,7 +1273,7 @@ flutter:
dartPluginClass: SomePlugin
''');
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File registrantImpl = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1290,7 +1297,7 @@ flutter:
dartPluginClass: SomePlugin
''');
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File registrantImpl = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1305,7 +1312,7 @@ flutter:
testUsingContext('Injecting creates generated Linux plugin Cmake file', () async {
createFakePlugin(fs);
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File pluginMakefile = linuxProject.generatedPluginCmakeFile;
@ -1328,7 +1335,7 @@ flutter:
'/local_plugins/plugin_b',
]);
await injectPlugins(flutterProject, linuxPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, useImplicitPubspecResolution: true);
final File pluginCmakeFile = linuxProject.generatedPluginCmakeFile;
final File pluginRegistrant = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1346,7 +1353,7 @@ flutter:
testUsingContext('Injecting creates generated Windows registrant', () async {
createFakePlugin(fs);
await injectPlugins(flutterProject, windowsPlatform: true);
await injectPlugins(flutterProject, windowsPlatform: true, useImplicitPubspecResolution: true);
final File registrantHeader = windowsProject.managedDirectory.childFile('generated_plugin_registrant.h');
final File registrantImpl = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1370,7 +1377,7 @@ flutter:
dartPluginClass: SomePlugin
''');
await injectPlugins(flutterProject, windowsPlatform: true);
await injectPlugins(flutterProject, windowsPlatform: true, useImplicitPubspecResolution: true);
final File registrantImpl = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1393,7 +1400,7 @@ flutter:
dartPluginClass: SomePlugin
''');
await injectPlugins(flutterProject, windowsPlatform: true);
await injectPlugins(flutterProject, windowsPlatform: true, useImplicitPubspecResolution: true);
final File registrantImpl = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1413,7 +1420,7 @@ flutter:
'/local_plugins/plugin_b',
]);
await injectPlugins(flutterProject, windowsPlatform: true);
await injectPlugins(flutterProject, windowsPlatform: true, useImplicitPubspecResolution: true);
final File pluginCmakeFile = windowsProject.generatedPluginCmakeFile;
final File pluginRegistrant = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@ -1433,7 +1440,7 @@ flutter:
setUpProject(fsWindows);
createFakePlugin(fsWindows);
await injectPlugins(flutterProject, linuxPlatform: true, windowsPlatform: true);
await injectPlugins(flutterProject, linuxPlatform: true, windowsPlatform: true, useImplicitPubspecResolution: true);
for (final CmakeBasedProject? project in <CmakeBasedProject?>[linuxProject, windowsProject]) {
final File pluginCmakefile = project!.generatedPluginCmakeFile;
@ -1458,6 +1465,7 @@ flutter:
linuxPlatform: true,
windowsPlatform: true,
allowedPlugins: PreviewDevice.supportedPubPlugins,
useImplicitPubspecResolution: true,
),
throwsToolExit(message: '''
The Flutter Preview device does not support the following plugins from your pubspec.yaml:
@ -1477,6 +1485,7 @@ The Flutter Preview device does not support the following plugins from your pubs
iosPlatform: true,
macOSPlatform: true,
darwinDependencyManagement: dependencyManagement,
useImplicitPubspecResolution: true,
);
expect(
dependencyManagement.setupPlatforms,
@ -1492,6 +1501,7 @@ The Flutter Preview device does not support the following plugins from your pubs
await injectPlugins(
flutterProject,
darwinDependencyManagement: dependencyManagement,
useImplicitPubspecResolution: true,
);
expect(dependencyManagement.setupPlatforms, <SupportedPlatform>[]);
}, overrides: <Type, Generator>{
@ -1511,7 +1521,7 @@ The Flutter Preview device does not support the following plugins from your pubs
linuxProject.exists = true;
createFakePlugin(fs);
// refreshPluginsList should call createPluginSymlinks.
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(linuxProject.pluginSymlinkDirectory.childLink('some_plugin').existsSync(), true);
}, overrides: <Type, Generator>{
@ -1524,7 +1534,7 @@ The Flutter Preview device does not support the following plugins from your pubs
windowsProject.exists = true;
createFakePlugin(fs);
// refreshPluginsList should call createPluginSymlinks.
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
expect(windowsProject.pluginSymlinkDirectory.childLink('some_plugin').existsSync(), true);
}, overrides: <Type, Generator>{
@ -1570,7 +1580,7 @@ The Flutter Preview device does not support the following plugins from your pubs
// refreshPluginsList should remove existing links and recreate on changes.
createFakePlugin(fs);
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
for (final File file in dummyFiles) {
expect(file.existsSync(), false);
@ -1609,7 +1619,7 @@ The Flutter Preview device does not support the following plugins from your pubs
linuxProject.exists = true;
windowsProject.exists = true;
createFakePlugin(fs);
await refreshPluginsList(flutterProject, writeLegacyPluginsList: true);
await refreshPluginsList(flutterProject, useImplicitPubspecResolution: true);
final List<Link> links = <Link>[
linuxProject.pluginSymlinkDirectory.childLink('some_plugin'),
@ -1708,6 +1718,7 @@ The Flutter Preview device does not support the following plugins from your pubs
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
);
expect(
@ -1733,6 +1744,7 @@ The Flutter Preview device does not support the following plugins from your pubs
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
);
expect(
@ -1757,6 +1769,7 @@ The Flutter Preview device does not support the following plugins from your pubs
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
);
expect(
@ -1786,6 +1799,7 @@ The Flutter Preview device does not support the following plugins from your pubs
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
);
expect(
@ -1811,6 +1825,7 @@ The Flutter Preview device does not support the following plugins from your pubs
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
);
expect(
@ -1835,6 +1850,7 @@ The Flutter Preview device does not support the following plugins from your pubs
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
);
expect(plugin.pluginPodspecPath(fs, IOSPlugin.kConfigKey), isNull);

View File

@ -141,12 +141,12 @@ void main() {
FlutterManifest.empty(logger: logger),
FlutterManifest.empty(logger: logger),
);
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectNotExists(project.directory);
});
_testInMemory('does nothing in plugin or package root project', () async {
final FlutterProject project = await aPluginProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectNotExists(project.ios.hostAppRoot.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
expectNotExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app')));
expectNotExists(project.ios.hostAppRoot.childDirectory('Flutter').childFile('Generated.xcconfig'));
@ -158,7 +158,7 @@ void main() {
// that a project was a plugin, but shouldn't be as this creates false
// positives.
project.directory.childDirectory('example').createSync();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.ios.hostAppRoot.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app')));
expectExists(project.ios.hostAppRoot.childDirectory('Flutter').childFile('Generated.xcconfig'));
@ -166,22 +166,22 @@ void main() {
});
_testInMemory('injects plugins for iOS', () async {
final FlutterProject project = await someProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.ios.hostAppRoot.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
});
_testInMemory('generates Xcode configuration for iOS', () async {
final FlutterProject project = await someProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.ios.hostAppRoot.childDirectory('Flutter').childFile('Generated.xcconfig'));
});
_testInMemory('injects plugins for Android', () async {
final FlutterProject project = await someProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app')));
});
_testInMemory('updates local properties for Android', () async {
final FlutterProject project = await someProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
});
_testInMemory('checkForDeprecation fails on invalid android app manifest file', () async {
@ -224,18 +224,18 @@ void main() {
final FlutterProject project = await aPluginProject();
project.example.directory.deleteSync();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expect(testLogger.statusText, isNot(contains('https://github.com/flutter/flutter/blob/main/docs/platforms/android/Upgrading-pre-1.12-Android-projects.md')));
});
_testInMemory('updates local properties for Android', () async {
final FlutterProject project = await someProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
});
testUsingContext('injects plugins for macOS', () async {
final FlutterProject project = await someProject();
project.macos.managedDirectory.createSync(recursive: true);
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.macos.pluginRegistrantImplementation);
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
@ -249,7 +249,7 @@ void main() {
testUsingContext('generates Xcode configuration for macOS', () async {
final FlutterProject project = await someProject();
project.macos.managedDirectory.createSync(recursive: true);
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.macos.generatedXcodePropertiesFile);
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
@ -263,7 +263,7 @@ void main() {
testUsingContext('injects plugins for Linux', () async {
final FlutterProject project = await someProject();
project.linux.cmakeFile.createSync(recursive: true);
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.linux.managedDirectory.childFile('generated_plugin_registrant.h'));
expectExists(project.linux.managedDirectory.childFile('generated_plugin_registrant.cc'));
}, overrides: <Type, Generator>{
@ -278,7 +278,7 @@ void main() {
testUsingContext('injects plugins for Windows', () async {
final FlutterProject project = await someProject();
project.windows.cmakeFile.createSync(recursive: true);
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.windows.managedDirectory.childFile('generated_plugin_registrant.h'));
expectExists(project.windows.managedDirectory.childFile('generated_plugin_registrant.cc'));
}, overrides: <Type, Generator>{
@ -292,14 +292,14 @@ void main() {
});
_testInMemory('creates Android library in module', () async {
final FlutterProject project = await aModuleProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
expectExists(project.android.hostAppGradleRoot.childFile('settings.gradle'));
expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('Flutter')));
});
_testInMemory('creates iOS pod in module', () async {
final FlutterProject project = await aModuleProject();
await project.regeneratePlatformSpecificTooling(writeLegacyPluginsList: true);
await project.regeneratePlatformSpecificTooling(useImplicitPubspecResolution: true);
final Directory flutter = project.ios.hostAppRoot.childDirectory('Flutter');
expectExists(flutter.childFile('podhelper.rb'));
expectExists(flutter.childFile('flutter_export_environment.sh'));

View File

@ -637,7 +637,7 @@ void main() {
Pub: () => FakePub(),
Usage: () => usage,
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('use packagesPath to generate BuildInfo', () async {

View File

@ -139,6 +139,8 @@ void main() {
),
true,
);
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('WebBuilder throws tool exit on failure', () async {
@ -178,5 +180,7 @@ void main() {
expect(logger.errorText, contains('Target hello failed: FormatException: illegal character in input string'));
expect(testUsage.timings, isEmpty);
expect(fakeAnalytics.sentEvents, isEmpty);
}, overrides: <Type, Generator>{
ProcessManager: () => FakeProcessManager.any(),
});
}

View File

@ -38,6 +38,7 @@ void main() {
},
dependencies: <String>[],
isDirectDependency: true,
isDevDependency: false,
),
], renderer);