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