notes.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. # -*- coding: utf-8 -*-
  2. from __future__ import with_statement
  3. import os
  4. import re
  5. from django.conf import settings
  6. from django.core.management.base import BaseCommand
  7. from django_extensions.compat import get_template_setting
  8. from django_extensions.management.utils import signalcommand
  9. ANNOTATION_RE = re.compile(r"\{?#[\s]*?(TODO|FIXME|BUG|HACK|WARNING|NOTE|XXX)[\s:]?(.+)")
  10. ANNOTATION_END_RE = re.compile(r"(.*)#\}(.*)")
  11. class Command(BaseCommand):
  12. help = 'Show all annotations like TODO, FIXME, BUG, HACK, WARNING, NOTE or XXX in your py and HTML files.'
  13. label = 'annotation tag (TODO, FIXME, BUG, HACK, WARNING, NOTE, XXX)'
  14. def add_arguments(self, parser):
  15. super().add_arguments(parser)
  16. parser.add_argument(
  17. '--tag',
  18. dest='tag',
  19. help='Search for specific tags only',
  20. action='append'
  21. )
  22. @signalcommand
  23. def handle(self, *args, **options):
  24. # don't add django internal code
  25. apps = [app.replace(".", "/") for app in filter(lambda app: not app.startswith('django.contrib'), settings.INSTALLED_APPS)]
  26. template_dirs = get_template_setting('DIRS', [])
  27. base_dir = getattr(settings, 'BASE_DIR')
  28. if template_dirs:
  29. apps += template_dirs
  30. for app_dir in apps:
  31. if base_dir:
  32. app_dir = os.path.join(base_dir, app_dir)
  33. for top, dirs, files in os.walk(app_dir):
  34. for fn in files:
  35. if os.path.splitext(fn)[1] in ('.py', '.html'):
  36. fpath = os.path.join(top, fn)
  37. annotation_lines = []
  38. with open(fpath, 'r') as fd:
  39. i = 0
  40. for line in fd.readlines():
  41. i += 1
  42. if ANNOTATION_RE.search(line):
  43. tag, msg = ANNOTATION_RE.findall(line)[0]
  44. if options['tag']:
  45. if tag not in map(str.upper, map(str, options['tag'])):
  46. break
  47. if ANNOTATION_END_RE.search(msg.strip()):
  48. msg = ANNOTATION_END_RE.findall(msg.strip())[0][0]
  49. annotation_lines.append("[%3s] %-5s %s" % (i, tag, msg.strip()))
  50. if annotation_lines:
  51. self.stdout.write("%s:" % fpath)
  52. for annotation in annotation_lines:
  53. self.stdout.write(" * %s" % annotation)
  54. self.stdout.write("")