Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Finished the new --help output, closes issue22, r=twobraids
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbe committed Nov 19, 2011
1 parent d45f9ee commit f6d8304
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 97 deletions.
81 changes: 35 additions & 46 deletions configman/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,66 +378,55 @@ def get_options(self, source=None, options=None, prefix=''):
#--------------------------------------------------------------------------
def output_summary(self,
output_stream=sys.stdout,
output_template="--{name}\n\t\t{doc} (default: "
"{default})",
bool_output_template="--{name}\n\t\t{doc}",
short_form_template="\t-{short_form}, ",
no_short_form_template="\t ",
block_password=True):
"""outputs the list of acceptable commands. This is useful as the
output of the 'help' option or usage.
Parameters:
outputStream: where to send the output
sortOption: 0 - sort by the single character option
1 - sort by the long option
with_parameters_template: a string template for
outputing options that have parameters from the long form onward
outputTemplateForOptionsWithoutParameters: a string template for
outputing options that have no parameters from the long form onward
short_form_template: a string template for the first
part of a listing where there is a single letter form of the command
outputTemplatePrefixForNo: a string template for the first part of a
listing where there is no single letter form of the command
"""outputs a usage tip and the list of acceptable commands.
This is useful as the output of the 'help' option or usage.
"""
if self.app_name or self.app_description:
print >> output_stream, 'Application:',
if self.app_name:
print >> output_stream, self.app_name, self.app_version
if self.app_description:
print >> output_stream, self.app_description
if self.app_name or self.app_description:
print >> output_stream, ''

names_list = self.get_option_names()
names_list.sort()
for x in names_list:
if x in self.options_banned_from_help:
if names_list:
print >> output_stream, 'Options:'

for name in names_list:
if name in self.options_banned_from_help:
continue
option = self.get_option_by_name(x)
option = self.get_option_by_name(name)

line = ' ' * 2 # always start with 2 spaces
if option.short_form:
prefix = short_form_template
else:
prefix = no_short_form_template
if isinstance(option.value, bool):
template = bool_output_template
else:
template = output_template
output_parameters = option.__dict__.copy()
output_parameters['name'] = x
if output_parameters['doc'] == None:
output_parameters['doc'] = 'no documentation available'
if block_password and 'password' in option.name.lower():
output_parameters['default'] = '********'
output_parameters['value'] = '********'
template = '%s%s' % (prefix, template)
# in the following line, we want the default to show the values
# that have been read it from config files. In other words,
# we want to show the user what the values will be if they
# make no further action
line += '-%s, ' % option.short_form
line += '--%s' % name
line = line.ljust(30) # seems to the common practise

doc = option.doc if option.doc is not None else ''
try:
value = output_parameters['value']
value = option.value
type_of_value = type(value)
converter_function = conv.to_string_converters[type_of_value]
output_parameters['default'] = converter_function(value)
default = converter_function(value)
except KeyError:
output_parameters['default'] = output_parameters['value']
print >> output_stream, template.format(**output_parameters)
default = option.value
if default is not None:
if 'password' in name.lower():
default = '*********'
if doc:
doc += ' '
if name not in ('help',):
# don't bother with certain dead obvious ones
doc += '(default: %s)' % default

line += doc
print >> output_stream, line


#--------------------------------------------------------------------------
def write_config(self, config_file_type=None,
Expand Down
117 changes: 66 additions & 51 deletions configman/tests/test_config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ def test_output_summary(self):
"""test_output_summary: the output from help"""
n = config_manager.Namespace()
n.add_option('aaa', False, 'the a', short_form='a')
n.add_option('bee', True)
n.b = 17
n.c = config_manager.Namespace()
n.c.add_option('fred', doc='husband from Flintstones')
Expand All @@ -597,58 +598,72 @@ def test_output_summary(self):
manager_controls=False,
#use_config_files=False,
use_auto_help=False,
argv_source=[])
argv_source=[],
#app_name='foo',
#app_version='1.0',
#app_description='This app is cool.'
)
s = StringIO()
c.output_summary(output_stream=s)
r = s.getvalue()
self.assertTrue('Options:\n' in r)

options = r.split('Options:\n')[1]
s.close()

expect = [
'\t-a, --aaa',
'\t\tthe a',
'\t --b',
'\t\tno documentation available (default: 17)',
'\t --c.fred',
'\t\thusband from Flintstones (default: None)',
'\t --d.fred',
'\t\tmale neighbor from I Love Lucy (default: None)',
'\t --d.x.password',
'\t\tthe password (default: ********)',
'\t-s, --d.x.size',
'\t\thow big in tons (default: 100)',
('-a, --aaa', 'the a (default: False)'),
('--b', '(default: 17)'),
('--bee', '(default: True)'),
('--c.fred', 'husband from Flintstones'),
('--d.fred', 'male neighbor from I Love Lucy'),
('--d.x.password', 'the password (default: *********)'),
('-s, --d.x.size', 'how big in tons (default: 100)'),
]
expect = '\n'.join(expect)
self.assertEqual(r.rstrip(), expect.rstrip())

def test_config_manager_output_summary(self):
"""Test that ConfigurationManager().output_summary() works"""
point = -1 # used to assert the sort order
for i, (start, end) in enumerate(expect):
self.assertTrue(point < options.find(start + ' ') < options.find(' ' + end))
point = options.find(end)

def test_output_summary_header(self):
"""a config with an app_name, app_version and app_description is
printed on the output summary.
"""
n = config_manager.Namespace()
n.add_option('aaa', False, 'the a', short_form='a')
n.b = 17
n.c = config_manager.Namespace()
n.c.add_option('fred', doc='the doc',
default="[ ('version', 'fred', 100), "
"('product', 'sally', 100)]",
from_string_converter=eval)
n.c.add_option('wilma', doc='wife from Flintstones')
c = config_manager.ConfigurationManager([n],
c = config_manager.ConfigurationManager(n,
manager_controls=False,
#use_config_files=False,
use_auto_help=False,
argv_source=[])
s = StringIO()
c.output_summary(output_stream=s)
received = s.getvalue()
s.close()
expected = r""" -a, --aaa
the a
--b
no documentation available (default: 17)
--c.fred
the doc (default: [('version', 'fred', 100), ('product', 'sally', 100)])
--c.wilma
wife from Flintstones (default: None)
"""
self.assertEqual(received.strip(), expected.strip())
argv_source=[],
#app_name='foo',
#app_version='1.0',
#app_description='This app is cool.'
)
def get_output(conf):
s = StringIO()
conf.output_summary(output_stream=s)
return s.getvalue()

output = get_output(c)
assert 'Options:' in output
self.assertTrue('Application:' not in output)

c.app_name = 'foobar'
output = get_output(c)
assert 'Options:' in output
self.assertTrue('Application: foobar' in output)

c.app_version = '1.0'
output = get_output(c)
assert 'Options:' in output
self.assertTrue('Application: foobar 1.0' in output)

c.app_description = "This ain't your mama's app"
output = get_output(c)
assert 'Options:' in output
self.assertTrue('Application: foobar 1.0\n' in output)
self.assertTrue("This ain't your mama's app\n\n" in output)


def test_eval_as_converter(self):
"""does eval work as a to string converter on an Option object?"""
Expand Down Expand Up @@ -730,21 +745,21 @@ def output_summary(inner_self):
output_stream = StringIO()
r = super(MyConfigManager, inner_self).output_summary(
output_stream=output_stream,
output_template='{name}-{doc}-{default}',
bool_output_template='{name}-{doc}',
short_form_template='{short_form}',
no_short_form_template='',
block_password=False)
r = output_stream.getvalue()
print r
output_stream.close()
self.assertEqual(r, "fred 1.0\n"
"my app\n"
"help-print this\n"
"password-the password-wilma\n")
self.assertTrue('Application: fred 1.0' in r)
self.assertTrue('my app\n\n' in r)
self.assertTrue('Options:\n' in r)
self.assertTrue(' --help' in r and 'print this' in r)
self.assertTrue('print this (default: True)' not in r)
self.assertTrue(' --password' in r)
self.assertTrue('the password (default: *********)' in r)
self.assertTrue(' --_application' not in r)

def my_exit():
pass

old_sys_exit = sys.exit
sys.exit = my_exit
try:
Expand Down

0 comments on commit f6d8304

Please sign in to comment.