dump-command-help 3.2 KB

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