[med-svn] [Git][med-team/sphinxcontrib-autoprogram][upstream] New upstream version 0.1.4
Andreas Tille
gitlab at salsa.debian.org
Mon Mar 26 17:16:23 UTC 2018
Andreas Tille pushed to branch upstream at Debian Med / sphinxcontrib-autoprogram
Commits:
f5e20274 by Andreas Tille at 2018-03-26T19:09:27+02:00
New upstream version 0.1.4
- - - - -
7 changed files:
- PKG-INFO
- README.rst
- setup.cfg
- setup.py
- sphinxcontrib/autoprogram.py
- sphinxcontrib_autoprogram.egg-info/PKG-INFO
- sphinxcontrib_autoprogram.egg-info/requires.txt
Changes:
=====================================
PKG-INFO
=====================================
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,13 +1,26 @@
Metadata-Version: 1.1
Name: sphinxcontrib-autoprogram
-Version: 0.1.2
+Version: 0.1.4
Summary: Documenting CLI programs
-Home-page: https://bitbucket.org/birkenfeld/sphinx-contrib
+Home-page: https://github.com/sphinx-contrib/autoprogram
Author: Hong Minhee
-Author-email: minhee at dahlia.kr
+Author-email: hong.minhee at gmail.com
License: BSD
-Description: ``sphinxcontrib.autoprogram`` --- Documenting CLI programs
- ==========================================================
+Description-Content-Type: UNKNOWN
+Description: ``sphinxcontrib.autoprogram``
+ =============================
+
+ .. image:: https://badge.fury.io/py/sphinxcontrib-autoprogram.svg
+ :target: https://pypi.org/project/sphinxcontrib-autoprogram/
+ :alt: Latest PyPI version
+
+ .. image:: https://readthedocs.org/projects/sphinxcontrib-autoprogram/badge/
+ :target: https://sphinxcontrib-autoprogram.readthedocs.io/
+ :alt: Documentation Status
+
+ .. image:: https://travis-ci.org/sphinx-contrib/autoprogram.svg?branch=master
+ :alt: Build Status
+ :target: https://travis-ci.org/sphinx-contrib/autoprogram
This contrib extension, ``sphinxcontrib.autoprogram``, provides an automated
way to document CLI programs. It scans ``arparser.ArgumentParser`` object,
@@ -22,10 +35,10 @@ Description: ``sphinxcontrib.autoprogram`` --- Documenting CLI programs
You can find the documentation from the following URL:
- https://pythonhosted.org/sphinxcontrib-autoprogram/
+ https://sphinxcontrib-autoprogram.readthedocs.io/
Platform: any
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
@@ -35,6 +48,9 @@ Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Implementation :: Stackless
=====================================
README.rst
=====================================
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,17 @@
-``sphinxcontrib.autoprogram`` --- Documenting CLI programs
-==========================================================
+``sphinxcontrib.autoprogram``
+=============================
+
+.. image:: https://badge.fury.io/py/sphinxcontrib-autoprogram.svg
+ :target: https://pypi.org/project/sphinxcontrib-autoprogram/
+ :alt: Latest PyPI version
+
+.. image:: https://readthedocs.org/projects/sphinxcontrib-autoprogram/badge/
+ :target: https://sphinxcontrib-autoprogram.readthedocs.io/
+ :alt: Documentation Status
+
+.. image:: https://travis-ci.org/sphinx-contrib/autoprogram.svg?branch=master
+ :alt: Build Status
+ :target: https://travis-ci.org/sphinx-contrib/autoprogram
This contrib extension, ``sphinxcontrib.autoprogram``, provides an automated
way to document CLI programs. It scans ``arparser.ArgumentParser`` object,
@@ -14,4 +26,4 @@ Install using ``pip``:
You can find the documentation from the following URL:
-https://pythonhosted.org/sphinxcontrib-autoprogram/
+https://sphinxcontrib-autoprogram.readthedocs.io/
=====================================
setup.cfg
=====================================
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,6 @@
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
[bdist_wheel]
universal = 1
=====================================
setup.py
=====================================
--- a/setup.py
+++ b/setup.py
@@ -7,11 +7,11 @@ from setuptools import setup, find_packages
# Do not change the variable name. It's parsed by doc/conf.py script.
-version = '0.1.2'
+version = '0.1.4'
requires = ['Sphinx >= 1.2', 'six']
-if sys.version_info < (2, 7):
+if 'bdist_wheel' not in sys.argv and sys.version_info < (2, 7):
requires.append('argparse')
@@ -23,15 +23,15 @@ def readme():
setup(
name='sphinxcontrib-autoprogram',
version=version,
- url='https://bitbucket.org/birkenfeld/sphinx-contrib',
+ url='https://github.com/sphinx-contrib/autoprogram',
license='BSD',
author='Hong Minhee',
- author_email='minhee' '@' 'dahlia.kr',
+ author_email='\x68\x6f\x6e\x67.minhee' '@' '\x67\x6d\x61\x69\x6c.com',
description='Documenting CLI programs',
long_description=readme(),
zip_safe=False,
classifiers=[
- 'Development Status :: 4 - Beta',
+ 'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Environment :: Web Environment',
'Intended Audience :: Developers',
@@ -41,6 +41,9 @@ setup(
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Programming Language :: Python :: Implementation :: Stackless',
@@ -52,6 +55,7 @@ setup(
packages=find_packages(),
namespace_packages=['sphinxcontrib'],
include_package_data=True,
- test_suite='sphinxcontrib.autoprogram.suite',
- install_requires=requires
+ install_requires=requires,
+ extras_requires={":python_version=='2.6'": ['argparse']},
+ test_suite='sphinxcontrib.autoprogram.suite'
)
=====================================
sphinxcontrib/autoprogram.py
=====================================
--- a/sphinxcontrib/autoprogram.py
+++ b/sphinxcontrib/autoprogram.py
@@ -11,27 +11,40 @@
# pylint: disable=protected-access,missing-docstring
import argparse
import collections
-try:
- import builtins
-except ImportError:
- import __builtin__ as builtins
-import functools
+import os
import re
+import sys
import unittest
-import six
from docutils import nodes
+from docutils.parsers.rst import Directive
from docutils.parsers.rst.directives import unchanged
-from docutils.statemachine import ViewList
-from sphinx.util.compat import Directive
-from sphinx.util.nodes import nested_parse_with_titles
+from docutils.statemachine import StringList, ViewList
+from six import exec_
+from six.moves import builtins, reduce
from sphinx.domains import std
+from sphinx.util.nodes import nested_parse_with_titles
-__all__ = ('BOOLEAN_OPTIONS', 'AutoprogramDirective', 'ScannerTestCase',
+__all__ = ('AutoprogramDirective',
+ 'AutoprogramDirectiveTestCase', 'ScannerTestCase',
'import_object', 'scan_programs', 'setup', 'suite')
-def scan_programs(parser, command=[]):
+def get_subparser_action(parser):
+ neg1_action = parser._actions[-1]
+
+ if isinstance(neg1_action, argparse._SubParsersAction):
+ return neg1_action
+
+ for a in parser._actions:
+ if isinstance(a, argparse._SubParsersAction):
+ return a
+
+
+def scan_programs(parser, command=[], maxdepth=0, depth=0):
+ if maxdepth and depth >= maxdepth:
+ return
+
options = []
for arg in parser._actions:
if not (arg.option_strings or
@@ -39,14 +52,26 @@ def scan_programs(parser, command=[]):
name = (arg.metavar or arg.dest).lower()
desc = (arg.help or '') % {'default': arg.default}
options.append(([name], desc))
+
for arg in parser._actions:
- if arg.option_strings:
+ if arg.option_strings and arg.help is not argparse.SUPPRESS:
if isinstance(arg, (argparse._StoreAction,
argparse._AppendAction)):
if arg.choices is None:
- metavar = (arg.metavar or arg.dest).lower()
- names = ['{0} <{1}>'.format(option_string, metavar)
- for option_string in arg.option_strings]
+ metavar = arg.metavar or arg.dest
+
+ if isinstance(metavar, tuple):
+ names = [
+ '{0} <{1}>'.format(
+ option_string, '> <'.join(metavar).lower()
+ )
+ for option_string in arg.option_strings
+ ]
+ else:
+ names = [
+ '{0} <{1}>'.format(option_string, metavar.lower())
+ for option_string in arg.option_strings
+ ]
else:
choices = '{0}'.format(','.join(arg.choices))
names = ['{0} {{{1}}}'.format(option_string, choices)
@@ -55,15 +80,26 @@ def scan_programs(parser, command=[]):
names = list(arg.option_strings)
desc = (arg.help or '') % {'default': arg.default}
options.append((names, desc))
- yield command, options, parser.description, parser.epilog or ''
+
+ yield command, options, parser
+
if parser._subparsers:
- choices = parser._subparsers._actions[-1].choices.items()
+ choices = ()
+
+ subp_action = get_subparser_action(parser)
+
+ if subp_action:
+ choices = subp_action.choices.items()
+
if not (hasattr(collections, 'OrderedDict') and
isinstance(choices, collections.OrderedDict)):
choices = sorted(choices, key=lambda pair: pair[0])
+
for cmd, sub in choices:
if isinstance(sub, argparse.ArgumentParser):
- for program in scan_programs(sub, command + [cmd]):
+ for program in scan_programs(
+ sub, command + [cmd], maxdepth, depth + 1
+ ):
yield program
@@ -87,7 +123,7 @@ def import_object(import_name):
with open(f[0]) as fobj:
codestring = fobj.read()
foo = imp.new_module("foo")
- six.exec_(codestring, foo.__dict__)
+ exec_(codestring, foo.__dict__)
sys.modules["foo"] = foo
mod = __import__("foo")
@@ -95,8 +131,7 @@ def import_object(import_name):
else:
raise ImportError("No module named {}".format(module_name))
- reduce_ = getattr(functools, 'reduce', None) or reduce
- mod = reduce_(getattr, module_name.split('.')[1:], mod)
+ mod = reduce(getattr, module_name.split('.')[1:], mod)
globals_ = builtins
if not isinstance(globals_, dict):
globals_ = globals_.__dict__
@@ -107,32 +142,94 @@ class AutoprogramDirective(Directive):
has_content = False
required_arguments = 1
- option_spec = {'prog': unchanged}
+ option_spec = {
+ 'prog': unchanged,
+ 'maxdepth': unchanged,
+ 'start_command': unchanged,
+ 'strip_usage': unchanged,
+ 'no_usage_codeblock': unchanged,
+ }
def make_rst(self):
import_name, = self.arguments
parser = import_object(import_name or '__undefined__')
- parser.prog = self.options.get('prog', parser.prog)
- for commands, options, desc, epilog in scan_programs(parser):
- command = ' '.join(commands)
- title = '{0} {1}'.format(parser.prog, command).rstrip()
+ prog = self.options.get('prog')
+ if prog:
+ original_prog = parser.prog
+ parser.prog = prog
+ start_command = self.options.get('start_command', '').split(' ')
+ strip_usage = 'strip_usage' in self.options
+ usage_codeblock = 'no_usage_codeblock' not in self.options
+
+ if start_command[0] == '':
+ start_command.pop(0)
+
+ if start_command:
+ def get_start_cmd_parser(p):
+ looking_for = start_command.pop(0)
+ action = get_subparser_action(p)
+
+ if not action:
+ raise ValueError('No actions for command ' + looking_for)
+
+ subp = action.choices[looking_for]
+
+ if start_command:
+ return get_start_cmd_parser(subp)
+
+ return subp
+
+ parser = get_start_cmd_parser(parser)
+ if prog and parser.prog.startswith(original_prog):
+ parser.prog = parser.prog.replace(original_prog, prog, 1)
+
+ for commands, options, cmd_parser in scan_programs(
+ parser, maxdepth=int(self.options.get('maxdepth', 0))
+ ):
+ if prog and cmd_parser.prog.startswith(original_prog):
+ cmd_parser.prog = cmd_parser.prog.replace(
+ original_prog, prog, 1)
+ title = cmd_parser.prog.rstrip()
+ usage = cmd_parser.format_usage()
+
+ if strip_usage:
+ to_strip = title.rsplit(' ', 1)[0]
+ len_to_strip = len(to_strip) - 4
+ usage_lines = usage.splitlines()
+
+ usage = os.linesep.join([
+ usage_lines[0].replace(to_strip, '...'),
+ ] + [
+ l[len_to_strip:] for l in usage_lines[1:]
+ ])
+
yield ''
yield '.. program:: ' + title
yield ''
yield title
yield ('!' if commands else '?') * len(title)
yield ''
- yield desc or ''
+ for line in (cmd_parser.description or '').splitlines():
+ yield line
yield ''
- yield parser.format_usage()
+
+ if usage_codeblock:
+ yield '.. code-block:: console'
+ yield ''
+ for usage_line in usage.splitlines():
+ yield ' ' + usage_line
+ else:
+ yield usage
+
yield ''
+
for option_strings, help_ in options:
yield '.. option:: {0}'.format(', '.join(option_strings))
yield ''
yield ' ' + help_.replace('\n', ' \n')
yield ''
yield ''
- for line in epilog.splitlines():
+ for line in (cmd_parser.epilog or '').splitlines():
yield line or ''
def run(self):
@@ -175,14 +272,17 @@ class ScannerTestCase(unittest.TestCase):
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
+ parser.add_argument('--key-value', metavar=('KEY', 'VALUE'), nargs=2)
+ parser.add_argument('--max', help=argparse.SUPPRESS) # must be opt-out
+
programs = scan_programs(parser)
programs = list(programs)
self.assertEqual(1, len(programs))
parser_info, = programs
- program, options, desc, _ = parser_info
+ program, options, cmd_parser = parser_info
self.assertEqual([], program)
- self.assertEqual('Process some integers.', desc)
- self.assertEqual(4, len(options))
+ self.assertEqual('Process some integers.', cmd_parser.description)
+ self.assertEqual(5, len(options))
self.assertEqual(
(['n'], 'an integer for the accumulator'),
options[0]
@@ -200,6 +300,10 @@ class ScannerTestCase(unittest.TestCase):
(['--sum'], 'sum the integers (default: find the max)'),
options[3]
)
+ self.assertEqual(
+ (['--key-value <key> <value>', ], ''),
+ options[4]
+ )
def test_subcommands(self):
parser = argparse.ArgumentParser(description='Process some integers.')
@@ -217,9 +321,9 @@ class ScannerTestCase(unittest.TestCase):
programs = list(programs)
self.assertEqual(3, len(programs))
# main
- program, options, desc, _ = programs[0]
+ program, options, cmd_parser = programs[0]
self.assertEqual([], program)
- self.assertEqual('Process some integers.', desc)
+ self.assertEqual('Process some integers.', cmd_parser.description)
self.assertEqual(1, len(options))
self.assertEqual(
(['-h', '--help'],
@@ -227,9 +331,9 @@ class ScannerTestCase(unittest.TestCase):
options[0]
)
# max
- program, options, desc, _ = programs[1]
+ program, options, cmd_parser = programs[1]
self.assertEqual(['max'], program)
- self.assertEqual('Find the max.', desc)
+ self.assertEqual('Find the max.', cmd_parser.description)
self.assertEqual(2, len(options))
self.assertEqual((['n'], 'An integer for the accumulator.'),
options[0])
@@ -239,9 +343,9 @@ class ScannerTestCase(unittest.TestCase):
options[1]
)
# sum
- program, options, desc, _ = programs[2]
+ program, options, cmd_parser = programs[2]
self.assertEqual(['sum'], program)
- self.assertEqual('Sum the integers.', desc)
+ self.assertEqual('Sum the integers.', cmd_parser.description)
self.assertEqual(2, len(options))
self.assertEqual((['n'], 'An integer for the accumulator.'),
options[0])
@@ -249,7 +353,7 @@ class ScannerTestCase(unittest.TestCase):
def test_choices(self):
parser = argparse.ArgumentParser()
parser.add_argument("--awesomeness", choices=["meh", "awesome"])
- program, options, desc, _ = list(scan_programs(parser))[0]
+ program, options, cmd_parser = list(scan_programs(parser))[0]
log_option = options[1]
self.assertEqual((["--awesomeness {meh,awesome}"], ''), log_option)
@@ -262,8 +366,29 @@ class ScannerTestCase(unittest.TestCase):
programs = list(programs)
self.assertEqual(1, len(programs))
parser_data, = programs
- program, options, desc, epilog = parser_data
- self.assertEqual('The integers will be processed.', epilog)
+ program, options, cmd_parser = parser_data
+ self.assertEqual('The integers will be processed.', cmd_parser.epilog)
+
+
+class AutoprogramDirectiveTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.untouched_sys_path = sys.path[:]
+ sample_prog_path = os.path.join(os.path.dirname(__file__), '..', 'doc')
+ sys.path.insert(0, sample_prog_path)
+ self.directive = AutoprogramDirective(
+ 'autoprogram', ['cli:parser'], {'prog': 'cli.py'},
+ StringList([], items=[]), 1, 0,
+ '.. autoprogram:: cli:parser\n :prog: cli.py\n',
+ None, None
+ )
+
+ def tearDown(self):
+ sys.path[:] = self.untouched_sys_path
+
+ def test_make_rst(self):
+ """Alt least it shouldn't raise errors during making RST string."""
+ list(self.directive.make_rst())
class UtilTestCase(unittest.TestCase):
@@ -284,7 +409,5 @@ class UtilTestCase(unittest.TestCase):
suite = unittest.TestSuite()
-suite.addTests(
- unittest.defaultTestLoader.loadTestsFromTestCase(ScannerTestCase)
-)
-suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(UtilTestCase))
+for test_case in ScannerTestCase, AutoprogramDirectiveTestCase, UtilTestCase:
+ suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(test_case))
=====================================
sphinxcontrib_autoprogram.egg-info/PKG-INFO
=====================================
--- a/sphinxcontrib_autoprogram.egg-info/PKG-INFO
+++ b/sphinxcontrib_autoprogram.egg-info/PKG-INFO
@@ -1,13 +1,26 @@
Metadata-Version: 1.1
Name: sphinxcontrib-autoprogram
-Version: 0.1.2
+Version: 0.1.4
Summary: Documenting CLI programs
-Home-page: https://bitbucket.org/birkenfeld/sphinx-contrib
+Home-page: https://github.com/sphinx-contrib/autoprogram
Author: Hong Minhee
-Author-email: minhee at dahlia.kr
+Author-email: hong.minhee at gmail.com
License: BSD
-Description: ``sphinxcontrib.autoprogram`` --- Documenting CLI programs
- ==========================================================
+Description-Content-Type: UNKNOWN
+Description: ``sphinxcontrib.autoprogram``
+ =============================
+
+ .. image:: https://badge.fury.io/py/sphinxcontrib-autoprogram.svg
+ :target: https://pypi.org/project/sphinxcontrib-autoprogram/
+ :alt: Latest PyPI version
+
+ .. image:: https://readthedocs.org/projects/sphinxcontrib-autoprogram/badge/
+ :target: https://sphinxcontrib-autoprogram.readthedocs.io/
+ :alt: Documentation Status
+
+ .. image:: https://travis-ci.org/sphinx-contrib/autoprogram.svg?branch=master
+ :alt: Build Status
+ :target: https://travis-ci.org/sphinx-contrib/autoprogram
This contrib extension, ``sphinxcontrib.autoprogram``, provides an automated
way to document CLI programs. It scans ``arparser.ArgumentParser`` object,
@@ -22,10 +35,10 @@ Description: ``sphinxcontrib.autoprogram`` --- Documenting CLI programs
You can find the documentation from the following URL:
- https://pythonhosted.org/sphinxcontrib-autoprogram/
+ https://sphinxcontrib-autoprogram.readthedocs.io/
Platform: any
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
@@ -35,6 +48,9 @@ Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Implementation :: Stackless
=====================================
sphinxcontrib_autoprogram.egg-info/requires.txt
=====================================
--- a/sphinxcontrib_autoprogram.egg-info/requires.txt
+++ b/sphinxcontrib_autoprogram.egg-info/requires.txt
@@ -1,2 +1,2 @@
-Sphinx >= 1.2
-six
\ No newline at end of file
+Sphinx>=1.2
+six
View it on GitLab: https://salsa.debian.org/med-team/sphinxcontrib-autoprogram/commit/f5e20274a3bc503833a7a976e1d4815e225432c8
---
View it on GitLab: https://salsa.debian.org/med-team/sphinxcontrib-autoprogram/commit/f5e20274a3bc503833a7a976e1d4815e225432c8
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/debian-med-commit/attachments/20180326/0c43bcf8/attachment-0001.html>
More information about the debian-med-commit
mailing list