| #!/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()) |