run_other_pylint.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/env python3
  2. # Copyright (c) 2019 The ungoogled-chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Run Pylint over any module"""
  6. import argparse
  7. import os
  8. import shutil
  9. import sys
  10. from pathlib import Path
  11. from pylint import lint
  12. class ChangeDir:
  13. """
  14. Changes directory to path in with statement
  15. """
  16. def __init__(self, path):
  17. self._path = path
  18. self._orig_path = os.getcwd()
  19. def __enter__(self):
  20. os.chdir(str(self._path))
  21. def __exit__(self, *_):
  22. os.chdir(self._orig_path)
  23. def run_pylint(module_path, pylint_options, ignore_prefixes=tuple()):
  24. """Runs Pylint. Returns a boolean indicating success"""
  25. pylint_stats = Path('/run/user/{}/pylint_stats'.format(os.getuid()))
  26. if not pylint_stats.parent.is_dir(): #pylint: disable=no-member
  27. pylint_stats = Path('/run/shm/pylint_stats')
  28. os.environ['PYLINTHOME'] = str(pylint_stats)
  29. input_paths = list()
  30. if not module_path.exists():
  31. print('ERROR: Cannot find', module_path)
  32. sys.exit(1)
  33. if module_path.is_dir():
  34. for path in module_path.rglob('*.py'):
  35. ignore_matched = False
  36. for prefix in ignore_prefixes:
  37. if path.parts[:len(prefix)] == prefix:
  38. ignore_matched = True
  39. break
  40. if ignore_matched:
  41. continue
  42. input_paths.append(str(path))
  43. else:
  44. input_paths.append(str(module_path))
  45. runner = lint.Run((*input_paths, *pylint_options), do_exit=False)
  46. if pylint_stats.is_dir():
  47. shutil.rmtree(str(pylint_stats))
  48. if runner.linter.msg_status != 0:
  49. print('WARNING: Non-zero exit status:', runner.linter.msg_status)
  50. return False
  51. return True
  52. def main():
  53. """CLI entrypoint"""
  54. parser = argparse.ArgumentParser(description='Run Pylint over arbitrary module')
  55. parser.add_argument('--hide-fixme', action='store_true', help='Hide "fixme" Pylint warnings.')
  56. parser.add_argument('--show-locally-disabled',
  57. action='store_true',
  58. help='Show "locally-disabled" Pylint warnings.')
  59. parser.add_argument('module_path', type=Path, help='Path to the module to check')
  60. args = parser.parse_args()
  61. if not args.module_path.exists():
  62. print('ERROR: Module path "{}" does not exist'.format(args.module_path))
  63. sys.exit(1)
  64. disables = [
  65. 'wrong-import-position',
  66. 'bad-continuation',
  67. ]
  68. if args.hide_fixme:
  69. disables.append('fixme')
  70. if not args.show_locally_disabled:
  71. disables.append('locally-disabled')
  72. pylint_options = [
  73. '--disable={}'.format(','.join(disables)),
  74. '--jobs=4',
  75. '--score=n',
  76. '--persistent=n',
  77. ]
  78. if not run_pylint(args.module_path, pylint_options):
  79. sys.exit(1)
  80. sys.exit(0)
  81. if __name__ == '__main__':
  82. main()