blob: f7a9090b4b1401c7f3ebbb0b6723e76e51f4f9e1 [file] [log] [blame]
#!/usr/bin/env fuchsia-vendored-python
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import os
import tempfile
import subprocess
import sys
import zipfile
# Wraps a clang-doc invocation for the hermetic build.
#
# Clang-doc generates a directory of output. Since the output file list isn't knowable in advance,
# we need to generate a single archive of the output. This script creates a new empty temp
# directory, runs clang-doc to generate the output, zips that directory to the output, and deletes
# the temporary directory.
#
# Positional arguments are passed directly to clang-doc. Prefix with a "--" to separate them from
# the parameters to this script. Do not include the --output parameter, this will be synthesized
# by this script to point to the temp directory.
#
# Example:
#
# clang_doc_invoke.py --clang-doc=prebuilt/x64/clang-doc --temp-dir-parent=/tmp
# --out.zip=output.zip -- --format=yaml --executor=all-TUs --filter=foo.cc
# 🠭 Args to clang-doc start here.
def main():
parser = argparse.ArgumentParser(
"Runs clang-doc in a temporary directory and zips the output.\n"
)
parser.add_argument(
"--clang-doc", help="Path to clang-doc binary.", required=True
)
parser.add_argument(
"--temp-dir-parent",
help="Parent directory of the unique temp dir to use.",
required=True,
)
parser.add_argument(
"--out-zip",
help="Name of the .zip file to create from the clang-doc output.",
required=True,
)
parser.add_argument(
"clang_doc_args",
help="Arguments to pass to clang-doc",
nargs="+",
metavar="clang-doc-args",
)
args = parser.parse_args()
with tempfile.TemporaryDirectory(dir=args.temp_dir_parent) as temp_dir:
completed = subprocess.run(
[args.clang_doc, "--output", temp_dir] + args.clang_doc_args,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
file_count = 0
with zipfile.ZipFile(args.out_zip, "w") as outfile:
for root, dirs, files in os.walk(temp_dir):
for file in files:
file_path = os.path.join(root, file)
outfile.write(
file_path, arcname=os.path.relpath(file_path, temp_dir)
)
file_count = file_count + 1
if file_count == 0:
# Clang-doc doesn't always return nonzero on failure so this is often the failure case.
print("clang-doc produced no files, failing.")
print(
" This is normally because the target is not in the 'default' build"
)
print(
" and the fix is to add the cpp_docgen target to your 'universe'."
)
print("\nclang-doc output:\n")
print(bytes.decode(completed.stdout))
return 1
return 0
if __name__ == "__main__":
sys.exit(main())