Skip to content

Commit

Permalink
docs(sphinx-conf): Update CLI doc. process to handle uncommon CLI gro…
Browse files Browse the repository at this point in the history
…ups cases
  • Loading branch information
santiagogaray committed Mar 24, 2021
1 parent ce62cf0 commit fa35913
Showing 1 changed file with 62 additions and 49 deletions.
111 changes: 62 additions & 49 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
}

autodoc_member_order = 'groupwise'

# -- CLI documentation -------------------------------------------------------
"""Improves the CLI documentation section.
Expand All @@ -233,8 +234,6 @@
Note:
This process assumes that each CLI module represent a group of subcommands.
Important: Use hash tables below to address special cases such as
command group names different from their module file name.
"""
# Activate this CLI documentation process
custom_cli_docs = True
Expand All @@ -253,18 +252,6 @@
# Format: {library_name: tool_name}
ht_lib_tool = {}

# Cli_file/cli_group hash table.
# Created to address CLI file names that differ from the included CLI group name
# Format: {
# library_name_1: {CLI_filename_1: group_name_1,
# CLI_filename_2: group_name_2
# },
# library_name_2: {CLI_filename_3: group_name_3,
# CLI_filename_4: group_name_4
# }
# }
ht_cli_file_group = {}


def create_cli_files():
"""Generate additional files required by sphinx to build well structured
Expand All @@ -281,29 +268,37 @@ def create_cli_files():
if not result:
return

all_groups, lib_name, tool_name = result
ht_cli, lib_name, tool_name = result

# Prepare docs folder and reST files to create
doc_folder = os.path.join(proj_folder, 'cli')
if not os.path.isdir(doc_folder):
os.mkdir(doc_folder)

# Exclude CLI groups if corresponding reST file detected in docs/cli
new_groups = [name for name in all_groups
if name + ".rst" not in os.listdir(doc_folder)]

if not cli_overwrite and not new_groups:
print("[CLI]: No new CLI files created.")
return
# Create new groups only list by excluding CLI groups that have a reST file
# inside docs/cli
def get_new_groups_only():
ht_new_cli_groups = {}
for mod_name in ht_cli.keys():
if mod_name + ".rst" not in os.listdir(doc_folder):
ht_new_cli_groups[mod_name] = ht_cli[mod_name]
return ht_new_cli_groups

if not cli_overwrite:
ht_new_cli = get_new_groups_only()
if not ht_new_cli:
print("[CLI]: No new CLI files created.")
return
else:
ht_new_cli = ht_cli

# Create CLI reST files for each module(command group) found.
click_groups = all_groups if cli_overwrite else new_groups
result = write_cli_files(click_groups, lib_name, tool_name, doc_folder)
result = write_cli_files(ht_new_cli, lib_name, tool_name, doc_folder)
if not result:
print("[CLI]: Something went wrong during CLI docs generation")

# Update/Create index file with command group section included
update_cli_index(os.path.join(doc_folder, 'index.rst'), all_groups)
update_cli_index(os.path.join(doc_folder, 'index.rst'), ht_cli.keys())


def get_cli_data(project_folder):
Expand Down Expand Up @@ -354,29 +349,53 @@ def get_cli_data(project_folder):
print("[CLI data]: No CLI library found")
return None

# Generate a list with the module source files(.py).
# Get CLI module names and their corresponding group names as a dictionary
ht_mod_group = get_cli_groups(cli_path)

if ht_mod_group == {}:
print("[CLI data]: No CLI modules detected in /cli folder.")
return None

# Return library data
return ht_mod_group, lib_name, tool_name


def get_cli_groups(cli_path):
"""Retrieve CLI group data found inside a specified cli path.
Args:
cli_path: the path that contains the CLI modules to extract group
data from.
Returns:
A dictionary with module file names and the corresponding
group names found.
"""
module_names = [os.path.splitext(file)[0] for file in os.listdir(cli_path)
if os.path.splitext(file)[1] == ".py"]

# Remove files that aren't a cli module
discard_names = ["__init__", "util", "helper"]
module_names = [name for name in module_names if name not in discard_names
and not name.startswith('_')]
discard_names = ["__init__"]
module_names = [name for name in module_names if name not in discard_names]

if not module_names:
print("[CLI data]: No CLI modules detected in /cli folder.")
return None
ht_groups = {}
for name in module_names:
with open(os.path.join(cli_path, name + ".py"), 'r') as cli_file:
text = cli_file.read()
m = re.search(r'^@click\.group\(.*\ndef\s(\w*)\s*\(\):', text,
flags=re.MULTILINE)
if m:
ht_groups[name] = m.group(1)

# Return library data
return module_names, lib_name, tool_name
return ht_groups


def write_cli_files(group_filenames, lib_name, tool_name, doc_folder):
def write_cli_files(ht_cli_data, lib_name, tool_name, doc_folder):
"""Writes a reST file with CLI directives for each click group provided.
Args:
group_filenames: A list containing the names of the CLI files that
rst files will be generated for.
ht_cli_data: A dictionary containing the names of the reSt CLI files
that will be generated and their corresponding CLI group name.
lib_name: The name of the library the click groups belong to. For
example ``honeybee_energy``, ``dragonfly`` or ``honeybee_radiance``
are possible library names.
Expand All @@ -387,25 +406,18 @@ def write_cli_files(group_filenames, lib_name, tool_name, doc_folder):
"""

# Creating missing CLI reST files
group_filenames = ht_cli_data.keys()
print("[CLI files]: Creating ({}) CLI rst files: {}...".format(
len(group_filenames), group_filenames))

# Retrieve valid group names where the file name and CLI group name don't
# match
group_names = list.copy(group_filenames)
if lib_name in ht_cli_file_group:
ht_file_group = ht_cli_file_group[lib_name]
group_names = [ht_file_group[
name] if name in ht_file_group else name for name in group_names]
len(group_filenames), list(group_filenames)))

# Write sphinx-click directive with options for each CLI group
for file, group in zip(group_filenames, group_names):
for file in group_filenames:
cli_content = ["{}\n".format(file),
"{}\n".format("=" * len(file)),
"\n",
".. click:: {}.cli.{}:{}\n".format(
lib_name, file, group),
" :prog: {} {}\n".format(tool_name, group),
lib_name, file, ht_cli_data[file]),
" :prog: {} {}\n".format(tool_name, ht_cli_data[file]),
" :show-nested:\n"
]

Expand Down Expand Up @@ -466,6 +478,7 @@ def update_cli_index(index_path, group_filenames):
# -----------------------------------------------------------------------------



def setup(app):
"""Run custom code with access to the Shinx application object
Expand Down

0 comments on commit fa35913

Please sign in to comment.