Browse Source

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
changes/27/265627/14
KATO Tomoyuki 6 years ago
parent
commit
a25b753af2
  1. 2
      bin/doc-tools-update-cli-reference
  2. 437
      os_doc_tools/commands.py
  3. 6
      releasenotes/notes/cli-ref-rst-20365acfdba086f2.yaml

2
bin/doc-tools-update-cli-reference

@ -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##* }"

437
os_doc_tools/commands.py

@ -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('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
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 -->
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)
<?dbhtml stop-chunking?>
if os_command == "keystone":
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")
<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"""
os_file.write("The openstack client is a common OpenStack")
os_file.write("command-line interface (CLI).\n\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"""
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")
header3 = """
This chapter documents <command>%(os_command)s</command> version
<literal>%(version)s</literal>.
</para>
os_file.write("This chapter documents :command:`" + os_command + "` ")
os_file.write("version ``" + version + "``.\n\n")
<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>
os_file.write("For help on a specific :command:`" + os_command + "` ")
os_file.write("command, enter:\n\n")
<section xml:id=\"%(os_command)sclient_command_usage\">
<title>%(os_command)s usage</title>\n"""
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"""
os_file.write(".. code-block:: console\n\n")
if use_help_flag(os_command):
os_file.write(" $ " + os_command + " COMMAND --help\n\n")
else:
header_deprecation = None
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)
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(" <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")
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")
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

@ -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…
Cancel
Save