Remove `uploader` command (#3335)
We now have a web-interface for managing the uploaders. That should be the preferred way.
Leaving a (hidden) stub telling the user to use the web interface instead.
See also breaking change request: https://github.com/dart-lang/sdk#48526
diff --git a/lib/src/command/uploader.dart b/lib/src/command/uploader.dart
index 99a6a57..cae4963 100644
--- a/lib/src/command/uploader.dart
+++ b/lib/src/command/uploader.dart
@@ -6,10 +6,7 @@
import 'dart:io';
import '../command.dart';
-import '../exit_codes.dart' as exit_codes;
-import '../http.dart';
-import '../log.dart' as log;
-import '../oauth2.dart' as oauth2;
+import '../utils.dart';
/// Handles the `uploader` pub command.
class UploaderCommand extends PubCommand {
@@ -23,6 +20,9 @@
@override
String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-uploader';
+ @override
+ bool get hidden => true;
+
/// The URL of the package hosting server.
Uri get server => Uri.parse(argResults['server']);
@@ -41,58 +41,18 @@
@override
Future<void> runProtected() async {
- if (argResults.wasParsed('server')) {
- await log.warningsOnlyUnlessTerminal(() {
- log.message(
- '''
-The --server option is deprecated. Use `publish_to` in your pubspec.yaml or set
-the \$PUB_HOSTED_URL environment variable.''',
- );
- });
- }
- if (argResults.rest.isEmpty) {
- log.error('No uploader command given.');
- printUsage();
- overrideExitCode(exit_codes.USAGE);
- return;
- }
-
- var rest = argResults.rest.toList();
-
- // TODO(rnystrom): Use subcommands for these.
- var command = rest.removeAt(0);
- if (!['add', 'remove'].contains(command)) {
- log.error('Unknown uploader command "$command".');
- printUsage();
- overrideExitCode(exit_codes.USAGE);
- return;
- } else if (rest.isEmpty) {
- log.error('No uploader given for "pub uploader $command".');
- printUsage();
- overrideExitCode(exit_codes.USAGE);
- return;
- }
-
- final package = argResults['package'] ?? entrypoint.root.name;
- final uploader = rest[0];
+ String packageName = '<packageName>';
try {
- final response = await oauth2.withClient(cache, (client) {
- if (command == 'add') {
- var url = server.resolve('/api/packages/'
- '${Uri.encodeComponent(package)}/uploaders');
- return client
- .post(url, headers: pubApiHeaders, body: {'email': uploader});
- } else {
- // command == 'remove'
- var url = server.resolve('/api/packages/'
- '${Uri.encodeComponent(package)}/uploaders/'
- '${Uri.encodeComponent(uploader)}');
- return client.delete(url, headers: pubApiHeaders);
- }
- });
- handleJsonSuccess(response);
- } on PubHttpException catch (error) {
- handleJsonError(error.response);
+ packageName = entrypoint.root.name;
+ } on Exception catch (_) {
+ // Probably run without a pubspec.
+ // Just print error below without a specific package name.
}
+ fail('''
+Package uploaders are no longer managed from the command line.
+Manage uploaders from:
+
+https://pub.dev/packages/$packageName/admin
+''');
}
}
diff --git a/test/pub_uploader_test.dart b/test/pub_uploader_test.dart
index 47d50d3..643671a 100644
--- a/test/pub_uploader_test.dart
+++ b/test/pub_uploader_test.dart
@@ -2,168 +2,34 @@
// for details. 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:async';
-import 'dart:convert';
-
-import 'package:pub/src/exit_codes.dart' as exit_codes;
-import 'package:shelf/shelf.dart' as shelf;
import 'package:test/test.dart';
-import 'package:test_process/test_process.dart';
import 'descriptor.dart' as d;
import 'test_pub.dart';
-Future<TestProcess> startPubUploader(PackageServer server, List<String> args) {
- var tokenEndpoint = Uri.parse(server.url).resolve('/token').toString();
- var allArgs = ['uploader', ...args];
- return startPub(
- args: allArgs,
- tokenEndpoint: tokenEndpoint,
- environment: {'PUB_HOSTED_URL': tokenEndpoint});
-}
-
void main() {
- group('displays usage', () {
- test('when run with no arguments', () {
- return runPub(args: ['uploader'], exitCode: exit_codes.USAGE);
- });
+ test('displays deprecation notice', () async {
+ await runPub(
+ args: ['uploader', 'add'],
+ error: '''
+Package uploaders are no longer managed from the command line.
+Manage uploaders from:
- test('when run with only a command', () {
- return runPub(args: ['uploader', 'add'], exitCode: exit_codes.USAGE);
- });
+https://pub.dev/packages/<packageName>/admin
+''',
+ exitCode: 1,
+ );
- test('when run with an invalid command', () {
- return runPub(
- args: ['uploader', 'foo', 'email'], exitCode: exit_codes.USAGE);
- });
- });
+ await d.appDir().create();
+ await runPub(
+ args: ['uploader', 'add'],
+ error: '''
+Package uploaders are no longer managed from the command line.
+Manage uploaders from:
- test('adds an uploader', () async {
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(
- globalServer, ['--package', 'pkg', 'add', 'email']);
-
- globalServer.expect('POST', '/api/packages/pkg/uploaders', (request) {
- return request.readAsString().then((body) {
- expect(body, equals('email=email'));
-
- return shelf.Response.ok(
- jsonEncode({
- 'success': {'message': 'Good job!'}
- }),
- headers: {'content-type': 'application/json'});
- });
- });
-
- expect(pub.stdout, emits('Good job!'));
- await pub.shouldExit(exit_codes.SUCCESS);
- });
-
- test('removes an uploader', () async {
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(
- globalServer, ['--package', 'pkg', 'remove', 'email']);
-
- globalServer.expect('DELETE', '/api/packages/pkg/uploaders/email',
- (request) {
- return shelf.Response.ok(
- jsonEncode({
- 'success': {'message': 'Good job!'}
- }),
- headers: {'content-type': 'application/json'});
- });
-
- expect(pub.stdout, emits('Good job!'));
- await pub.shouldExit(exit_codes.SUCCESS);
- });
-
- test('defaults to the current package', () async {
- await d.validPackage.create();
-
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(globalServer, ['add', 'email']);
-
- globalServer.expect('POST', '/api/packages/test_pkg/uploaders', (request) {
- return shelf.Response.ok(
- jsonEncode({
- 'success': {'message': 'Good job!'}
- }),
- headers: {'content-type': 'application/json'});
- });
-
- expect(pub.stdout, emits('Good job!'));
- await pub.shouldExit(exit_codes.SUCCESS);
- });
-
- test('add provides an error', () async {
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(
- globalServer, ['--package', 'pkg', 'add', 'email']);
-
- globalServer.expect('POST', '/api/packages/pkg/uploaders', (request) {
- return shelf.Response(400,
- body: jsonEncode({
- 'error': {'message': 'Bad job!'}
- }),
- headers: {'content-type': 'application/json'});
- });
-
- expect(pub.stderr, emits('Bad job!'));
- await pub.shouldExit(1);
- });
-
- test('remove provides an error', () async {
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(
- globalServer, ['--package', 'pkg', 'remove', 'e/mail']);
-
- globalServer.expect('DELETE', '/api/packages/pkg/uploaders/e%2Fmail',
- (request) {
- return shelf.Response(400,
- body: jsonEncode({
- 'error': {'message': 'Bad job!'}
- }),
- headers: {'content-type': 'application/json'});
- });
-
- expect(pub.stderr, emits('Bad job!'));
- await pub.shouldExit(1);
- });
-
- test('add provides invalid JSON', () async {
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(
- globalServer, ['--package', 'pkg', 'add', 'email']);
-
- globalServer.expect('POST', '/api/packages/pkg/uploaders',
- (request) => shelf.Response.ok('{not json'));
-
- expect(
- pub.stderr,
- emitsLines('Invalid server response:\n'
- '{not json'));
- await pub.shouldExit(1);
- });
-
- test('remove provides invalid JSON', () async {
- await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
- var pub = await startPubUploader(
- globalServer, ['--package', 'pkg', 'remove', 'email']);
-
- globalServer.expect('DELETE', '/api/packages/pkg/uploaders/email',
- (request) => shelf.Response.ok('{not json'));
-
- expect(
- pub.stderr,
- emitsLines('Invalid server response:\n'
- '{not json'));
- await pub.shouldExit(1);
+https://pub.dev/packages/myapp/admin
+''',
+ exitCode: 1,
+ );
});
}
diff --git a/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt b/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
index d80d984..9585341 100644
--- a/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
+++ b/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
@@ -114,7 +114,11 @@
## Section 12
$ pub uploader -C myapp add sigurdm@google.com
-Good job!
+[STDERR] Package uploaders are no longer managed from the command line.
+[STDERR] Manage uploaders from:
+[STDERR]
+[STDERR] https://pub.dev/packages/test_pkg/admin
+[EXIT CODE] 1
-------------------------------- END OF OUTPUT ---------------------------------
diff --git a/test/testdata/goldens/help_test/pub uploader --help.txt b/test/testdata/goldens/help_test/pub uploader --help.txt
deleted file mode 100644
index 10c9d9d..0000000
--- a/test/testdata/goldens/help_test/pub uploader --help.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# GENERATED BY: test/help_test.dart
-
-## Section 0
-$ pub uploader --help
-Manage uploaders for a package on pub.dartlang.org.
-
-Usage: pub uploader [options] {add/remove} <email>
--h, --help Print this usage information.
- --package The package whose uploaders will be modified.
- (defaults to the current package)
--C, --directory=<dir> Run this in the directory<dir>.
-
-Run "pub help" to see global options.
-See https://dart.dev/tools/pub/cmd/pub-uploader for detailed documentation.
-