mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Removes dev dependencies from generated plugin registrant for non-Android platforms (#161828)
Removes dev dependencies from the generated plugin registrants for all platforms since they will be removed from release builds (this was already done for Android, mostly in https://github.com/flutter/flutter/pull/161343). Fixes https://github.com/flutter/flutter/issues/161348. ## 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. <!-- 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
This commit is contained in:
parent
1dd3f5d45b
commit
fffbf663ff
@ -363,20 +363,11 @@ List<Map<String, Object?>> _extractPlatformMaps(Iterable<Plugin> plugins, String
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _writeAndroidPluginRegistrant(
|
Future<void> _writeAndroidPluginRegistrant(FlutterProject project, List<Plugin> plugins) async {
|
||||||
FlutterProject project,
|
final List<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(
|
||||||
List<Plugin> plugins, {
|
|
||||||
required bool releaseMode,
|
|
||||||
}) async {
|
|
||||||
Iterable<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(
|
|
||||||
plugins,
|
plugins,
|
||||||
AndroidPlugin.kConfigKey,
|
AndroidPlugin.kConfigKey,
|
||||||
);
|
);
|
||||||
// TODO(camsim99): Remove dev dependencies from release builds for all platforms. See https://github.com/flutter/flutter/issues/161348.
|
|
||||||
if (releaseMode) {
|
|
||||||
methodChannelPlugins = methodChannelPlugins.where((Plugin p) => !p.isDevDependency);
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Map<String, Object?>> androidPlugins = _extractPlatformMaps(
|
final List<Map<String, Object?>> androidPlugins = _extractPlatformMaps(
|
||||||
methodChannelPlugins,
|
methodChannelPlugins,
|
||||||
AndroidPlugin.kConfigKey,
|
AndroidPlugin.kConfigKey,
|
||||||
@ -1204,7 +1195,7 @@ Future<void> injectBuildTimePluginFilesForWebPlatform(
|
|||||||
|
|
||||||
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects.
|
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects.
|
||||||
///
|
///
|
||||||
/// The injected files are required by the flutter app as soon as possible, so
|
/// The injected files are required by the Flutter app as soon as possible, so
|
||||||
/// it can be built.
|
/// it can be built.
|
||||||
///
|
///
|
||||||
/// Files written by this method end up in platform-specific locations that are
|
/// Files written by this method end up in platform-specific locations that are
|
||||||
@ -1225,18 +1216,19 @@ Future<void> injectPlugins(
|
|||||||
DarwinDependencyManagement? darwinDependencyManagement,
|
DarwinDependencyManagement? darwinDependencyManagement,
|
||||||
bool? releaseMode,
|
bool? releaseMode,
|
||||||
}) async {
|
}) async {
|
||||||
final List<Plugin> plugins = await findPlugins(project);
|
List<Plugin> plugins = await findPlugins(project);
|
||||||
|
|
||||||
|
if (releaseMode ?? false) {
|
||||||
|
plugins = plugins.where((Plugin p) => !p.isDevDependency).toList();
|
||||||
|
}
|
||||||
|
|
||||||
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(
|
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(
|
||||||
plugins,
|
plugins,
|
||||||
pluginResolutionType: _PluginResolutionType.nativeOrDart,
|
pluginResolutionType: _PluginResolutionType.nativeOrDart,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (androidPlatform) {
|
if (androidPlatform) {
|
||||||
await _writeAndroidPluginRegistrant(
|
await _writeAndroidPluginRegistrant(project, pluginsByPlatform[AndroidPlugin.kConfigKey]!);
|
||||||
project,
|
|
||||||
pluginsByPlatform[AndroidPlugin.kConfigKey]!,
|
|
||||||
releaseMode: releaseMode ?? false,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (iosPlatform) {
|
if (iosPlatform) {
|
||||||
await _writeIOSPluginRegistrant(project, pluginsByPlatform[IOSPlugin.kConfigKey]!);
|
await _writeIOSPluginRegistrant(project, pluginsByPlatform[IOSPlugin.kConfigKey]!);
|
||||||
|
@ -244,7 +244,7 @@ class AndroidPlugin extends PluginPlatform implements NativeOrDartPlugin {
|
|||||||
/// The [name] of the plugin is required. Additionally, either:
|
/// The [name] of the plugin is required. Additionally, either:
|
||||||
/// - [defaultPackage], or
|
/// - [defaultPackage], or
|
||||||
/// - an implementation consisting of:
|
/// - an implementation consisting of:
|
||||||
/// - the [pluginClass] (with optional [classPrefix]) that will be the entry
|
/// - the [classPrefix] (with optional [pluginClass]) that will be the entry
|
||||||
/// point to the plugin's native code, and/or
|
/// point to the plugin's native code, and/or
|
||||||
/// - the [dartPluginClass] with optional [dartFileName] that will be
|
/// - the [dartPluginClass] with optional [dartFileName] that will be
|
||||||
/// the entry point for the plugin's Dart code
|
/// the entry point for the plugin's Dart code
|
||||||
|
@ -637,6 +637,18 @@ class AndroidProject extends FlutterProjectPlatform {
|
|||||||
return hostAppGradleRoot.childFile('AndroidManifest.xml');
|
return hostAppGradleRoot.childFile('AndroidManifest.xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File get generatedPluginRegistrantFile {
|
||||||
|
return hostAppGradleRoot
|
||||||
|
.childDirectory('app')
|
||||||
|
.childDirectory('src')
|
||||||
|
.childDirectory('main')
|
||||||
|
.childDirectory('java')
|
||||||
|
.childDirectory('io')
|
||||||
|
.childDirectory('flutter')
|
||||||
|
.childDirectory('plugins')
|
||||||
|
.childFile('GeneratedPluginRegistrant.java');
|
||||||
|
}
|
||||||
|
|
||||||
File get gradleAppOutV1File => gradleAppOutV1Directory.childFile('app-debug.apk');
|
File get gradleAppOutV1File => gradleAppOutV1Directory.childFile('app-debug.apk');
|
||||||
|
|
||||||
Directory get gradleAppOutV1Directory {
|
Directory get gradleAppOutV1Directory {
|
||||||
|
@ -2510,6 +2510,226 @@ The Flutter Preview device does not support the following plugins from your pubs
|
|||||||
returnsNormally,
|
returnsNormally,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('injectPlugins in release mode', () {
|
||||||
|
const String testPluginName = 'test_plugin';
|
||||||
|
|
||||||
|
// Fake pub to override dev dependencies of flutterProject.
|
||||||
|
final Pub fakePubWithTestPluginDevDependency = FakePubWithPrimedDeps(
|
||||||
|
devDependencies: <String>{testPluginName},
|
||||||
|
);
|
||||||
|
|
||||||
|
testUsingContext(
|
||||||
|
'excludes dev dependencies from Android plugin registrant',
|
||||||
|
() async {
|
||||||
|
final Directory pluginDir = createPlugin(
|
||||||
|
name: testPluginName,
|
||||||
|
platforms: const <String, _PluginPlatformInfo>{
|
||||||
|
'android': _PluginPlatformInfo(pluginClass: 'Foo', androidPackage: 'bar.foo'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// injectPlugins will fail if main native class not found in expected spot, so add
|
||||||
|
// it first.
|
||||||
|
pluginDir
|
||||||
|
.childDirectory('android')
|
||||||
|
.childDirectory('src')
|
||||||
|
.childDirectory('main')
|
||||||
|
.childDirectory('java')
|
||||||
|
.childDirectory('bar')
|
||||||
|
.childDirectory('foo')
|
||||||
|
.childFile('Foo.java')
|
||||||
|
..createSync(recursive: true)
|
||||||
|
..writeAsStringSync('import io.flutter.embedding.engine.plugins.FlutterPlugin;');
|
||||||
|
|
||||||
|
// Test non-release mode.
|
||||||
|
await injectPlugins(flutterProject, androidPlatform: true, releaseMode: false);
|
||||||
|
final File generatedPluginRegistrant =
|
||||||
|
flutterProject.android.generatedPluginRegistrantFile;
|
||||||
|
expect(generatedPluginRegistrant, exists);
|
||||||
|
expect(generatedPluginRegistrant.readAsStringSync(), contains('bar.foo.Foo'));
|
||||||
|
|
||||||
|
// Test release mode.
|
||||||
|
await injectPlugins(flutterProject, androidPlatform: true, releaseMode: true);
|
||||||
|
expect(generatedPluginRegistrant, exists);
|
||||||
|
expect(generatedPluginRegistrant.readAsStringSync(), isNot(contains('bar.foo.Foo')));
|
||||||
|
},
|
||||||
|
overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
FeatureFlags: enableExplicitPackageDependencies,
|
||||||
|
Pub: () => fakePubWithTestPluginDevDependency,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
testUsingContext(
|
||||||
|
'excludes dev dependencies from iOS plugin registrant',
|
||||||
|
() async {
|
||||||
|
createPlugin(
|
||||||
|
name: testPluginName,
|
||||||
|
platforms: const <String, _PluginPlatformInfo>{
|
||||||
|
'ios': _PluginPlatformInfo(pluginClass: 'Foo'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final FakeDarwinDependencyManagement dependencyManagement =
|
||||||
|
FakeDarwinDependencyManagement();
|
||||||
|
const String devDepImport = '#import <$testPluginName/Foo.h>';
|
||||||
|
|
||||||
|
// Test non-release mode.
|
||||||
|
await injectPlugins(
|
||||||
|
flutterProject,
|
||||||
|
iosPlatform: true,
|
||||||
|
darwinDependencyManagement: dependencyManagement,
|
||||||
|
releaseMode: false,
|
||||||
|
);
|
||||||
|
final File generatedPluginRegistrantImpl =
|
||||||
|
flutterProject.ios.pluginRegistrantImplementation;
|
||||||
|
expect(generatedPluginRegistrantImpl, exists);
|
||||||
|
expect(generatedPluginRegistrantImpl.readAsStringSync(), contains(devDepImport));
|
||||||
|
|
||||||
|
// Test release mode.
|
||||||
|
await injectPlugins(
|
||||||
|
flutterProject,
|
||||||
|
iosPlatform: true,
|
||||||
|
darwinDependencyManagement: dependencyManagement,
|
||||||
|
releaseMode: true,
|
||||||
|
);
|
||||||
|
expect(generatedPluginRegistrantImpl, exists);
|
||||||
|
expect(generatedPluginRegistrantImpl.readAsStringSync(), isNot(contains(devDepImport)));
|
||||||
|
},
|
||||||
|
overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
FeatureFlags: enableExplicitPackageDependencies,
|
||||||
|
Pub: () => fakePubWithTestPluginDevDependency,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
testUsingContext(
|
||||||
|
'excludes dev dependencies from Linux plugin registrant',
|
||||||
|
() async {
|
||||||
|
createPlugin(
|
||||||
|
name: testPluginName,
|
||||||
|
platforms: const <String, _PluginPlatformInfo>{
|
||||||
|
'linux': _PluginPlatformInfo(pluginClass: 'Foo'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const String expectedDevDepImport = '#include <$testPluginName/foo.h>';
|
||||||
|
|
||||||
|
// Test non-release mode.
|
||||||
|
await injectPlugins(flutterProject, linuxPlatform: true, releaseMode: false);
|
||||||
|
final File generatedPluginRegistrant = flutterProject.linux.managedDirectory.childFile(
|
||||||
|
'generated_plugin_registrant.cc',
|
||||||
|
);
|
||||||
|
expect(generatedPluginRegistrant, exists);
|
||||||
|
expect(generatedPluginRegistrant.readAsStringSync(), contains(expectedDevDepImport));
|
||||||
|
|
||||||
|
// Test release mode.
|
||||||
|
await injectPlugins(flutterProject, linuxPlatform: true, releaseMode: true);
|
||||||
|
expect(generatedPluginRegistrant, exists);
|
||||||
|
expect(
|
||||||
|
generatedPluginRegistrant.readAsStringSync(),
|
||||||
|
isNot(contains(expectedDevDepImport)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
FeatureFlags: enableExplicitPackageDependencies,
|
||||||
|
Pub: () => fakePubWithTestPluginDevDependency,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
testUsingContext(
|
||||||
|
'excludes dev dependencies from MacOS plugin registrant',
|
||||||
|
() async {
|
||||||
|
createPlugin(
|
||||||
|
name: testPluginName,
|
||||||
|
platforms: const <String, _PluginPlatformInfo>{
|
||||||
|
'macos': _PluginPlatformInfo(pluginClass: 'Foo'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final FakeDarwinDependencyManagement dependencyManagement =
|
||||||
|
FakeDarwinDependencyManagement();
|
||||||
|
const String expectedDevDepRegistration = 'Foo.register';
|
||||||
|
|
||||||
|
// Test non-release mode.
|
||||||
|
await injectPlugins(
|
||||||
|
flutterProject,
|
||||||
|
macOSPlatform: true,
|
||||||
|
darwinDependencyManagement: dependencyManagement,
|
||||||
|
releaseMode: false,
|
||||||
|
);
|
||||||
|
final File generatedPluginRegistrant = flutterProject.macos.managedDirectory.childFile(
|
||||||
|
'GeneratedPluginRegistrant.swift',
|
||||||
|
);
|
||||||
|
expect(generatedPluginRegistrant, exists);
|
||||||
|
expect(
|
||||||
|
generatedPluginRegistrant.readAsStringSync(),
|
||||||
|
contains(expectedDevDepRegistration),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test release mode.
|
||||||
|
await injectPlugins(
|
||||||
|
flutterProject,
|
||||||
|
macOSPlatform: true,
|
||||||
|
darwinDependencyManagement: dependencyManagement,
|
||||||
|
releaseMode: true,
|
||||||
|
);
|
||||||
|
expect(generatedPluginRegistrant, exists);
|
||||||
|
expect(
|
||||||
|
generatedPluginRegistrant.readAsStringSync(),
|
||||||
|
isNot(contains(expectedDevDepRegistration)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
FeatureFlags: enableExplicitPackageDependencies,
|
||||||
|
Pub: () => fakePubWithTestPluginDevDependency,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
testUsingContext(
|
||||||
|
'excludes dev dependencies from Windows plugin registrant',
|
||||||
|
() async {
|
||||||
|
createPlugin(
|
||||||
|
name: testPluginName,
|
||||||
|
platforms: const <String, _PluginPlatformInfo>{
|
||||||
|
'windows': _PluginPlatformInfo(pluginClass: 'Foo'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const String expectedDevDepRegistration = '#include <$testPluginName/foo.h>';
|
||||||
|
|
||||||
|
// Test non-release mode.
|
||||||
|
await injectPlugins(flutterProject, windowsPlatform: true, releaseMode: false);
|
||||||
|
final File generatedPluginRegistrantImpl = flutterProject.windows.managedDirectory
|
||||||
|
.childFile('generated_plugin_registrant.cc');
|
||||||
|
expect(generatedPluginRegistrantImpl, exists);
|
||||||
|
expect(
|
||||||
|
generatedPluginRegistrantImpl.readAsStringSync(),
|
||||||
|
contains(expectedDevDepRegistration),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test release mode.
|
||||||
|
await injectPlugins(flutterProject, windowsPlatform: true, releaseMode: true);
|
||||||
|
expect(generatedPluginRegistrantImpl, exists);
|
||||||
|
expect(
|
||||||
|
generatedPluginRegistrantImpl.readAsStringSync(),
|
||||||
|
isNot(contains(expectedDevDepRegistration)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
FeatureFlags: enableExplicitPackageDependencies,
|
||||||
|
Pub: () => fakePubWithTestPluginDevDependency,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext(
|
testUsingContext(
|
||||||
@ -2718,6 +2938,17 @@ class FakeAndroidProject extends Fake implements AndroidProject {
|
|||||||
AndroidEmbeddingVersionResult computeEmbeddingVersion() {
|
AndroidEmbeddingVersionResult computeEmbeddingVersion() {
|
||||||
return AndroidEmbeddingVersionResult(embeddingVersion, 'reasons for version');
|
return AndroidEmbeddingVersionResult(embeddingVersion, 'reasons for version');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
File get generatedPluginRegistrantFile => hostAppGradleRoot
|
||||||
|
.childDirectory('app')
|
||||||
|
.childDirectory('src')
|
||||||
|
.childDirectory('main')
|
||||||
|
.childDirectory('java')
|
||||||
|
.childDirectory('io')
|
||||||
|
.childDirectory('flutter')
|
||||||
|
.childDirectory('plugins')
|
||||||
|
.childFile('GeneratedPluginRegistrant.java');
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeWebProject extends Fake implements WebProject {
|
class FakeWebProject extends Fake implements WebProject {
|
||||||
|
@ -1,58 +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 'package:file/file.dart';
|
|
||||||
import 'package:file/memory.dart';
|
|
||||||
import 'package:file_testing/file_testing.dart';
|
|
||||||
import 'package:flutter_tools/src/base/template.dart';
|
|
||||||
import 'package:flutter_tools/src/flutter_plugins.dart';
|
|
||||||
import 'package:flutter_tools/src/isolated/mustache_template.dart';
|
|
||||||
import 'package:flutter_tools/src/platform_plugins.dart';
|
|
||||||
import 'package:flutter_tools/src/plugins.dart';
|
|
||||||
import 'package:flutter_tools/src/project.dart';
|
|
||||||
|
|
||||||
import '../../src/common.dart';
|
|
||||||
|
|
||||||
const TemplateRenderer renderer = MustacheTemplateRenderer();
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWithoutContext('Win32 injects Win32 plugins', () async {
|
|
||||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
||||||
setUpProject(fileSystem);
|
|
||||||
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(
|
|
||||||
fileSystem.currentDirectory,
|
|
||||||
);
|
|
||||||
|
|
||||||
await writeWindowsPluginFiles(flutterProject, <Plugin>[
|
|
||||||
Plugin(
|
|
||||||
name: 'test',
|
|
||||||
path: 'foo',
|
|
||||||
defaultPackagePlatforms: const <String, String>{},
|
|
||||||
pluginDartClassPlatforms: const <String, DartPluginClassAndFilePair>{},
|
|
||||||
platforms: const <String, PluginPlatform>{
|
|
||||||
WindowsPlugin.kConfigKey: WindowsPlugin(
|
|
||||||
name: 'test',
|
|
||||||
pluginClass: 'Foo',
|
|
||||||
variants: <PluginPlatformVariant>{PluginPlatformVariant.win32},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
dependencies: <String>[],
|
|
||||||
isDirectDependency: true,
|
|
||||||
isDevDependency: false,
|
|
||||||
),
|
|
||||||
], renderer);
|
|
||||||
|
|
||||||
final Directory managed = flutterProject.windows.managedDirectory;
|
|
||||||
expect(flutterProject.windows.generatedPluginCmakeFile, exists);
|
|
||||||
expect(managed.childFile('generated_plugin_registrant.h'), exists);
|
|
||||||
expect(
|
|
||||||
managed.childFile('generated_plugin_registrant.cc').readAsStringSync(),
|
|
||||||
contains('#include <test/foo.h>'),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void setUpProject(FileSystem fileSystem) {
|
|
||||||
fileSystem.file('pubspec.yaml').createSync();
|
|
||||||
}
|
|
@ -27,8 +27,7 @@ final class FakePubWithPrimedDeps implements Pub {
|
|||||||
'name': rootPackageName,
|
'name': rootPackageName,
|
||||||
'kind': 'root',
|
'kind': 'root',
|
||||||
'dependencies': <String>[...dependencies.keys, ...devDependencies]..sort(),
|
'dependencies': <String>[...dependencies.keys, ...devDependencies]..sort(),
|
||||||
'directDependencies': <String>[...?dependencies[rootPackageName], ...devDependencies]
|
'directDependencies': <String>[...?dependencies[rootPackageName]]..sort(),
|
||||||
..sort(),
|
|
||||||
'devDependencies': <String>[...devDependencies],
|
'devDependencies': <String>[...devDependencies],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user