| #!/usr/bin/env fuchsia-vendored-python |
| # Copyright 2020 The Fuchsia Authors |
| # |
| # Use of this source code is governed by a MIT-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/MIT |
| |
| import argparse |
| import json |
| import os |
| import sys |
| |
| # Some boot options have non-primitive types. |
| # This map is used to map the type of the boot-option |
| # to a string suitable for markdown documentation about the option. |
| SPECIAL_TYPES = { |
| "SmallString": r"\<string>", |
| "RedactedHex": r"\<hexadecimal>", |
| "TestOption": "test", |
| "uart::all::Driver": r"\[none | legacy | qemu | \<type>,\<base>,\<irq>\]", |
| } |
| |
| |
| def generate_doc(option): |
| # Types that are lists are enumerations of valid values for this option. |
| # and are printed as [ <value1> | <value2> |...]. |
| if isinstance(option["type"], list): |
| option["type"] = "\[%s\]" % " | ".join(option["type"]) |
| else: |
| # Non-list types could be a special type, or default to the |
| # type passed in. This allows SPECIAL_TYPES to handle non-primitive |
| # types and primitive types fall back to themselves as the default. |
| option["type"] = SPECIAL_TYPES.get( |
| option["type"], r"\<%s>" % option["type"] |
| ) |
| if option["default"] != "": |
| if isinstance(option["default"], bool): |
| option["default"] = "true" if option["default"] else "false" |
| elif isinstance(option["default"], int): |
| option["default"] = "%#x" % option["default"] |
| option["default"] = "**Default:** `%s`\n" % option["default"] |
| # Return the multiline string with the values interpolated. |
| return """ |
| ### {name}={type} |
| |
| {default} |
| {documentation} |
| """.format( |
| **option |
| ) |
| |
| |
| def generate_docs(title, options): |
| return """ |
| ## Options {title} |
| {options} |
| """.format( |
| title=title, options="".join(generate_doc(option) for option in options) |
| ) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser(description="Produce boot-options.md") |
| parser.add_argument( |
| "output", help="Output file", metavar="//docs/gen/boot-options.md" |
| ) |
| parser.add_argument( |
| "json", help="JSON input file", metavar="boot-options.json" |
| ) |
| parser.add_argument( |
| "preamble", help="Markdown preamble file", metavar="preamble.md" |
| ) |
| parser.add_argument( |
| "postamble", help="Markdown postamble file", metavar="postamble.md" |
| ) |
| args = parser.parse_args() |
| |
| with open(args.json) as f: |
| options = json.load(f) |
| |
| with open(args.preamble) as f: |
| preamble = f.read() |
| |
| with open(args.postamble) as f: |
| postamble = f.read() |
| |
| text = preamble |
| |
| text += generate_docs("common to all machines", options["common"]) |
| del options["common"] |
| for arch, arch_options in sorted(options.items()): |
| text += generate_docs( |
| "available only on %s machines" % arch, arch_options |
| ) |
| |
| text += postamble |
| |
| if os.path.exists(args.output): |
| with open(args.output) as f: |
| if f.read() == text: |
| return 0 |
| |
| with open(args.output, "w") as f: |
| f.write(text) |
| |
| return 0 |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main()) |