cli.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. """Command line interface for pydocstyle."""
  2. import logging
  3. import sys
  4. from .checker import check
  5. from .config import ConfigurationParser, IllegalConfiguration
  6. from .utils import log
  7. from .violations import Error
  8. __all__ = ('main',)
  9. class ReturnCode:
  10. no_violations_found = 0
  11. violations_found = 1
  12. invalid_options = 2
  13. def run_pydocstyle():
  14. log.setLevel(logging.DEBUG)
  15. conf = ConfigurationParser()
  16. setup_stream_handlers(conf.get_default_run_configuration())
  17. try:
  18. conf.parse()
  19. except IllegalConfiguration:
  20. return ReturnCode.invalid_options
  21. run_conf = conf.get_user_run_configuration()
  22. # Reset the logger according to the command line arguments
  23. setup_stream_handlers(run_conf)
  24. log.debug("starting in debug mode.")
  25. Error.explain = run_conf.explain
  26. Error.source = run_conf.source
  27. errors = []
  28. try:
  29. for (
  30. filename,
  31. checked_codes,
  32. ignore_decorators,
  33. property_decorators,
  34. ignore_self_only_init,
  35. ) in conf.get_files_to_check():
  36. errors.extend(
  37. check(
  38. (filename,),
  39. select=checked_codes,
  40. ignore_decorators=ignore_decorators,
  41. property_decorators=property_decorators,
  42. ignore_self_only_init=ignore_self_only_init,
  43. )
  44. )
  45. except IllegalConfiguration as error:
  46. # An illegal configuration file was found during file generation.
  47. log.error(error.args[0])
  48. return ReturnCode.invalid_options
  49. count = 0
  50. for error in errors: # type: ignore
  51. if hasattr(error, 'code'):
  52. sys.stdout.write('%s\n' % error)
  53. count += 1
  54. if count == 0:
  55. exit_code = ReturnCode.no_violations_found
  56. else:
  57. exit_code = ReturnCode.violations_found
  58. if run_conf.count:
  59. print(count)
  60. return exit_code
  61. def main():
  62. """Run pydocstyle as a script."""
  63. try:
  64. sys.exit(run_pydocstyle())
  65. except KeyboardInterrupt:
  66. pass
  67. def setup_stream_handlers(conf):
  68. """Set up logging stream handlers according to the options."""
  69. class StdoutFilter(logging.Filter):
  70. def filter(self, record):
  71. return record.levelno in (logging.DEBUG, logging.INFO)
  72. log.handlers = []
  73. stdout_handler = logging.StreamHandler(sys.stdout)
  74. stdout_handler.setLevel(logging.WARNING)
  75. stdout_handler.addFilter(StdoutFilter())
  76. if conf.debug:
  77. stdout_handler.setLevel(logging.DEBUG)
  78. elif conf.verbose:
  79. stdout_handler.setLevel(logging.INFO)
  80. else:
  81. stdout_handler.setLevel(logging.WARNING)
  82. log.addHandler(stdout_handler)
  83. stderr_handler = logging.StreamHandler(sys.stderr)
  84. msg_format = "%(levelname)s: %(message)s"
  85. stderr_handler.setFormatter(logging.Formatter(fmt=msg_format))
  86. stderr_handler.setLevel(logging.WARNING)
  87. log.addHandler(stderr_handler)