dump-command-help 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/env python
  2. import os
  3. import click
  4. from click.formatting import join_options
  5. from sentry.runner import cli as root_command
  6. def get_opts(param):
  7. any_prefix_is_slash = []
  8. def _write(opts):
  9. rv, any_slashes = join_options(opts)
  10. if any_slashes:
  11. any_prefix_is_slash[:] = [True]
  12. if not param.is_flag and not param.count:
  13. rv += " " + param.make_metavar()
  14. return rv
  15. rv = [_write(param.opts)]
  16. if param.secondary_opts:
  17. rv.append(_write(param.secondary_opts))
  18. return (any_prefix_is_slash and "; " or " / ").join(rv)
  19. def write_page(out, data):
  20. path = data["path"]
  21. filename = os.path.join(out, *path[1:]) + "/index.rst"
  22. if len(path) == 1:
  23. filename += ".inc"
  24. dirname = os.path.dirname(filename)
  25. os.makedirs(dirname, exist_ok=True)
  26. args = [x["metavar"] for x in data["arguments"]]
  27. title = "`%s`" % " ".join(data["path"] + args)
  28. body = [title, "-" * len(title), "", data["help"] or ""]
  29. body.append("")
  30. body.append("Options")
  31. body.append("```````")
  32. body.append("")
  33. for opt in data["options"]:
  34. prefix = "- ``%s``: " % opt["opt_string"]
  35. for line in click.wrap_text(opt["help"], 74, prefix, " ").splitlines() or [""]:
  36. body.append(line)
  37. body.append("- ``--help``: print this help page.")
  38. if data["subcommands"]:
  39. body.append("")
  40. body.append("Subcommands")
  41. body.append("```````````")
  42. body.append("")
  43. body.append(".. toctree::")
  44. body.append(" :maxdepth: 1")
  45. body.append("")
  46. for subcmd in data["subcommands"]:
  47. body.append(f" {subcmd} <{subcmd}/index>")
  48. body.append("")
  49. with open(filename, "w") as f:
  50. for line in body:
  51. f.write("%s\n" % line.encode("utf-8"))
  52. class NoHelp(Exception):
  53. pass
  54. def dump_command(out, cmd, path):
  55. if cmd.help is None:
  56. raise NoHelp
  57. data = {
  58. "path": path,
  59. "help": cmd.help.replace("\b", ""),
  60. "options": [],
  61. "arguments": [],
  62. "subcommands": [],
  63. }
  64. for param in cmd.params:
  65. if isinstance(param, click.Option):
  66. help_text = param.help or ""
  67. if param.show_default:
  68. help_text += " [default: %s]" % (
  69. ", ".join("%s" % d for d in param.default)
  70. if isinstance(param.default, (list, tuple))
  71. else (param.default,)
  72. )
  73. data["options"].append({"opt_string": get_opts(param), "help": help_text})
  74. else:
  75. data["arguments"].append({"metavar": param.make_metavar()})
  76. if isinstance(cmd, click.Group):
  77. for child_name, child_cmd in cmd.commands.items():
  78. try:
  79. dump_command(out, child_cmd, path + [child_name])
  80. except NoHelp:
  81. pass
  82. else:
  83. data["subcommands"].append(child_name)
  84. write_page(out, data)
  85. @click.command()
  86. @click.option("--output-path", "out", type=click.Path(), default="build/cli-help")
  87. def cli(out):
  88. dump_command(out, root_command, ["sentry"])
  89. if __name__ == "__main__":
  90. cli()