dump-command-help 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 = [
  33. title,
  34. '-' * len(title),
  35. '',
  36. data['help'] or '',
  37. ]
  38. body.append('')
  39. body.append('Options')
  40. body.append('```````')
  41. body.append('')
  42. for opt in data['options']:
  43. prefix = '- ``%s``: ' % opt['opt_string']
  44. for line in click.wrap_text(
  45. opt['help'], 74, prefix, ' ').splitlines() or ['']:
  46. body.append(line)
  47. body.append('- ``--help``: print this help page.')
  48. if data['subcommands']:
  49. body.append('')
  50. body.append('Subcommands')
  51. body.append('```````````')
  52. body.append('')
  53. body.append('.. toctree::')
  54. body.append(' :maxdepth: 1')
  55. body.append('')
  56. for subcmd in data['subcommands']:
  57. body.append(' %s <%s/index>' % (subcmd, subcmd))
  58. body.append('')
  59. with open(filename, 'w') as f:
  60. for line in body:
  61. f.write('%s\n' % line.encode('utf-8'))
  62. class NoHelp(Exception):
  63. pass
  64. def dump_command(out, cmd, path):
  65. if cmd.help is None:
  66. raise NoHelp
  67. data = {
  68. 'path': path,
  69. 'help': cmd.help.replace('\b', ''),
  70. 'options': [],
  71. 'arguments': [],
  72. 'subcommands': [],
  73. }
  74. for param in cmd.params:
  75. if isinstance(param, click.Option):
  76. help_text = param.help or ''
  77. if param.show_default:
  78. help_text += ' [default: %s]' % (
  79. ', '.join('%s' % d for d in param.default)
  80. if isinstance(param.default, (list, tuple))
  81. else (param.default,))
  82. data['options'].append({
  83. 'opt_string': get_opts(param),
  84. 'help': help_text,
  85. })
  86. else:
  87. data['arguments'].append({
  88. 'metavar': param.make_metavar(),
  89. })
  90. if isinstance(cmd, click.Group):
  91. for child_name, child_cmd in six.iteritems(cmd.commands):
  92. try:
  93. dump_command(out, child_cmd, path + [child_name])
  94. except NoHelp:
  95. pass
  96. else:
  97. data['subcommands'].append(child_name)
  98. write_page(out, data)
  99. @click.command()
  100. @click.option('--output-path', 'out', type=click.Path(),
  101. default='build/cli-help')
  102. def cli(out):
  103. dump_command(out, root_command, ['sentry'])
  104. if __name__ == '__main__':
  105. cli()