Skip to content

Commit

Permalink
replace global OptionParser and refactor main()
Browse files Browse the repository at this point in the history
  • Loading branch information
gvalkov committed Nov 10, 2012
1 parent 46a2175 commit 2c64a1e
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 48 deletions.
90 changes: 65 additions & 25 deletions pip/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from pip.log import logger
from pip.util import get_installed_distributions, get_prog
from pip.vcs import git, mercurial, subversion, bazaar # noqa
from pip.baseparser import create_main_parser
from pip.commands import commands, get_similar_commands, get_summaries


Expand Down Expand Up @@ -73,40 +74,79 @@ def autocomplete():
opt_label += '='
print(opt_label)
else:
# show options of main parser only when necessary
parser = create_main_parser()

# show main parser options only when necessary
if current.startswith('-') or current.startswith('--'):
subcommands += [opt.get_opt_string()
for opt in parser.option_list
if opt.help != optparse.SUPPRESS_HELP]
opts = [i.option_list for i in parser.option_groups]
opts.append(parser.option_list)
opts = (o for it in opts for o in it)

subcommands += [i.get_opt_string() for i in opts
if i.help != optparse.SUPPRESS_HELP]

print(' '.join([x for x in subcommands if x.startswith(current)]))
sys.exit(1)


def parseopts(args):
parser = create_main_parser()

# create command listing
command_summaries = get_summaries()

description = ['Commands:']
description.extend([' %-20s %s' % (i, j) for i,j in command_summaries])

# We have to add the name of the default OptionGroup here for now.
description.append('\nOptions:')
parser.description = '\n'.join(description)

options, args = parser.parse_args(args)

if options.version:
sys.stdout.write(parser.version)
sys.stdout.write(os.linesep)
sys.exit()

# pip || pip help || pip --help -> print_help()
if options.help or not args or (args[0] == 'help' and len(args) == 1):
parser.print_help()
sys.exit()

if not args:
msg = 'You must give a command (use "pip --help" to see a list of commands)'
raise CommandError(msg)

command = args[0].lower()

if command not in commands:
guess = get_similar_commands(command)

msg = ['unknown command "%s"' % command]
if guess:
msg.append('maybe you meant "%s"' % guess)

raise CommandError(' - '.join(msg)) # TODO:

return command, options, args, parser


def main(initial_args=None):
if initial_args is None:
initial_args = sys.argv[1:]

autocomplete()
options, args = parser.parse_args(initial_args)
if options.help and not args:
args = ['help']
if not args:
parser.error('You must give a command '
'(use "%s help" to see a list of commands)' % get_prog())
command = args[0].lower()
load_command(command)
if command not in command_dict:
close_commands = difflib.get_close_matches(command, command_names())
if close_commands:
guess = close_commands[0]
if args[1:]:
guess = "%s %s" % (guess, " ".join(args[1:]))
else:
guess = 'install %s' % command
error_dict = {'arg': command, 'guess': guess,
'script': os.path.basename(sys.argv[0])}
parser.error('No command by the name %(script)s %(arg)s\n '
'(maybe you meant "%(script)s %(guess)s")' % error_dict)
command = command_dict[command]

try:
cmd_name, options, args, parser = parseopts(initial_args)
except PipError:
e = sys.exc_info()[1]
sys.stderr.write(str(e))
sys.stderr.write(os.linesep)
sys.exit(1)

command = commands[cmd_name](parser) #see baseparser.Command
return command.main(args[1:], options)


Expand Down
2 changes: 0 additions & 2 deletions pip/baseparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,5 +310,3 @@ def create_main_parser():

return parser

parser = create_main_parser()

35 changes: 14 additions & 21 deletions pip/commands/help.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
from pip.basecommand import (Command, command_dict,
load_all_commands, SUCCESS,
ERROR)
from pip.basecommand import Command, SUCCESS, ERROR
from pip.exceptions import CommandError
from pip.baseparser import parser


class HelpCommand(Command):
Expand All @@ -11,22 +8,18 @@ class HelpCommand(Command):
summary = 'Show available commands'

def run(self, options, args):
load_all_commands()
if args:
## FIXME: handle errors better here
command = args[0]
if command not in command_dict:
raise CommandError('No command with the name: %s' % command)
command = command_dict[command]
command.parser.print_help()
from pip.commands import commands

try:
# 'pip help' with no args is handled by pip.__init__.parseopt()
cmd_name = args[0] # the command we need help for
except:
return SUCCESS
parser.print_help()
print('\nCommands available:')
commands = list(set(command_dict.values()))
commands.sort(key=lambda x: x.name)
for command in commands:
if command.hidden:
continue
print(' %s: %s' % (command.name, command.summary))
return SUCCESS

if cmd_name not in commands:
raise CommandError('unknown command "%s"' % cmd_name)

command = commands[cmd_name](self.main_parser) # instantiate
command.parser.print_help()

return SUCCESS
1 change: 1 addition & 0 deletions tests/test_help.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pip.exceptions import CommandError
from pip.baseparser import create_main_parser
from pip.commands.help import (HelpCommand,
SUCCESS,
ERROR,)
Expand Down
1 change: 1 addition & 0 deletions tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
SearchCommand)
from pip.status_codes import NO_MATCHES_FOUND, SUCCESS
from pip.backwardcompat import xmlrpclib, b
from pip.baseparser import create_main_parser
from mock import Mock
from tests.test_pip import run_pip, reset_env, pyversion
from tests.pypi_server import assert_equal
Expand Down

0 comments on commit 2c64a1e

Please sign in to comment.