diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index fcbdb52823..615733dbd2 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -20,7 +20,10 @@ import '../runner/flutter_command.dart'; class PackagesCommand extends FlutterCommand { PackagesCommand() { addSubcommand(PackagesGetCommand('get', false)); - addSubcommand(PackagesGetCommand('upgrade', true)); + //addSubcommand(PackagesGetCommand('upgrade', true)); + addSubcommand(PackagesInteractiveGetCommand('upgrade', 'Upgrade the current package\'s dependencies to latest versions.')); + addSubcommand(PackagesInteractiveGetCommand('add', 'Add a dependency to pubspec.yaml.')); + addSubcommand(PackagesInteractiveGetCommand('remove', 'Removes a dependency from the current package.')); addSubcommand(PackagesTestCommand()); addSubcommand(PackagesForwardCommand('publish', 'Publish the current package to pub.dartlang.org', requiresPubspec: true)); addSubcommand(PackagesForwardCommand('downgrade', 'Downgrade packages in a Flutter project', requiresPubspec: true)); @@ -29,6 +32,8 @@ class PackagesCommand extends FlutterCommand { addSubcommand(PackagesForwardCommand('cache', 'Work with the Pub system cache')); addSubcommand(PackagesForwardCommand('version', 'Print Pub version')); addSubcommand(PackagesForwardCommand('uploader', 'Manage uploaders for a package on pub.dev')); + addSubcommand(PackagesForwardCommand('login', 'Log into pub.dev.')); + addSubcommand(PackagesForwardCommand('logout', 'Log out of pub.dev.')); addSubcommand(PackagesForwardCommand('global', 'Work with Pub global packages')); addSubcommand(PackagesForwardCommand('outdated', 'Analyze dependencies to find which ones can be upgraded', requiresPubspec: true)); addSubcommand(PackagesPassthroughCommand()); @@ -253,3 +258,82 @@ class PackagesPassthroughCommand extends FlutterCommand { return FlutterCommandResult.success(); } } + +class PackagesInteractiveGetCommand extends FlutterCommand { + PackagesInteractiveGetCommand(this._commandName, this._description) { + requiresPubspecYaml(); + } + + @override + ArgParser argParser = ArgParser.allowAnything(); + + final String _commandName; + final String _description; + + @override + String get name => _commandName; + + @override + String get description { + return '$_description.\n' + 'This runs the "pub" tool in a Flutter context.'; + } + + @override + String get invocation { + return '${runner.executableName} pub $_commandName []'; + } + + @override + Future runCommand() async { + List rest = argResults.rest; + String target; + if (rest.length == 1 && + (rest[0].contains('/') || + rest[0].contains(r'\'))) { + // HACK: Supporting flutter specific behavior where you can pass a + // folder to the command. + target = findProjectRoot(rest[0]); + rest = []; + } else { + target = findProjectRoot(); + } + if (target == null) { + throwToolExit('Expected to find project root in ' + 'current working directory.'); + } + final FlutterProject flutterProject = FlutterProject.fromPath(target); + + if (flutterProject.manifest.generateSyntheticPackage) { + final Environment environment = Environment( + artifacts: globals.artifacts, + logger: globals.logger, + cacheDir: globals.cache.getRoot(), + engineVersion: globals.flutterVersion.engineRevision, + fileSystem: globals.fs, + flutterRootDir: globals.fs.directory(Cache.flutterRoot), + outputDir: globals.fs.directory(getBuildDirectory()), + processManager: globals.processManager, + projectDir: flutterProject.directory, + ); + + await generateLocalizationsSyntheticPackage( + environment: environment, + buildSystem: globals.buildSystem, + ); + } + + final List subArgs = rest.toList() + ..removeWhere((String arg) => arg == '--'); + await pub.interactively( + [name, ...subArgs], + directory: target, + stdio: globals.stdio, + touchesPackageConfig: true, + generateSyntheticPackage: flutterProject.manifest.generateSyntheticPackage, + ); + + await flutterProject.regeneratePlatformSpecificTooling(); + return FlutterCommandResult.success(); + } +} diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index ed6ace001c..defb78c1f2 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -127,6 +127,8 @@ abstract class Pub { List arguments, { String directory, @required io.Stdio stdio, + bool touchesPackageConfig = false, + bool generateSyntheticPackage = false, }); } @@ -324,6 +326,8 @@ class _DefaultPub implements Pub { List arguments, { String directory, @required io.Stdio stdio, + bool touchesPackageConfig = false, + bool generateSyntheticPackage = false, }) async { final io.Process process = await _processUtils.start( _pubCommand(arguments), @@ -357,6 +361,23 @@ class _DefaultPub implements Pub { if (code != 0) { throwToolExit('pub finished with exit code $code', exitCode: code); } + + if (touchesPackageConfig) { + final File packageConfigFile = _fileSystem.file( + _fileSystem.path.join(directory, '.dart_tool', 'package_config.json')); + final Directory generatedDirectory = _fileSystem.directory( + _fileSystem.path.join(directory, '.dart_tool', 'flutter_gen')); + final File lastVersion = _fileSystem.file( + _fileSystem.path.join(directory, '.dart_tool', 'version')); + final File currentVersion = _fileSystem.file( + _fileSystem.path.join(Cache.flutterRoot, 'version')); + lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); + await _updatePackageConfig( + packageConfigFile, + generatedDirectory, + generateSyntheticPackage, + ); + } } /// The command used for running pub. diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart index 6c7aa33a11..57624fc1c4 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -374,6 +374,7 @@ void main() { expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { + Stdio: () => MockStdio()..stdout.terminalColumns = 80, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, diff --git a/packages/flutter_tools/test/src/throwing_pub.dart b/packages/flutter_tools/test/src/throwing_pub.dart index 41a150905a..de4013684c 100644 --- a/packages/flutter_tools/test/src/throwing_pub.dart +++ b/packages/flutter_tools/test/src/throwing_pub.dart @@ -36,7 +36,13 @@ class ThrowingPub implements Pub { } @override - Future interactively(List arguments, {String directory, @required Stdio stdio,}) { + Future interactively( + List arguments, { + String directory, + @required Stdio stdio, + bool touchesPackageConfig = false, + bool generateSyntheticPackage = false, + }) { throw UnsupportedError('Attempted to invoke pub during test.'); } }