2021-01-21 00:37:01 +00:00
|
|
|
#!/usr/bin/python3
|
2019-05-27 19:06:28 +09:00
|
|
|
# coding: utf-8
|
|
|
|
|
2019-08-26 02:58:42 +01:00
|
|
|
# Builds Voxel Tools API docs
|
2019-05-27 19:06:28 +09:00
|
|
|
#
|
|
|
|
# Requires Python 3.4+
|
|
|
|
# Run with --help for usage
|
|
|
|
#
|
|
|
|
# Configure these variables for your system or specify on the command line
|
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
import sys
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2019-08-26 02:58:42 +01:00
|
|
|
if sys.version_info < (3, 4):
|
2019-05-27 19:06:28 +09:00
|
|
|
print("Please upgrade python to version 3.4 or higher.")
|
2019-08-26 02:58:42 +01:00
|
|
|
print("Your version: %s\n" % sys.version_info)
|
2019-05-27 19:06:28 +09:00
|
|
|
sys.exit(1)
|
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
import xml_to_markdown
|
|
|
|
import subprocess
|
|
|
|
import getopt
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
from pathlib import Path
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2021-01-24 14:32:38 +00:00
|
|
|
SOURCES = "source"
|
2021-01-21 22:40:15 +00:00
|
|
|
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
def update_classes_xml(custom_godot_path, godot_repo_root, verbose=False):
|
|
|
|
godot_executable = custom_godot_path
|
|
|
|
if godot_executable is None or godot_executable == "":
|
|
|
|
bindir = godot_repo_root / 'bin'
|
|
|
|
godot_executable = find_godot(bindir)
|
|
|
|
if godot_executable is None:
|
|
|
|
print("Godot executable not found")
|
|
|
|
return
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2019-08-26 02:58:42 +01:00
|
|
|
if verbose:
|
2021-01-21 00:37:01 +00:00
|
|
|
print("Found Godot at: %s" % godot_executable)
|
|
|
|
|
2019-08-26 02:58:42 +01:00
|
|
|
# Dump XML files from Godot
|
2021-01-21 00:37:01 +00:00
|
|
|
args = [str(godot_executable), ' --doctool ', str(godot_repo_root)]
|
2019-08-26 02:58:42 +01:00
|
|
|
if verbose:
|
|
|
|
print("Running: ", args)
|
|
|
|
result = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
|
|
universal_newlines=True)
|
|
|
|
if verbose:
|
|
|
|
print(result.stdout)
|
|
|
|
print("Disregard Godot's errors about files unless they are about Voxel*.")
|
2019-05-27 19:06:28 +09:00
|
|
|
|
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
def find_godot(bindir):
|
2019-05-27 19:06:28 +09:00
|
|
|
# Match a filename like these
|
2021-01-21 00:37:01 +00:00
|
|
|
# godot.windows.tools.64.exe
|
|
|
|
# godot.x11.tools.64
|
2019-05-27 19:06:28 +09:00
|
|
|
#regex = r"godot\.(windows|x11|osx)(\.opt)?(\.tools)?\.(32|64)(\.exe)?"
|
2021-01-21 00:37:01 +00:00
|
|
|
prefix = "godot"
|
|
|
|
suffix = ""
|
2019-05-27 19:06:28 +09:00
|
|
|
if sys.platform == "win32" or sys.platform == "cygwin":
|
2021-01-21 00:37:01 +00:00
|
|
|
prefix += ".windows"
|
|
|
|
suffix = ".exe"
|
2019-05-27 19:06:28 +09:00
|
|
|
else:
|
2021-01-21 00:37:01 +00:00
|
|
|
# TODO Mac OS?
|
|
|
|
prefix += ".x11"
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
bits = ".64"
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
# Names to try by priority
|
|
|
|
names = [
|
|
|
|
prefix + ".tools" + bits + suffix,
|
|
|
|
prefix + ".opt.tools" + bits + suffix
|
|
|
|
]
|
|
|
|
|
|
|
|
for name in names:
|
|
|
|
path = bindir / name
|
|
|
|
if os.path.isfile(path):
|
|
|
|
return path
|
|
|
|
|
|
|
|
print("Error: Godot binary not specified and none suitable found in %s" % bindir)
|
2019-08-26 02:58:42 +01:00
|
|
|
return None
|
2019-05-27 19:06:28 +09:00
|
|
|
|
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
def update_mkdocs_file(mkdocs_config_fpath, md_classes_dir):
|
|
|
|
absolute_paths = md_classes_dir.glob("*.md")
|
|
|
|
class_files = []
|
2021-01-21 22:40:15 +00:00
|
|
|
docs_folder = mkdocs_config_fpath.parents[0] / SOURCES
|
2021-01-21 00:37:01 +00:00
|
|
|
for absolute_path in absolute_paths:
|
|
|
|
class_files.append(str(absolute_path.relative_to(docs_folder)).replace('\\', '/'))
|
|
|
|
class_files = sorted(class_files)
|
|
|
|
|
|
|
|
with open(mkdocs_config_fpath, 'r', encoding='utf-8') as f:
|
|
|
|
lines = f.readlines()
|
|
|
|
|
|
|
|
processed_lines = []
|
|
|
|
in_generated_section = False
|
|
|
|
|
|
|
|
for line in lines:
|
|
|
|
if in_generated_section:
|
|
|
|
if "</generated_class_list>" in line:
|
|
|
|
in_generated_section = False
|
|
|
|
else:
|
|
|
|
continue
|
|
|
|
if "<generated_class_list>" in line:
|
|
|
|
in_generated_section = True
|
2021-01-21 22:41:57 +00:00
|
|
|
indent = line[:line.find('#')]
|
|
|
|
processed_lines.append(line)
|
|
|
|
for class_file in class_files:
|
|
|
|
processed_lines.append(indent + "- " + class_file + "\n")
|
2021-02-16 20:34:33 +00:00
|
|
|
else:
|
|
|
|
processed_lines.append(line)
|
2021-01-21 00:37:01 +00:00
|
|
|
|
|
|
|
yml = "".join(processed_lines)
|
|
|
|
with open(mkdocs_config_fpath, 'w', encoding='utf-8') as f:
|
|
|
|
f.write(yml)
|
|
|
|
|
|
|
|
|
|
|
|
def print_usage():
|
|
|
|
print("\nUsage: ", sys.argv[0],
|
|
|
|
"[-d] [-a] [-m] [-h] [-v] [-g path_to_godot]")
|
|
|
|
print()
|
|
|
|
print("\t-d -> Execute Godot doctool to update XML class data")
|
|
|
|
print("\t-a -> Update Markdown API files from XML class data")
|
|
|
|
print("\t-m -> Update mkdocs config file with generated content such as API files")
|
|
|
|
print("\t-h, --help -> Prints help")
|
|
|
|
print("\t-v -> Verbose. Print more details when running.")
|
|
|
|
print("\t-g -> Specify custom path to Godot. Otherwise will use compiled executable under the repo's bin directory.")
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
2019-05-27 19:06:28 +09:00
|
|
|
###########################
|
2019-08-26 02:58:42 +01:00
|
|
|
# Main()
|
2019-05-27 19:06:28 +09:00
|
|
|
|
|
|
|
def main():
|
2019-08-26 02:58:42 +01:00
|
|
|
# Default paths are determined from the location of this script
|
|
|
|
my_path = Path(os.path.realpath(__file__))
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2019-08-26 02:58:42 +01:00
|
|
|
# Default parameters
|
2019-05-27 19:06:28 +09:00
|
|
|
verbose = False
|
2021-01-21 00:37:01 +00:00
|
|
|
must_run_doctool = False
|
|
|
|
must_update_md_from_xml = False
|
|
|
|
must_update_mkdocs_config = False
|
2019-08-26 02:58:42 +01:00
|
|
|
godot_executable = ""
|
2021-01-21 00:37:01 +00:00
|
|
|
|
|
|
|
godot_repo_root = my_path.parents[4]
|
2021-01-21 22:40:15 +00:00
|
|
|
md_path = my_path.parents[1] / SOURCES / 'api'
|
2019-08-26 02:58:42 +01:00
|
|
|
xml_path = my_path.parents[1] / 'classes'
|
2021-01-21 00:37:01 +00:00
|
|
|
mkdocs_config_path = my_path.parents[1] / 'mkdocs.yml'
|
2019-08-26 02:58:42 +01:00
|
|
|
|
|
|
|
# Parse command line arguments
|
|
|
|
try:
|
2021-01-21 00:37:01 +00:00
|
|
|
opts, args = getopt.getopt(sys.argv[1:], "damhvg:", "help")
|
2019-08-26 02:58:42 +01:00
|
|
|
except getopt.error as msg:
|
|
|
|
print("Error: ", msg)
|
2019-05-27 19:06:28 +09:00
|
|
|
print_usage()
|
2021-01-21 00:37:01 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
did_something = False
|
2019-05-27 19:06:28 +09:00
|
|
|
|
|
|
|
for opt, arg in opts:
|
2021-01-21 00:37:01 +00:00
|
|
|
if opt == '-d':
|
|
|
|
must_run_doctool = True
|
|
|
|
if opt == '-a':
|
|
|
|
must_update_md_from_xml = True
|
|
|
|
if opt == '-m':
|
|
|
|
must_update_mkdocs_config = True
|
2019-08-26 02:58:42 +01:00
|
|
|
if opt in ('-h', '--help'):
|
2019-05-27 19:06:28 +09:00
|
|
|
print_usage()
|
2021-01-21 00:37:01 +00:00
|
|
|
did_something = True
|
2019-08-26 02:58:42 +01:00
|
|
|
if opt == '-v':
|
2019-05-27 19:06:28 +09:00
|
|
|
verbose = True
|
2021-01-21 00:37:01 +00:00
|
|
|
if opt == '-g':
|
|
|
|
godot_executable = arg
|
2019-05-27 19:06:28 +09:00
|
|
|
|
2021-01-21 00:37:01 +00:00
|
|
|
if must_run_doctool:
|
2019-08-26 13:50:18 +01:00
|
|
|
update_classes_xml(godot_executable, godot_repo_root, verbose)
|
2021-01-21 00:37:01 +00:00
|
|
|
did_something = True
|
|
|
|
|
|
|
|
if must_update_mkdocs_config:
|
|
|
|
update_mkdocs_file(mkdocs_config_path, md_path)
|
|
|
|
did_something = True
|
|
|
|
|
|
|
|
if must_update_md_from_xml:
|
|
|
|
xml_to_markdown.process_xml_folder(xml_path, md_path, verbose)
|
|
|
|
did_something = True
|
|
|
|
|
|
|
|
if not did_something:
|
|
|
|
print("No operation specified.")
|
|
|
|
print_usage()
|
2019-05-27 19:06:28 +09:00
|
|
|
|
|
|
|
|
2019-08-26 02:58:42 +01:00
|
|
|
# If called from command line
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|