Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(932)

Side by Side Diff: sdk/lib/_internal/pub/bin/pub.dart

Issue 138723005: Support subcommands in pub and pub help. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Infer hiddenness from subcommands. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/pub/lib/src/command.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:io'; 6 import 'dart:io';
7 7
8 import 'package:args/args.dart'; 8 import 'package:args/args.dart';
9 import 'package:path/path.dart' as path; 9 import 'package:path/path.dart' as path;
10 import 'package:stack_trace/stack_trace.dart';
10 11
11 import '../lib/src/command.dart'; 12 import '../lib/src/command.dart';
12 import '../lib/src/exit_codes.dart' as exit_codes; 13 import '../lib/src/exit_codes.dart' as exit_codes;
14 import '../lib/src/http.dart';
13 import '../lib/src/io.dart'; 15 import '../lib/src/io.dart';
14 import '../lib/src/log.dart' as log; 16 import '../lib/src/log.dart' as log;
15 import '../lib/src/sdk.dart' as sdk; 17 import '../lib/src/sdk.dart' as sdk;
16 import '../lib/src/utils.dart'; 18 import '../lib/src/utils.dart';
17 19
18 void main(List<String> arguments) { 20 void main(List<String> arguments) {
19 ArgResults options; 21 ArgResults options;
20 22
21 try { 23 try {
22 options = PubCommand.pubArgParser.parse(arguments, 24 options = PubCommand.pubArgParser.parse(arguments,
23 allowTrailingOptions: true); 25 allowTrailingOptions: true);
24 } on FormatException catch (e) { 26 } on FormatException catch (e) {
25 log.error(e.message); 27 log.error(e.message);
26 log.error('Run "pub help" to see available options.'); 28 log.error('Run "pub help" to see available options.');
27 flushThenExit(exit_codes.USAGE); 29 flushThenExit(exit_codes.USAGE);
28 return; 30 return;
29 } 31 }
30 32
31 if (options['version']) { 33 if (options['version']) {
32 log.message('Pub ${sdk.version}'); 34 log.message('Pub ${sdk.version}');
33 return; 35 return;
34 } 36 }
35 37
36 if (options['help']) { 38 if (options['help']) {
37 PubCommand.printGlobalUsage(); 39 PubCommand.printGlobalUsage();
38 return; 40 return;
39 } 41 }
40 42
41 if (options.command == null) {
42 if (options.rest.isEmpty) {
43 // No command was chosen.
44 PubCommand.printGlobalUsage();
45 } else {
46 log.error('Could not find a command named "${options.rest[0]}".');
47 log.error('Run "pub help" to see available commands.');
48 flushThenExit(exit_codes.USAGE);
49 }
50 return;
51 }
52
53 if (options['trace']) { 43 if (options['trace']) {
54 log.recordTranscript(); 44 log.recordTranscript();
55 } 45 }
56 46
57 switch (options['verbosity']) { 47 switch (options['verbosity']) {
58 case 'normal': log.showNormal(); break; 48 case 'normal': log.showNormal(); break;
59 case 'io': log.showIO(); break; 49 case 'io': log.showIO(); break;
60 case 'solver': log.showSolver(); break; 50 case 'solver': log.showSolver(); break;
61 case 'all': log.showAll(); break; 51 case 'all': log.showAll(); break;
62 default: 52 default:
(...skipping 11 matching lines...) Expand all
74 var cacheDir; 64 var cacheDir;
75 if (Platform.environment.containsKey('PUB_CACHE')) { 65 if (Platform.environment.containsKey('PUB_CACHE')) {
76 cacheDir = Platform.environment['PUB_CACHE']; 66 cacheDir = Platform.environment['PUB_CACHE'];
77 } else if (Platform.operatingSystem == 'windows') { 67 } else if (Platform.operatingSystem == 'windows') {
78 var appData = Platform.environment['APPDATA']; 68 var appData = Platform.environment['APPDATA'];
79 cacheDir = path.join(appData, 'Pub', 'Cache'); 69 cacheDir = path.join(appData, 'Pub', 'Cache');
80 } else { 70 } else {
81 cacheDir = '${Platform.environment['HOME']}/.pub-cache'; 71 cacheDir = '${Platform.environment['HOME']}/.pub-cache';
82 } 72 }
83 73
84 validatePlatform().then((_) { 74 validatePlatform().then((_) => runPub(cacheDir, options, arguments));
85 PubCommand.commands[options.command.name].run(cacheDir, options, arguments); 75 }
76
77 /// Runs the appropriate pub command whose [arguments] have been parsed to
78 /// [options] using the system cache in [cacheDir].
79 ///
80 /// Handles and correctly reports any errors that occur while running.
81 void runPub(String cacheDir, ArgResults options, List<String> arguments) {
82 var captureStackChains =
83 options['trace'] ||
84 options['verbose'] ||
85 options['verbosity'] == 'all';
86
87 captureErrors(() => invokeCommand(cacheDir, options),
88 captureStackChains: captureStackChains).catchError((error, Chain chain) {
89 // This is basically the top-level exception handler so that we don't
90 // spew a stack trace on our users.
91 var message;
92
93 log.error(getErrorMessage(error));
94 log.fine("Exception type: ${error.runtimeType}");
95
96 if (options['trace'] || !isUserFacingException(error)) {
97 log.error(chain.terse);
98 } else {
99 log.fine(chain.terse);
100 }
101
102 if (error is ApplicationException && error.innerError != null) {
103 var message = "Wrapped exception: ${error.innerError}";
104 if (error.innerTrace != null) message = "$message\n${error.innerTrace}";
105 log.fine(message);
106 }
107
108 if (options['trace']) {
109 log.dumpTranscript();
110 } else if (!isUserFacingException(error)) {
111 log.error("""
112 This is an unexpected error. Please run
113
114 pub --trace ${arguments.map((arg) => "'$arg'").join(' ')}
115
116 and include the results in a bug report on http://dartbug.com/new.
117 """);
118 }
119
120 return flushThenExit(chooseExitCode(error));
121 }).then((_) {
122 // Explicitly exit on success to ensure that any dangling dart:io handles
123 // don't cause the process to never terminate.
124 return flushThenExit(exit_codes.SUCCESS);
86 }); 125 });
87 } 126 }
88 127
128 /// Returns the appropriate exit code for [exception], falling back on 1 if no
129 /// appropriate exit code could be found.
130 int chooseExitCode(exception) {
131 if (exception is HttpException || exception is HttpException ||
132 exception is SocketException || exception is PubHttpException) {
133 return exit_codes.UNAVAILABLE;
134 } else if (exception is FormatException) {
135 return exit_codes.DATA;
136 } else if (exception is UsageException) {
137 return exit_codes.USAGE;
138 } else {
139 return 1;
140 }
141 }
142
143 /// Walks the command tree and runs the selected pub command.
144 Future invokeCommand(String cacheDir, ArgResults mainOptions) {
145 var commands = PubCommand.mainCommands;
146 var command;
147 var commandString = "pub";
148 var options = mainOptions;
149
150 while (commands.isNotEmpty) {
151 if (options.command == null) {
152 if (options.rest.isEmpty) {
153 if (command == null) {
154 // No top-level command was chosen.
155 PubCommand.printGlobalUsage();
156 return new Future.value();
157 }
158
159 command.usageError('Missing subcommand for "$commandString".');
160 } else {
161 if (command == null) {
162 PubCommand.usageErrorWithCommands(commands,
163 'Could not find a command named "${options.rest[0]}".');
164 }
165
166 command.usageError('Could not find a subcommand named '
167 '"${options.rest[0]}" for "$commandString".');
168 }
169 }
170
171 // Step into the command.
172 options = options.command;
173 command = commands[options.name];
174 commands = command.subcommands;
175 commandString += " ${options.name}";
176
177 if (options['help']) {
178 command.printUsage();
179 return new Future.value();
180 }
181 }
182
183 // Make sure there aren't unexpected arguments.
184 if (!command.takesArguments && options.rest.isNotEmpty) {
185 command.usageError(
186 'Command "${options.name}" does not take any arguments.');
187 }
188
189 return syncFuture(() {
190 return command.run(cacheDir, options);
191 }).whenComplete(() {
192 command.cache.deleteTempDir();
193 });
194 }
195
89 /// Checks that pub is running on a supported platform. If it isn't, it prints 196 /// Checks that pub is running on a supported platform. If it isn't, it prints
90 /// an error message and exits. Completes when the validation is done. 197 /// an error message and exits. Completes when the validation is done.
91 Future validatePlatform() { 198 Future validatePlatform() {
92 return syncFuture(() { 199 return syncFuture(() {
93 if (Platform.operatingSystem != 'windows') return null; 200 if (Platform.operatingSystem != 'windows') return null;
94 201
95 return runProcess('ver', []).then((result) { 202 return runProcess('ver', []).then((result) {
96 if (result.stdout.join('\n').contains('XP')) { 203 if (result.stdout.join('\n').contains('XP')) {
97 log.error('Sorry, but pub is not supported on Windows XP.'); 204 log.error('Sorry, but pub is not supported on Windows XP.');
98 return flushThenExit(exit_codes.USAGE); 205 return flushThenExit(exit_codes.USAGE);
99 } 206 }
100 }); 207 });
101 }); 208 });
102 } 209 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/pub/lib/src/command.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698