manpage: use bpy.app.help_text() for manual text extraction
Call Blender directly to generate the man-page, instead of relying on the systems Python which called Blender twice and processed it's output.
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
This script generates the blender.1 man page, embedding the help text
|
This script generates the blender.1 man page, embedding the help text
|
||||||
from the Blender executable itself. Invoke it as follows:
|
from the Blender executable itself. Invoke it as follows:
|
||||||
|
|
||||||
blender.1.py --blender <path-to-blender> --output <output-filename>
|
./blender.bin -b --python doc/manpage/blender.1.py -- --output <output-filename>
|
||||||
|
|
||||||
where <path-to-blender> is the path to the Blender executable,
|
where <path-to-blender> is the path to the Blender executable,
|
||||||
and <output-filename> is where to write the generated man page.
|
and <output-filename> is where to write the generated man page.
|
||||||
@@ -13,8 +13,8 @@ and <output-filename> is where to write the generated man page.
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
from typing import (
|
from typing import (
|
||||||
Dict,
|
Dict,
|
||||||
@@ -28,61 +28,28 @@ def man_format(data: str) -> str:
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def blender_extract_info(blender_bin: str) -> Dict[str, str]:
|
def blender_extract_info() -> Dict[str, str]:
|
||||||
|
# Only use of `bpy` in this file.
|
||||||
|
import bpy # type: ignore
|
||||||
|
blender_help_text = bpy.app.help_text()
|
||||||
|
blender_version_text = bpy.app.version_string
|
||||||
|
blender_build_date_text = bpy.app.build_date
|
||||||
|
|
||||||
blender_env = {
|
if blender_build_date_text == b'Unknown':
|
||||||
"ASAN_OPTIONS": (
|
|
||||||
os.environ.get("ASAN_OPTIONS", "") +
|
|
||||||
":exitcode=0:check_initialization_order=0:strict_init_order=0"
|
|
||||||
).lstrip(":"),
|
|
||||||
}
|
|
||||||
|
|
||||||
blender_help = subprocess.run(
|
|
||||||
[blender_bin, "--help"],
|
|
||||||
env=blender_env,
|
|
||||||
check=True,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
).stdout.decode(encoding="utf-8")
|
|
||||||
|
|
||||||
blender_version_output = subprocess.run(
|
|
||||||
[blender_bin, "--version"],
|
|
||||||
env=blender_env,
|
|
||||||
check=True,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
).stdout.decode(encoding="utf-8")
|
|
||||||
|
|
||||||
# Extract information from the version string.
|
|
||||||
# Note that some internal modules may print errors (e.g. color management),
|
|
||||||
# check for each lines prefix to ensure these aren't included.
|
|
||||||
blender_version = ""
|
|
||||||
blender_date = ""
|
|
||||||
for l in blender_version_output.split("\n"):
|
|
||||||
if l.startswith("Blender "):
|
|
||||||
# Remove 'Blender' prefix.
|
|
||||||
blender_version = l.split(" ", 1)[1].strip()
|
|
||||||
elif l.lstrip().startswith("build date:"):
|
|
||||||
# Remove 'build date:' prefix.
|
|
||||||
blender_date = l.split(":", 1)[1].strip()
|
|
||||||
if blender_version and blender_date:
|
|
||||||
break
|
|
||||||
|
|
||||||
if not blender_date:
|
|
||||||
# Happens when built without WITH_BUILD_INFO e.g.
|
# Happens when built without WITH_BUILD_INFO e.g.
|
||||||
date_string = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
|
blender_date = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
|
||||||
else:
|
else:
|
||||||
date_string = time.strftime("%B %d, %Y", time.strptime(blender_date, "%Y-%m-%d"))
|
blender_date = time.strftime("%B %d, %Y", time.strptime(blender_build_date_text, "%Y-%m-%d"))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"help": blender_help,
|
"help": blender_help_text,
|
||||||
"version": blender_version,
|
"version": blender_version_text,
|
||||||
"date": date_string,
|
"date": blender_date,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def man_page_from_blender_help(fh: TextIO, blender_bin: str, verbose: bool) -> None:
|
def man_page_from_blender_help(fh: TextIO, verbose: bool) -> None:
|
||||||
if verbose:
|
blender_info = blender_extract_info()
|
||||||
print("Extracting help text:", blender_bin)
|
|
||||||
blender_info = blender_extract_info(blender_bin)
|
|
||||||
|
|
||||||
# Header Content.
|
# Header Content.
|
||||||
fh.write(
|
fh.write(
|
||||||
@@ -175,11 +142,6 @@ def create_argparse() -> argparse.ArgumentParser:
|
|||||||
required=True,
|
required=True,
|
||||||
help="The man page to write to."
|
help="The man page to write to."
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"--blender",
|
|
||||||
required=True,
|
|
||||||
help="Path to the blender binary."
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--verbose",
|
"--verbose",
|
||||||
default=False,
|
default=False,
|
||||||
@@ -192,15 +154,15 @@ def create_argparse() -> argparse.ArgumentParser:
|
|||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
argv = sys.argv[sys.argv.index("--") + 1:]
|
||||||
parser = create_argparse()
|
parser = create_argparse()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
blender_bin = args.blender
|
|
||||||
output_filename = args.output
|
output_filename = args.output
|
||||||
verbose = args.verbose
|
verbose = args.verbose
|
||||||
|
|
||||||
with open(output_filename, "w", encoding="utf-8") as fh:
|
with open(output_filename, "w", encoding="utf-8") as fh:
|
||||||
man_page_from_blender_help(fh, blender_bin, verbose)
|
man_page_from_blender_help(fh, verbose)
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Written:", output_filename)
|
print("Written:", output_filename)
|
||||||
|
|
||||||
|
|||||||
@@ -1715,7 +1715,20 @@ if(\n\
|
|||||||
($\{BLENDER_BIN\} IS_NEWER_THAN $\{MANPAGE_OUT\}) OR\n\
|
($\{BLENDER_BIN\} IS_NEWER_THAN $\{MANPAGE_OUT\}) OR\n\
|
||||||
($\{MANPAGE_GEN\} IS_NEWER_THAN $\{MANPAGE_OUT\})\n\
|
($\{MANPAGE_GEN\} IS_NEWER_THAN $\{MANPAGE_OUT\})\n\
|
||||||
)\n\
|
)\n\
|
||||||
execute_process(COMMAND $\{MANPAGE_GEN\} --blender $\{BLENDER_BIN\} --output $\{MANPAGE_OUT\})\n\
|
set(\n\
|
||||||
|
ENV{ASAN_OPTIONS}\n\
|
||||||
|
\"$ENV{ASAN_OPTIONS}:exitcode=0:check_initialization_order=0:strict_init_order=0\"\n\
|
||||||
|
)\n\
|
||||||
|
execute_process(\n\
|
||||||
|
OUTPUT_QUIET\n\
|
||||||
|
ERROR_QUIET\n\
|
||||||
|
COMMAND $\{BLENDER_BIN\}\n\
|
||||||
|
--background\n\
|
||||||
|
--factory-startup\n\
|
||||||
|
--python $\{MANPAGE_GEN\}\n\
|
||||||
|
--\n\
|
||||||
|
--output $\{MANPAGE_OUT\}\n\
|
||||||
|
)\n\
|
||||||
endif()\n\
|
endif()\n\
|
||||||
"
|
"
|
||||||
DEPENDS blender
|
DEPENDS blender
|
||||||
|
|||||||
Reference in New Issue
Block a user