2013-01-18 22:25:15 +01:00
|
|
|
"""pip sphinx extensions"""
|
|
|
|
|
|
|
|
import optparse
|
|
|
|
import sys
|
2017-11-12 17:04:37 +01:00
|
|
|
from textwrap import dedent
|
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
from docutils import nodes
|
|
|
|
from docutils.parsers import rst
|
|
|
|
from docutils.statemachine import ViewList
|
2017-11-12 17:04:37 +01:00
|
|
|
|
2018-07-30 08:15:17 +02:00
|
|
|
from pip._internal.cli import cmdoptions
|
2020-04-27 13:39:25 +02:00
|
|
|
from pip._internal.commands import commands_dict, create_command
|
2020-03-26 20:08:16 +01:00
|
|
|
from pip._internal.req.req_file import SUPPORTED_OPTIONS
|
2013-01-18 22:25:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
class PipCommandUsage(rst.Directive):
|
|
|
|
required_arguments = 1
|
2020-08-06 05:18:37 +02:00
|
|
|
optional_arguments = 3
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
def run(self):
|
2019-07-10 09:36:33 +02:00
|
|
|
cmd = create_command(self.arguments[0])
|
2020-08-06 05:18:37 +02:00
|
|
|
cmd_prefix = 'python -m pip'
|
2020-08-04 18:59:10 +02:00
|
|
|
if len(self.arguments) > 1:
|
2020-08-06 05:18:37 +02:00
|
|
|
cmd_prefix = " ".join(self.arguments[1:])
|
|
|
|
cmd_prefix = cmd_prefix.strip('"')
|
|
|
|
cmd_prefix = cmd_prefix.strip("'")
|
2018-11-08 08:05:05 +01:00
|
|
|
usage = dedent(
|
2020-12-23 20:25:12 +01:00
|
|
|
cmd.usage.replace('%prog', f'{cmd_prefix} {cmd.name}')
|
2018-11-08 08:05:05 +01:00
|
|
|
).strip()
|
2013-01-18 22:25:15 +01:00
|
|
|
node = nodes.literal_block(usage, usage)
|
|
|
|
return [node]
|
|
|
|
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
class PipCommandDescription(rst.Directive):
|
|
|
|
required_arguments = 1
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
def run(self):
|
|
|
|
node = nodes.paragraph()
|
|
|
|
node.document = self.state.document
|
|
|
|
desc = ViewList()
|
2019-07-10 09:36:33 +02:00
|
|
|
cmd = create_command(self.arguments[0])
|
|
|
|
description = dedent(cmd.__doc__)
|
2013-01-18 22:25:15 +01:00
|
|
|
for line in description.split('\n'):
|
|
|
|
desc.append(line, "")
|
|
|
|
self.state.nested_parse(desc, 0, node)
|
|
|
|
return [node]
|
|
|
|
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
class PipOptions(rst.Directive):
|
|
|
|
|
|
|
|
def _format_option(self, option, cmd_name=None):
|
2020-02-29 20:53:59 +01:00
|
|
|
bookmark_line = (
|
|
|
|
".. _`{cmd_name}_{option._long_opts[0]}`:"
|
|
|
|
if cmd_name else
|
|
|
|
".. _`{option._long_opts[0]}`:"
|
|
|
|
).format(**locals())
|
2014-02-12 06:55:43 +01:00
|
|
|
line = ".. option:: "
|
2013-01-18 22:25:15 +01:00
|
|
|
if option._short_opts:
|
|
|
|
line += option._short_opts[0]
|
|
|
|
if option._short_opts and option._long_opts:
|
2020-02-29 20:53:59 +01:00
|
|
|
line += ", " + option._long_opts[0]
|
2013-01-18 22:25:15 +01:00
|
|
|
elif option._long_opts:
|
|
|
|
line += option._long_opts[0]
|
|
|
|
if option.takes_value():
|
|
|
|
metavar = option.metavar or option.dest.lower()
|
2020-12-23 20:25:12 +01:00
|
|
|
line += f" <{metavar.lower()}>"
|
2014-03-26 23:24:19 +01:00
|
|
|
# fix defaults
|
2013-01-18 22:25:15 +01:00
|
|
|
opt_help = option.help.replace('%default', str(option.default))
|
2014-03-26 23:24:19 +01:00
|
|
|
# fix paths with sys.prefix
|
2013-01-18 22:25:15 +01:00
|
|
|
opt_help = opt_help.replace(sys.prefix, "<sys.prefix>")
|
2020-02-29 20:53:59 +01:00
|
|
|
return [bookmark_line, "", line, "", " " + opt_help, ""]
|
2013-01-18 22:25:15 +01:00
|
|
|
|
|
|
|
def _format_options(self, options, cmd_name=None):
|
|
|
|
for option in options:
|
|
|
|
if option.help == optparse.SUPPRESS_HELP:
|
|
|
|
continue
|
|
|
|
for line in self._format_option(option, cmd_name):
|
|
|
|
self.view_list.append(line, "")
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
node = nodes.paragraph()
|
|
|
|
node.document = self.state.document
|
|
|
|
self.view_list = ViewList()
|
|
|
|
self.process_options()
|
|
|
|
self.state.nested_parse(self.view_list, 0, node)
|
|
|
|
return [node]
|
|
|
|
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
class PipGeneralOptions(PipOptions):
|
|
|
|
def process_options(self):
|
2014-01-28 15:17:51 +01:00
|
|
|
self._format_options(
|
2015-04-17 04:37:47 +02:00
|
|
|
[o() for o in cmdoptions.general_group['options']]
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2013-01-18 22:25:15 +01:00
|
|
|
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
class PipIndexOptions(PipOptions):
|
2019-11-12 23:54:43 +01:00
|
|
|
required_arguments = 1
|
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
def process_options(self):
|
2019-11-12 23:54:43 +01:00
|
|
|
cmd_name = self.arguments[0]
|
2014-01-28 15:17:51 +01:00
|
|
|
self._format_options(
|
2019-11-12 23:54:43 +01:00
|
|
|
[o() for o in cmdoptions.index_group['options']],
|
|
|
|
cmd_name=cmd_name,
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2013-01-18 22:25:15 +01:00
|
|
|
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
class PipCommandOptions(PipOptions):
|
|
|
|
required_arguments = 1
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
def process_options(self):
|
2019-07-10 09:36:33 +02:00
|
|
|
cmd = create_command(self.arguments[0])
|
2014-01-28 15:17:51 +01:00
|
|
|
self._format_options(
|
|
|
|
cmd.parser.option_groups[0].option_list,
|
|
|
|
cmd_name=cmd.name,
|
|
|
|
)
|
2013-01-18 22:25:15 +01:00
|
|
|
|
2013-02-16 19:02:41 +01:00
|
|
|
|
2020-03-26 20:08:16 +01:00
|
|
|
class PipReqFileOptionsReference(PipOptions):
|
|
|
|
|
2020-04-27 13:39:25 +02:00
|
|
|
def determine_opt_prefix(self, opt_name):
|
|
|
|
for command in commands_dict:
|
|
|
|
cmd = create_command(command)
|
|
|
|
if cmd.cmd_opts.has_option(opt_name):
|
|
|
|
return command
|
|
|
|
|
2020-12-23 20:25:12 +01:00
|
|
|
raise KeyError(f'Could not identify prefix of opt {opt_name}')
|
2020-04-27 13:39:25 +02:00
|
|
|
|
2020-03-26 20:08:16 +01:00
|
|
|
def process_options(self):
|
|
|
|
for option in SUPPORTED_OPTIONS:
|
|
|
|
if getattr(option, 'deprecated', False):
|
|
|
|
continue
|
|
|
|
|
|
|
|
opt = option()
|
|
|
|
opt_name = opt._long_opts[0]
|
|
|
|
if opt._short_opts:
|
|
|
|
short_opt_name = '{}, '.format(opt._short_opts[0])
|
|
|
|
else:
|
|
|
|
short_opt_name = ''
|
|
|
|
|
2020-04-27 13:39:25 +02:00
|
|
|
if option in cmdoptions.general_group['options']:
|
|
|
|
prefix = ''
|
|
|
|
else:
|
|
|
|
prefix = '{}_'.format(self.determine_opt_prefix(opt_name))
|
|
|
|
|
2020-03-26 20:08:16 +01:00
|
|
|
self.view_list.append(
|
2020-11-12 02:59:03 +01:00
|
|
|
'* :ref:`{short}{long}<{prefix}{opt_name}>`'.format(
|
2020-03-26 20:08:16 +01:00
|
|
|
short=short_opt_name,
|
|
|
|
long=opt_name,
|
2020-04-27 13:39:25 +02:00
|
|
|
prefix=prefix,
|
2020-03-26 20:08:16 +01:00
|
|
|
opt_name=opt_name
|
|
|
|
),
|
|
|
|
"\n"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2013-01-18 22:25:15 +01:00
|
|
|
def setup(app):
|
|
|
|
app.add_directive('pip-command-usage', PipCommandUsage)
|
|
|
|
app.add_directive('pip-command-description', PipCommandDescription)
|
|
|
|
app.add_directive('pip-command-options', PipCommandOptions)
|
|
|
|
app.add_directive('pip-general-options', PipGeneralOptions)
|
|
|
|
app.add_directive('pip-index-options', PipIndexOptions)
|
2020-03-26 20:08:16 +01:00
|
|
|
app.add_directive(
|
|
|
|
'pip-requirements-file-options-ref-list', PipReqFileOptionsReference
|
|
|
|
)
|