[cli-ref] Add support for multiple clients

- added ability to supply multiple clients at a time.
- added flag to continue processing clients even if an error
  occurs.
- fixed issue where an empty file was created if the client
  wasn't found.
- fixed issue where specifying --all-api and --all-manage would
  result in only --all-api being generated.

Change-Id: I8586279d884e1223ee7eb8ab12f50aa5ddc82561
This commit is contained in:
Peter Stachowski 2016-04-18 21:13:41 +00:00
parent 28dae6445b
commit 5034807430

@ -58,12 +58,15 @@ def quote_rst(line):
return line
def generate_heading(os_command, api_name, title, os_file):
def generate_heading(os_command, api_name, title,
output_dir, os_filename, continue_on_error):
"""Write RST file header.
:param os_command: client command to document
:param api_name: string description of the API of os_command
:param os_file: open filehandle for output of RST file
:param os_command: client command to document
:param api_name: string description of the API of os_command
:param output_dir: directory to write output file to
:param os_filename: name to create current output file as
:param continue_on_error: continue even if there's an error
"""
try:
@ -72,13 +75,18 @@ def generate_heading(os_command, api_name, title, os_file):
stderr=subprocess.STDOUT)
except OSError as e:
if e.errno == os.errno.ENOENT:
print("Command %s not found, aborting." % os_command)
sys.exit(1)
action = 'skipping' if continue_on_error else 'aborting'
print("Command %s not found, %s." % (os_command, action))
if continue_on_error:
return
else:
sys.exit(1)
# Extract version from "swift 0.3"
version = version.splitlines()[-1].strip().rpartition(' ')[2]
print("Documenting '%s help (version %s)'" % (os_command, version))
os_file = open(os.path.join(output_dir, os_filename), 'w')
os_file.write(".. ## WARNING ######################################\n")
os_file.write(".. This file is automatically generated, do not edit\n")
os_file.write(".. #################################################\n\n")
@ -114,6 +122,7 @@ def generate_heading(os_command, api_name, title, os_file):
os_file.write(".. _" + os_command + "_command_usage:\n\n")
format_heading(os_command + " usage", 2, os_file)
return os_file
def is_option(string):
@ -587,22 +596,30 @@ def discover_and_generate_subcommands(os_command, os_file, subcommands,
suffix, title_suffix)
def _get_clients_filename():
return os.path.join(os.path.dirname(__file__),
'resources/clients.yaml')
def get_clients():
"""Load client definitions from the resource file."""
fname = os.path.join(os.path.dirname(__file__),
'resources/clients.yaml')
fname = _get_clients_filename()
clients = yaml.load(open(fname, 'r'))
return clients
def document_single_project(os_command, output_dir):
def document_single_project(os_command, output_dir, continue_on_error):
"""Create documentation for os_command."""
clients = get_clients()
if os_command not in clients:
print("'%s' command not yet handled" % os_command)
sys.exit(-1)
print("(Command must be defined in '%s')" % _get_clients_filename())
if continue_on_error:
return False
else:
sys.exit(-1)
print("Documenting '%s'" % os_command)
@ -615,8 +632,15 @@ def document_single_project(os_command, output_dir):
title = data.get('title', '')
out_filename = os_command + ".rst"
out_file = open(os.path.join(output_dir, out_filename), 'w')
generate_heading(os_command, api_name, title, out_file)
out_file = generate_heading(os_command, api_name, title,
output_dir, out_filename,
continue_on_error)
if not out_file:
if continue_on_error:
return False
else:
sys.exit(-1)
subcommands = generate_command(os_command, out_file)
if os_command == 'cinder':
@ -705,13 +729,10 @@ def document_single_project(os_command, output_dir):
print("Finished.\n")
out_file.close()
return True
def main():
print("OpenStack Auto Documenting of Commands (using "
"openstack-doc-tools version %s)\n"
% os_doc_tools.__version__)
clients = get_clients()
api_clients = sorted([x for x in clients if not x.endswith('-manage')])
manage_clients = sorted([x for x in clients if x.endswith('-manage')])
@ -719,8 +740,10 @@ def main():
parser = argparse.ArgumentParser(description="Generate RST files "
"to document python-PROJECTclients.")
parser.add_argument('client', nargs='?',
help="OpenStack command to document. One of: " +
parser.add_argument('clients', metavar='client', nargs='*',
help="OpenStack command to document. Specify "
"multiple times to generate documentation for "
"multiple clients. One of: " +
", ".join(all_clients) + ".")
parser.add_argument("--all", help="Document all clients. "
"Namely " + ", ".join(all_clients) + ".",
@ -733,20 +756,43 @@ def main():
action="store_true")
parser.add_argument("--output-dir", default=".",
help="Directory to write generated files to")
parser.add_argument("--continue-on-error", default=False,
help="Continue with remaining clients even if an "
"error occurs generating a client file.",
action="store_true")
prog_args = parser.parse_args()
client_list = []
if prog_args.all or prog_args.all_api or prog_args.all_manage:
if prog_args.all or prog_args.all_api:
for client in clients.keys():
document_single_project(client, prog_args.output_dir)
client_list = api_clients
if prog_args.all or prog_args.all_manage:
for client in manage_clients:
document_single_project(client, prog_args.output_dir)
elif prog_args.client is None:
client_list.extend(manage_clients)
elif prog_args.clients:
client_list = prog_args.clients
if not client_list:
parser.print_help()
sys.exit(1)
else:
document_single_project(prog_args.client, prog_args.output_dir)
print("OpenStack Auto Documenting of Commands (using "
"openstack-doc-tools version %s)\n"
% os_doc_tools.__version__)
success_list = []
error_list = []
for client in client_list:
if document_single_project(
client, prog_args.output_dir, prog_args.continue_on_error):
success_list.append(client)
else:
error_list.append(client)
if success_list:
print("Generated documentation for: %s" % ", ".join(success_list))
if error_list:
print("Generation failed for: %s" % ", ".join(error_list))
sys.exit(1)
if __name__ == "__main__":