Update CLI Reference generation tool for RST
To migrate CLI Reference from DockBook to RST, output the documentation in RST format, with a few work around for RST/Sphinx specific issue. Change-Id: I32b4cfefa978436061d882f7520bbc92c1645b4e Implements: blueprint cli-ref-rst
This commit is contained in:
parent
4925655305
commit
a25b753af2
@ -89,6 +89,6 @@ git pull
|
||||
branch=update_client_$project
|
||||
git branch --list $branch && git branch -D $branch
|
||||
git checkout -b $branch
|
||||
mv ../output/ch_cli_${project}_commands.xml doc/cli-reference/generated
|
||||
mv ../output/${project}.rst "doc/cli-reference/source"
|
||||
version=$($project --version 2>&1)
|
||||
git commit -a -m "Update CLI reference for python-${project}client ${version##* }"
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import yaml
|
||||
@ -21,6 +22,7 @@ import yaml
|
||||
import os_doc_tools
|
||||
|
||||
DEVNULL = open(os.devnull, 'wb')
|
||||
MAXLINELENGTH = 78
|
||||
|
||||
|
||||
def use_help_flag(os_command):
|
||||
@ -33,28 +35,35 @@ def use_help_flag(os_command):
|
||||
return os_command == "swift" or "-manage" in os_command
|
||||
|
||||
|
||||
def quote_xml(line):
|
||||
"""Convert special characters for XML output."""
|
||||
def quote_rst(line):
|
||||
"""Convert special characters for RST output."""
|
||||
|
||||
line = line.replace('&', '&').replace('<', '<').replace('>', '>')
|
||||
line = line.replace('\\', '\\\\').replace('`', '\\`').replace('*', '\\*')
|
||||
|
||||
if '--' in line:
|
||||
line = re.sub(r'(--[^ .\'\\]*)', r":option:`\1`", line)
|
||||
# work around for "`--`" at murano
|
||||
line = line.replace('\\`:option:`--`\\`', '```--```')
|
||||
|
||||
if 'DEPRECATED!' in line:
|
||||
line = line.replace('DEPRECATED!', '<emphasis>DEPRECATED!</emphasis>')
|
||||
line = line.replace('DEPRECATED!', '**DEPRECATED!**')
|
||||
elif 'DEPRECATED' in line:
|
||||
line = line.replace('DEPRECATED', '<emphasis>DEPRECATED</emphasis>')
|
||||
line = line.replace('DEPRECATED', '**DEPRECATED**')
|
||||
|
||||
if 'env[' in line:
|
||||
line = line.replace('env[', '<code>env[').replace(']', ']</code>')
|
||||
line = line.replace('env[', '``env[').replace(']', ']``')
|
||||
# work around for "Default=env[...]" at cinder
|
||||
line = line.replace('=``', '= ``')
|
||||
|
||||
return line
|
||||
|
||||
|
||||
def generate_heading(os_command, api_name, title, os_file):
|
||||
"""Write DocBook file header.
|
||||
"""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 DocBook file
|
||||
:param os_file: open filehandle for output of RST file
|
||||
"""
|
||||
|
||||
try:
|
||||
@ -70,72 +79,41 @@ def generate_heading(os_command, api_name, title, os_file):
|
||||
|
||||
print("Documenting '%s help (version %s)'" % (os_command, version))
|
||||
|
||||
if use_help_flag(os_command):
|
||||
help_str = "<replaceable>COMMAND</replaceable> <option>--help</option>"
|
||||
else:
|
||||
help_str = "<option>help</option> <replaceable>COMMAND</replaceable>"
|
||||
|
||||
header1 = """<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<chapter xmlns=\"http://docbook.org/ns/docbook\"
|
||||
xmlns:xi=\"http://www.w3.org/2001/XInclude\"
|
||||
xmlns:xlink=\"http://www.w3.org/1999/xlink\"
|
||||
version=\"5.0\"
|
||||
xml:id=\"%(os_command)sclient_commands\">
|
||||
|
||||
<!-- This file is automatically generated, do not edit -->
|
||||
|
||||
<?dbhtml stop-chunking?>
|
||||
|
||||
<title>%(title)s</title>\n"""
|
||||
if os_command == "openstack":
|
||||
header2 = """
|
||||
<para>The <command>%(os_command)s</command> client is a common
|
||||
OpenStack command-line interface (CLI).\n"""
|
||||
else:
|
||||
header2 = """
|
||||
<para>The <command>%(os_command)s</command> client is the command-line
|
||||
interface (CLI) for the %(api_name)s and its extensions.\n"""
|
||||
|
||||
header3 = """
|
||||
This chapter documents <command>%(os_command)s</command> version
|
||||
<literal>%(version)s</literal>.
|
||||
</para>
|
||||
|
||||
<para>For help on a specific <command>%(os_command)s</command>
|
||||
command, enter:
|
||||
</para>
|
||||
<screen><prompt>$</prompt> <userinput><command>%(os_command)s</command> \
|
||||
%(help_str)s</userinput></screen>
|
||||
|
||||
<section xml:id=\"%(os_command)sclient_command_usage\">
|
||||
<title>%(os_command)s usage</title>\n"""
|
||||
os_file.write(".. ## WARNING ######################################\n")
|
||||
os_file.write(".. This file is automatically generated, do not edit\n")
|
||||
os_file.write(".. #################################################\n\n")
|
||||
format_heading(title, 1, os_file)
|
||||
|
||||
if os_command == "keystone":
|
||||
header_deprecation = """
|
||||
<warning>
|
||||
<para>The %(os_command)s CLI is deprecated in favor of
|
||||
python-openstackclient. For more information on
|
||||
python-openstackclient, please see
|
||||
<xref linkend="openstack_cli_identity_api_v2" /> and
|
||||
<xref linkend="openstack_cli_with_identity_api_v3" />.
|
||||
For a Python library, continue
|
||||
using python-%(os_command)sclient.</para>
|
||||
</warning>\n"""
|
||||
else:
|
||||
header_deprecation = None
|
||||
os_file.write(".. warning::\n\n")
|
||||
os_file.write(" The " + os_command + " CLI is deprecated\n")
|
||||
os_file.write(" in favor of python-openstackclient.\n")
|
||||
os_file.write(" For more information, see :doc:`openstack`.\n")
|
||||
os_file.write(" For a Python library, continue using\n")
|
||||
os_file.write(" python-" + os_command + "client.\n\n")
|
||||
|
||||
format_dict = {
|
||||
"os_command": os_command,
|
||||
"api_name": api_name,
|
||||
"title": title,
|
||||
"version": version,
|
||||
"help_str": help_str
|
||||
}
|
||||
os_file.write(header1 % format_dict)
|
||||
if header_deprecation:
|
||||
os_file.write(header_deprecation % format_dict)
|
||||
os_file.write(header2 % format_dict)
|
||||
os_file.write(header3 % format_dict)
|
||||
if os_command == "openstack":
|
||||
os_file.write("The openstack client is a common OpenStack")
|
||||
os_file.write("command-line interface (CLI).\n\n")
|
||||
else:
|
||||
os_file.write("The " + os_command + " client is the command-line ")
|
||||
os_file.write("interface (CLI) for\n")
|
||||
os_file.write("the " + api_name + " and its extensions.\n\n")
|
||||
|
||||
os_file.write("This chapter documents :command:`" + os_command + "` ")
|
||||
os_file.write("version ``" + version + "``.\n\n")
|
||||
|
||||
os_file.write("For help on a specific :command:`" + os_command + "` ")
|
||||
os_file.write("command, enter:\n\n")
|
||||
|
||||
os_file.write(".. code-block:: console\n\n")
|
||||
if use_help_flag(os_command):
|
||||
os_file.write(" $ " + os_command + " COMMAND --help\n\n")
|
||||
else:
|
||||
os_file.write(" $ " + os_command + " help COMMAND\n\n")
|
||||
|
||||
os_file.write(".. _" + os_command + "_command_usage:\n\n")
|
||||
format_heading(os_command + " usage", 2, os_file)
|
||||
|
||||
|
||||
def is_option(string):
|
||||
@ -233,13 +211,42 @@ def extract_options(line):
|
||||
return split_line
|
||||
|
||||
|
||||
def format_table(title, lines, os_file):
|
||||
"""Nicely print section of lines."""
|
||||
def format_heading(heading, level, os_file):
|
||||
"""Nicely print heading.
|
||||
|
||||
:param heading: heading strings
|
||||
:param level: heading level
|
||||
:param os_file: open filehandle for output of RST file
|
||||
"""
|
||||
|
||||
if level == 1:
|
||||
os_file.write("=" * len(heading) + "\n")
|
||||
|
||||
os_file.write(heading + "\n")
|
||||
|
||||
if level == 1:
|
||||
os_file.write("=" * len(heading) + "\n\n")
|
||||
elif level == 2:
|
||||
os_file.write("~" * len(heading) + "\n\n")
|
||||
elif level == 3:
|
||||
os_file.write("-" * len(heading) + "\n\n")
|
||||
else:
|
||||
os_file.write("\n")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def format_help(title, lines, os_file):
|
||||
"""Nicely print section of lines.
|
||||
|
||||
:param title: help title, if exist
|
||||
:param lines: strings to format
|
||||
:param os_file: open filehandle for output of RST file
|
||||
"""
|
||||
|
||||
close_entry = False
|
||||
os_file.write(" <variablelist wordsize=\"10\">\n")
|
||||
if title:
|
||||
os_file.write(" <title>%s</title>\n" % title)
|
||||
format_heading(title, 3, os_file)
|
||||
|
||||
for line in lines:
|
||||
if not line or line[0] != ' ':
|
||||
@ -252,9 +259,13 @@ def format_table(title, lines, os_file):
|
||||
# on next line
|
||||
# If there are more than 8 spaces, let's treat it as
|
||||
# explanation.
|
||||
if line.startswith(' '):
|
||||
if line.startswith(' '):
|
||||
# Explanation
|
||||
os_file.write(" %s\n" % quote_xml(line.lstrip(' ')))
|
||||
xline = quote_rst(line.lstrip(' '))
|
||||
if len(xline) > (MAXLINELENGTH - 2):
|
||||
# check niceness
|
||||
xline = xline.replace(' ', '\n ')
|
||||
os_file.write(" " + xline + "\n")
|
||||
continue
|
||||
# Now we have a command or parameter to handle
|
||||
split_line = extract_options(line)
|
||||
@ -262,31 +273,41 @@ def format_table(title, lines, os_file):
|
||||
if not close_entry:
|
||||
close_entry = True
|
||||
else:
|
||||
os_file.write(" </para>\n")
|
||||
os_file.write(" </listitem>\n")
|
||||
os_file.write(" </varlistentry>\n")
|
||||
os_file.write("\n")
|
||||
|
||||
xline = split_line[0]
|
||||
|
||||
# check niceness work around for long option name
|
||||
if len(xline) > (MAXLINELENGTH - 4):
|
||||
xline = xline.replace(', -', ',``\n\n``-')
|
||||
|
||||
# check niceness work around for long option name, openstack
|
||||
xline = xline.replace('--nic <net-id=net-uuid,v4-fixed-ip',
|
||||
'--nic <net-id=net-uuid,``\n\n``v4-fixed-ip')
|
||||
|
||||
# check niceness work around for long option name, glance
|
||||
xline = xline.replace('--sort-key {name,status,container',
|
||||
'--sort-key {name,status,``\n\n``container')
|
||||
|
||||
os_file.write("``" + xline + "``\n")
|
||||
|
||||
os_file.write(" <varlistentry>\n")
|
||||
os_file.write(" <term><command>%s</command></term>\n"
|
||||
% quote_xml(split_line[0]))
|
||||
os_file.write(" <listitem>\n")
|
||||
os_file.write(" <para>\n")
|
||||
if len(split_line) > 1:
|
||||
os_file.write(" %s\n" % quote_xml(split_line[1]))
|
||||
xline = quote_rst(split_line[1])
|
||||
if len(xline) > (MAXLINELENGTH - 2):
|
||||
# check niceness
|
||||
xline = xline.replace(' ', '\n ')
|
||||
os_file.write(" " + xline + "\n")
|
||||
|
||||
os_file.write(" </para>\n")
|
||||
os_file.write(" </listitem>\n")
|
||||
os_file.write(" </varlistentry>\n")
|
||||
os_file.write(" </variablelist>\n")
|
||||
os_file.write("\n")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def generate_command(os_command, os_file):
|
||||
"""Convert os_command --help to DocBook.
|
||||
"""Convert os_command --help to RST.
|
||||
|
||||
:param os_command: client command to document
|
||||
:param os_file: open filehandle for output of DocBook file
|
||||
:param os_file: open filehandle for output of RST file
|
||||
"""
|
||||
|
||||
if os_command == "glance":
|
||||
@ -300,13 +321,11 @@ def generate_command(os_command, os_file):
|
||||
|
||||
ignore_next_lines = False
|
||||
next_line_screen = True
|
||||
next_line_screen = True
|
||||
line_index = -1
|
||||
in_screen = False
|
||||
subcommands = 'complete'
|
||||
for line in help_lines:
|
||||
line_index += 1
|
||||
xline = quote_xml(line)
|
||||
if line and line[0] != ' ':
|
||||
# XXX: Might have whitespace before!!
|
||||
if '<subcommands>' in line:
|
||||
@ -315,69 +334,52 @@ def generate_command(os_command, os_file):
|
||||
if 'Positional arguments' in line:
|
||||
ignore_next_lines = True
|
||||
next_line_screen = True
|
||||
os_file.write("</computeroutput></screen>\n")
|
||||
os_file.write("\n\n")
|
||||
in_screen = False
|
||||
if os_command != "glance":
|
||||
format_table('Subcommands',
|
||||
help_lines[line_index + 2:], os_file)
|
||||
format_help('Subcommands',
|
||||
help_lines[line_index + 2:], os_file)
|
||||
continue
|
||||
if line.startswith(('Optional arguments:', 'Optional:',
|
||||
'Options:', 'optional arguments')):
|
||||
if in_screen:
|
||||
os_file.write("</computeroutput></screen>\n")
|
||||
os_file.write("\n\n")
|
||||
in_screen = False
|
||||
os_file.write(" </section>\n")
|
||||
os_file.write(" <section ")
|
||||
os_file.write("xml:id=\"%sclient_command_optional\">\n"
|
||||
% os_command)
|
||||
os_file.write(" <title>%s optional arguments</title>\n"
|
||||
% os_command)
|
||||
format_table('', help_lines[line_index + 1:],
|
||||
os_file)
|
||||
os_file.write(".. _" + os_command + "_command_options:\n\n")
|
||||
format_heading(os_command + " optional arguments", 2, os_file)
|
||||
format_help('', help_lines[line_index + 1:], os_file)
|
||||
next_line_screen = True
|
||||
ignore_next_lines = True
|
||||
continue
|
||||
# sahara
|
||||
# magnum and sahara
|
||||
if line.startswith('Common auth options'):
|
||||
if in_screen:
|
||||
os_file.write("</computeroutput></screen>\n")
|
||||
os_file.write("\n\n")
|
||||
in_screen = False
|
||||
os_file.write(" </section>\n")
|
||||
os_file.write(" <section ")
|
||||
os_file.write("xml:id=\"%sclient_command_common_auth\">\n"
|
||||
% os_command)
|
||||
os_file.write(" <title>%s common authentication "
|
||||
"arguments</title>\n"
|
||||
% os_command)
|
||||
format_table('', help_lines[line_index + 1:],
|
||||
os_file)
|
||||
os_file.write("\n")
|
||||
os_file.write(os_command)
|
||||
os_file.write(".. _" + os_command + "_common_auth:\n\n")
|
||||
format_heading(os_command + " common authentication arguments",
|
||||
2, os_file)
|
||||
format_help('', help_lines[line_index + 1:], os_file)
|
||||
next_line_screen = True
|
||||
ignore_next_lines = True
|
||||
continue
|
||||
# neutron
|
||||
if line.startswith('Commands for API v2.0:'):
|
||||
if in_screen:
|
||||
os_file.write("</computeroutput></screen>\n")
|
||||
os_file.write("\n\n")
|
||||
in_screen = False
|
||||
os_file.write(" </section>\n")
|
||||
os_file.write(" <section ")
|
||||
os_file.write("xml:id=\"%sclient_command_api_2_0\">\n"
|
||||
% os_command)
|
||||
os_file.write(" <title>%s API v2.0 commands</title>\n"
|
||||
% os_command)
|
||||
format_table('', help_lines[line_index + 1:],
|
||||
os_file)
|
||||
os_file.write(".. _" + os_command + "_common_api_v2:\n\n")
|
||||
format_heading(os_command + " API v2.0 commands", 2, os_file)
|
||||
format_help('', help_lines[line_index + 1:], os_file)
|
||||
next_line_screen = True
|
||||
ignore_next_lines = True
|
||||
continue
|
||||
# swift
|
||||
if line.startswith('Examples:'):
|
||||
os_file.write(" </section>\n")
|
||||
os_file.write(" <section ")
|
||||
os_file.write("xml:id=\"%sclient_command_examples\">\n"
|
||||
% os_command)
|
||||
os_file.write(" <title>%s examples</title>\n"
|
||||
% os_command)
|
||||
os_file.write(".. _" + os_command + "_examples:\n\n")
|
||||
format_heading(os_command + " examples", 2, os_file)
|
||||
next_line_screen = True
|
||||
ignore_next_lines = False
|
||||
continue
|
||||
@ -385,31 +387,31 @@ def generate_command(os_command, os_file):
|
||||
continue
|
||||
if not ignore_next_lines:
|
||||
if next_line_screen:
|
||||
os_file.write(" <screen><computeroutput>%s" % xline)
|
||||
os_file.write(".. code-block:: console\n\n")
|
||||
os_file.write(" " + line)
|
||||
next_line_screen = False
|
||||
in_screen = True
|
||||
elif line:
|
||||
os_file.write("\n%s" % xline.rstrip())
|
||||
os_file.write("\n " + line.rstrip())
|
||||
# subcommands (select bash-completion, complete for bash-completion)
|
||||
if 'bash-completion' in line:
|
||||
subcommands = 'bash-completion'
|
||||
|
||||
if in_screen:
|
||||
os_file.write("</computeroutput></screen>\n")
|
||||
os_file.write("\n\n")
|
||||
|
||||
os_file.write(" </section>\n")
|
||||
return subcommands
|
||||
|
||||
|
||||
def generate_subcommand(os_command, os_subcommand, os_file, extra_params,
|
||||
suffix, title_suffix):
|
||||
"""Convert os_command help os_subcommand to DocBook.
|
||||
"""Convert os_command help os_subcommand to RST.
|
||||
|
||||
:param os_command: client command to document
|
||||
:param os_subcommand: client subcommand to document
|
||||
:param os_file: open filehandle for output of DocBook file
|
||||
:param os_file: open filehandle for output of RST file
|
||||
:param extra_params: Extra parameter to pass to os_command
|
||||
:param suffix: Extra suffix to add to xml:id
|
||||
:param suffix: Extra suffix to add to link ID
|
||||
:param title_suffix: Extra suffix for title
|
||||
"""
|
||||
|
||||
@ -440,17 +442,14 @@ def generate_subcommand(os_command, os_subcommand, os_file, extra_params,
|
||||
help_lines = help_lines.split('\n')
|
||||
|
||||
os_subcommandid = os_subcommand.replace(' ', '_')
|
||||
os_file.write(" <section xml:id=\"%sclient_subcommand_%s%s\">\n"
|
||||
% (os_command, os_subcommandid, suffix))
|
||||
os_file.write(" <title>%s %s%s</title>\n"
|
||||
% (os_command, os_subcommand, title_suffix))
|
||||
os_file.write(".. _" + os_command + "_" + os_subcommandid + suffix)
|
||||
os_file.write(":\n\n")
|
||||
format_heading(os_command + " " + os_subcommand + title_suffix, 2, os_file)
|
||||
|
||||
if os_command == "swift":
|
||||
next_line_screen = False
|
||||
os_file.write("\n <screen><computeroutput>Usage: swift %s"
|
||||
"</computeroutput></screen>"
|
||||
% (os_subcommand))
|
||||
os_file.write("\n <para>")
|
||||
os_file.write(".. code-block:: console\n\n")
|
||||
os_file.write("Usage: swift " + os_subcommand + "\n\n")
|
||||
in_para = True
|
||||
else:
|
||||
next_line_screen = True
|
||||
@ -477,39 +476,47 @@ def generate_subcommand(os_command, os_subcommand, os_file, extra_params,
|
||||
'optional arguments')):
|
||||
if in_para:
|
||||
in_para = False
|
||||
os_file.write("\n </para>")
|
||||
os_file.write("\n")
|
||||
if line.startswith(('Positional arguments',
|
||||
'positional arguments')):
|
||||
format_table('Positional arguments',
|
||||
help_lines[line_index + 1:], os_file)
|
||||
format_help('Positional arguments',
|
||||
help_lines[line_index + 1:], os_file)
|
||||
skip_lines = True
|
||||
continue
|
||||
elif line.startswith(('Optional arguments:',
|
||||
'optional arguments')):
|
||||
format_table('Optional arguments',
|
||||
help_lines[line_index + 1:], os_file)
|
||||
format_help('Optional arguments',
|
||||
help_lines[line_index + 1:], os_file)
|
||||
break
|
||||
else:
|
||||
format_table('Arguments', help_lines[line_index + 1:], os_file)
|
||||
format_help('Arguments', help_lines[line_index + 1:], os_file)
|
||||
break
|
||||
if skip_lines:
|
||||
continue
|
||||
if not line:
|
||||
if not in_para:
|
||||
os_file.write("</computeroutput></screen>")
|
||||
os_file.write("\n <para>")
|
||||
os_file.write("\n")
|
||||
in_para = True
|
||||
continue
|
||||
xline = quote_xml(line)
|
||||
if next_line_screen:
|
||||
os_file.write(" <screen><computeroutput>%s" % xline)
|
||||
os_file.write(".. code-block:: console\n\n")
|
||||
os_file.write(" " + line + "\n")
|
||||
next_line_screen = False
|
||||
elif line.startswith(' '):
|
||||
# ceilometer alarm-gnocchi-aggregation-by-metrics-threshold-create
|
||||
# has 7 white space indentation
|
||||
if not line.isspace():
|
||||
# skip blank line, such as "trove help cluster-grow" command.
|
||||
os_file.write(" " + line + "\n")
|
||||
else:
|
||||
os_file.write("\n%s" % (xline))
|
||||
xline = quote_rst(line)
|
||||
if (len(xline) > MAXLINELENGTH):
|
||||
# check niceness
|
||||
xline = xline.replace(' ', '\n')
|
||||
os_file.write(xline + "\n")
|
||||
|
||||
if in_para:
|
||||
os_file.write("\n </para>\n")
|
||||
os_file.write(" </section>\n")
|
||||
os_file.write("\n")
|
||||
|
||||
|
||||
def discover_subcommands(os_command, subcommands, extra_params):
|
||||
@ -558,14 +565,14 @@ def discover_subcommands(os_command, subcommands, extra_params):
|
||||
|
||||
def generate_subcommands(os_command, os_file, subcommands, extra_params,
|
||||
suffix, title_suffix):
|
||||
"""Convert os_command help subcommands for all subcommands to DocBook.
|
||||
"""Convert os_command help subcommands for all subcommands to RST.
|
||||
|
||||
:param os_command: client command to document
|
||||
:param os_file: open filehandle for output of DocBook file
|
||||
:param os_file: open filehandle for output of RST file
|
||||
:param subcommands: list or type ('complete' or 'bash-completion')
|
||||
of subcommands to document
|
||||
:param extra_params: Extra parameter to pass to os_command.
|
||||
:param suffix: Extra suffix to add to xml:id
|
||||
:param suffix: Extra suffix to add to link ID
|
||||
:param title_suffix: Extra suffix for title
|
||||
"""
|
||||
for subcommand in subcommands:
|
||||
@ -576,14 +583,14 @@ def generate_subcommands(os_command, os_file, subcommands, extra_params,
|
||||
|
||||
def discover_and_generate_subcommands(os_command, os_file, subcommands,
|
||||
extra_params, suffix, title_suffix):
|
||||
"""Convert os_command help subcommands for all subcommands to DocBook.
|
||||
"""Convert os_command help subcommands for all subcommands to RST.
|
||||
|
||||
:param os_command: client command to document
|
||||
:param os_file: open filehandle for output of DocBook file
|
||||
:param os_file: open filehandle for output of RST file
|
||||
:param subcommands: list or type ('complete' or 'bash-completion')
|
||||
of subcommands to document
|
||||
:param extra_params: Extra parameter to pass to os_command.
|
||||
:param suffix: Extra suffix to add to xml:id
|
||||
:param suffix: Extra suffix to add to link ID
|
||||
:param title_suffix: Extra suffix for title
|
||||
"""
|
||||
subcommands = discover_subcommands(os_command, subcommands, extra_params)
|
||||
@ -591,16 +598,6 @@ def discover_and_generate_subcommands(os_command, os_file, subcommands,
|
||||
suffix, title_suffix)
|
||||
|
||||
|
||||
def generate_end(os_file):
|
||||
"""Finish writing file.
|
||||
|
||||
:param os_file: open filehandle for output of DocBook file
|
||||
"""
|
||||
|
||||
print("Finished.\n")
|
||||
os_file.write("</chapter>\n")
|
||||
|
||||
|
||||
def get_clients():
|
||||
"""Load client definitions from the resource file."""
|
||||
fname = os.path.join(os.path.dirname(__file__),
|
||||
@ -628,21 +625,18 @@ def document_single_project(os_command, output_dir):
|
||||
api_name = ''
|
||||
title = data.get('title', '')
|
||||
|
||||
out_filename = "ch_cli_" + os_command + "_commands.xml"
|
||||
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)
|
||||
subcommands = generate_command(os_command, out_file)
|
||||
|
||||
if os_command == 'cinder':
|
||||
out_file.write("""
|
||||
<section xml:id=\"cinder_cli_v1\">
|
||||
<title>Block Storage API v1 commands (DEPRECATED)</title>\n""")
|
||||
format_heading("Block Storage API v1 commands (DEPRECATED)",
|
||||
2, out_file)
|
||||
discover_and_generate_subcommands(os_command, out_file, subcommands,
|
||||
None, "", "")
|
||||
elif os_command == 'openstack':
|
||||
out_file.write("""
|
||||
<section xml:id=\"openstack_cli_identity_api_v2\">
|
||||
<title>OpenStack with Identity API v2 commands</title>\n""")
|
||||
format_heading("OpenStack with Identity API v2 commands", 2, out_file)
|
||||
auth_type_token = ["--os-auth-type", "token"]
|
||||
identity_api_v2 = ["--os-identity-api-version", "2"]
|
||||
extra_params = auth_type_token + identity_api_v2
|
||||
@ -651,9 +645,7 @@ def document_single_project(os_command, output_dir):
|
||||
generate_subcommands(os_command, out_file, subcommands_v2,
|
||||
extra_params, "_with_identity_api_v2", "")
|
||||
elif os_command == 'glance':
|
||||
out_file.write("""
|
||||
<section xml:id=\"glance_cli_v1\">
|
||||
<title>Image service API v1 commands</title>\n""")
|
||||
format_heading("Image service API v1 commands", 2, out_file)
|
||||
discover_and_generate_subcommands(os_command, out_file, subcommands,
|
||||
["--os-image-api-version", "1"],
|
||||
"_v1", " (v1)")
|
||||
@ -663,40 +655,37 @@ def document_single_project(os_command, output_dir):
|
||||
|
||||
# Print subcommands for different API versions
|
||||
if os_command == 'cinder':
|
||||
out_file.write(" </section>\n")
|
||||
out_file.write("""
|
||||
<section xml:id=\"cinder_cli_v2\">
|
||||
<title>Block Storage API v2 commands</title>
|
||||
<para>
|
||||
You can select an API version to use by adding the
|
||||
<parameter>--os-volume-api-version</parameter> parameter or by setting
|
||||
the corresponding environment variable:\n""")
|
||||
out_file.write("<screen><prompt>$</prompt> <userinput>"
|
||||
"export OS_VOLUME_API_VERSION=2</userinput></screen>\n"
|
||||
"</para>\n")
|
||||
out_file.write("\n")
|
||||
format_heading("Block Storage API v2 commands", 2, out_file)
|
||||
|
||||
out_file.write("You can select an API version to use by adding the\n")
|
||||
out_file.write(":option:`--os-volume-api-version` parameter or by\n")
|
||||
out_file.write("setting the corresponding environment variable:\n\n")
|
||||
|
||||
out_file.write(".. code-block:: console\n\n")
|
||||
out_file.write(" export OS_VOLUME_API_VERSION=2\n\n")
|
||||
|
||||
discover_and_generate_subcommands(os_command, out_file, subcommands,
|
||||
["--os-volume-api-version", "2"],
|
||||
"_v2", " (v2)")
|
||||
out_file.write(" </section>\n")
|
||||
if os_command == 'openstack':
|
||||
# Print the additional subcommands possible by using v3 of identity API
|
||||
out_file.write("""
|
||||
</section>\n
|
||||
<section xml:id=\"openstack_cli_with_identity_api_v3\">
|
||||
<title>OpenStack with Identity API v3 commands (diff)</title>
|
||||
<para>
|
||||
You can select the Identity API version to use by adding the
|
||||
<parameter>--os-identity-api-version</parameter> parameter or by setting
|
||||
the corresponding environment variable:\n""")
|
||||
out_file.write("<screen><prompt>$</prompt> <userinput>"
|
||||
"export OS_IDENTITY_API_VERSION=3</userinput>"
|
||||
"</screen>\n</para>\n")
|
||||
out_file.write("<para>\n"
|
||||
"This section documents only the difference in"
|
||||
" subcommands available for the openstack client when"
|
||||
" the identity API version is changed from v2 to v3.\n"
|
||||
"</para>\n")
|
||||
out_file.write("\n")
|
||||
format_heading("OpenStack with Identity API v3 commands (diff)",
|
||||
2, out_file)
|
||||
|
||||
out_file.write("You can select the Identity API version to use by\n")
|
||||
out_file.write("adding the :option:`--os-identity-api-version`\n")
|
||||
out_file.write("parameter or by setting the corresponding\n")
|
||||
out_file.write("environment variable:\n\n")
|
||||
|
||||
out_file.write(".. code-block:: console\n\n")
|
||||
out_file.write(" export OS_IDENTITY_API_VERSION=3\n\n")
|
||||
|
||||
out_file.write("This section documents only the difference in\n")
|
||||
out_file.write("subcommands available for the openstack client\n")
|
||||
out_file.write("when the Identity API version is changed from\n")
|
||||
out_file.write("v2 to v3.\n\n")
|
||||
|
||||
identity_api_v3 = ["--os-identity-api-version", "3"]
|
||||
extra_params = auth_type_token + identity_api_v3
|
||||
@ -707,30 +696,24 @@ def document_single_project(os_command, output_dir):
|
||||
generate_subcommands(os_command, out_file, subcommands_delta,
|
||||
extra_params, "_with_identity_api_v3",
|
||||
" (Identity API v3)")
|
||||
out_file.write(" </section>\n")
|
||||
if os_command == 'glance':
|
||||
out_file.write("""
|
||||
</section>\n
|
||||
<section xml:id=\"glance_cli_v2\">
|
||||
<title>Image service API v2 commands</title>
|
||||
<para>
|
||||
You can select an API version to use by adding the
|
||||
<parameter>--os-image-api-version</parameter> parameter or by setting
|
||||
the corresponding environment variable:\n""")
|
||||
out_file.write("<screen><prompt>$</prompt> <userinput>"
|
||||
"export OS_IMAGE_API_VERSION=2</userinput></screen>\n"
|
||||
"</para>\n")
|
||||
out_file.write("\n")
|
||||
format_heading("Image service API v2 commands", 2, out_file)
|
||||
out_file.write("You can select an API version to use by adding the\n")
|
||||
out_file.write(":option:`--os-image-api-version` parameter or by\n")
|
||||
out_file.write("setting the corresponding environment variable:\n\n")
|
||||
|
||||
out_file.write(".. code-block:: console\n\n")
|
||||
out_file.write(" export OS_IMAGE_API_VERSION=2\n\n")
|
||||
|
||||
discover_and_generate_subcommands(os_command, out_file, subcommands,
|
||||
["--os-image-api-version", "2"],
|
||||
"_v2", " (v2)")
|
||||
out_file.write(" </section>\n")
|
||||
|
||||
if os_command == 'glance':
|
||||
out_file.write(" <xi:include "
|
||||
"href=\"../section_cli_glance_property_keys.xml\"/>\n")
|
||||
out_file.write(".. include:: glance_property_keys.rst\n")
|
||||
|
||||
generate_end(out_file)
|
||||
print("Finished.\n")
|
||||
out_file.close()
|
||||
|
||||
|
||||
@ -744,7 +727,7 @@ def main():
|
||||
manage_clients = sorted([x for x in clients if x.endswith('-manage')])
|
||||
all_clients = api_clients + manage_clients
|
||||
|
||||
parser = argparse.ArgumentParser(description="Generate DocBook XML files "
|
||||
parser = argparse.ArgumentParser(description="Generate RST files "
|
||||
"to document python-PROJECTclients.")
|
||||
parser.add_argument('client', nargs='?',
|
||||
help="OpenStack command to document. One of: " +
|
||||
|
6
releasenotes/notes/cli-ref-rst-20365acfdba086f2.yaml
Normal file
6
releasenotes/notes/cli-ref-rst-20365acfdba086f2.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- Update CLI Reference generation tool for RST.
|
||||
To migrate CLI Reference from DocBook to RST,
|
||||
output the documentation in RST format,
|
||||
with a few work arounds for RST/Sphinx specific issues.
|
Loading…
x
Reference in New Issue
Block a user