commands.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. # -*- coding: utf-8 -*-
  2. """Click commands."""
  3. import os
  4. from glob import glob
  5. from subprocess import call
  6. import click
  7. from flask import current_app
  8. from flask.cli import with_appcontext
  9. from werkzeug.exceptions import MethodNotAllowed, NotFound
  10. HERE = os.path.abspath(os.path.dirname(__file__))
  11. PROJECT_ROOT = os.path.join(HERE, os.pardir)
  12. TEST_PATH = os.path.join(PROJECT_ROOT, 'tests')
  13. @click.command()
  14. def test():
  15. """Run the tests."""
  16. import pytest
  17. rv = pytest.main([TEST_PATH, '--verbose'])
  18. exit(rv)
  19. @click.command()
  20. @click.option('-f', '--fix-imports', default=False, is_flag=True,
  21. help='Fix imports using isort, before linting')
  22. def lint(fix_imports):
  23. """Lint and check code style with flake8 and isort."""
  24. skip = ['requirements']
  25. root_files = glob('*.py')
  26. root_directories = [
  27. name for name in next(os.walk('.'))[1] if not name.startswith('.')]
  28. files_and_directories = [
  29. arg for arg in root_files + root_directories if arg not in skip]
  30. def execute_tool(description, *args):
  31. """Execute a checking tool with its arguments."""
  32. command_line = list(args) + files_and_directories
  33. click.echo('{}: {}'.format(description, ' '.join(command_line)))
  34. rv = call(command_line)
  35. if rv != 0:
  36. exit(rv)
  37. if fix_imports:
  38. execute_tool('Fixing import order', 'isort', '-rc')
  39. execute_tool('Checking code style', 'flake8')
  40. @click.command()
  41. def clean():
  42. """Remove *.pyc and *.pyo files recursively starting at current directory.
  43. Borrowed from Flask-Script, converted to use Click.
  44. """
  45. for dirpath, dirnames, filenames in os.walk('.'):
  46. for filename in filenames:
  47. if filename.endswith('.pyc') or filename.endswith('.pyo'):
  48. full_pathname = os.path.join(dirpath, filename)
  49. click.echo('Removing {}'.format(full_pathname))
  50. os.remove(full_pathname)
  51. @click.command()
  52. @click.option('--url', default=None,
  53. help='Url to test (ex. /static/image.png)')
  54. @click.option('--order', default='rule',
  55. help='Property on Rule to order by (default: rule)')
  56. @with_appcontext
  57. def urls(url, order):
  58. """Display all of the url matching routes for the project.
  59. Borrowed from Flask-Script, converted to use Click.
  60. """
  61. rows = []
  62. column_length = 0
  63. column_headers = ('Rule', 'Endpoint', 'Arguments')
  64. if url:
  65. try:
  66. rule, arguments = (
  67. current_app.url_map
  68. .bind('localhost')
  69. .match(url, return_rule=True))
  70. rows.append((rule.rule, rule.endpoint, arguments))
  71. column_length = 3
  72. except (NotFound, MethodNotAllowed) as e:
  73. rows.append(('<{}>'.format(e), None, None))
  74. column_length = 1
  75. else:
  76. rules = sorted(
  77. current_app.url_map.iter_rules(),
  78. key=lambda rule: getattr(rule, order))
  79. for rule in rules:
  80. rows.append((rule.rule, rule.endpoint, None))
  81. column_length = 2
  82. str_template = ''
  83. table_width = 0
  84. if column_length >= 1:
  85. max_rule_length = max(len(r[0]) for r in rows)
  86. max_rule_length = max_rule_length if max_rule_length > 4 else 4
  87. str_template += '{:' + str(max_rule_length) + '}'
  88. table_width += max_rule_length
  89. if column_length >= 2:
  90. max_endpoint_length = max(len(str(r[1])) for r in rows)
  91. # max_endpoint_length = max(rows, key=len)
  92. max_endpoint_length = (
  93. max_endpoint_length if max_endpoint_length > 8 else 8)
  94. str_template += ' {:' + str(max_endpoint_length) + '}'
  95. table_width += 2 + max_endpoint_length
  96. if column_length >= 3:
  97. max_arguments_length = max(len(str(r[2])) for r in rows)
  98. max_arguments_length = (
  99. max_arguments_length if max_arguments_length > 9 else 9)
  100. str_template += ' {:' + str(max_arguments_length) + '}'
  101. table_width += 2 + max_arguments_length
  102. click.echo(str_template.format(*column_headers[:column_length]))
  103. click.echo('-' * table_width)
  104. for row in rows:
  105. click.echo(str_template.format(*row[:column_length]))