1
0

filemap.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # -*- coding: utf-8 -*-
  2. """
  3. tasks.filemap
  4. ~~~~~~~~~~~~~
  5. tests/filename_map.yml validity checks
  6. """
  7. import pathlib
  8. import re
  9. import yaml
  10. from invoke import task # pylint: disable=3rd-party-module-not-gated
  11. from tasks import utils
  12. CODE_DIR = pathlib.Path(__file__).resolve().parent.parent
  13. FILENAME_MAP_PATH = CODE_DIR / "tests" / "filename_map.yml"
  14. def _match_to_test_file(match):
  15. tests_path = CODE_DIR / "tests"
  16. parts = match.split(".")
  17. parts[-1] += ".py"
  18. return tests_path.joinpath(*parts).relative_to(CODE_DIR)
  19. def _check_matches(rule, matches):
  20. errors = 0
  21. for match in matches:
  22. filematch = _match_to_test_file(match)
  23. if not filematch.exists():
  24. utils.error(
  25. "The match '{}' for rule '{}' points to a non existing test module path: {}",
  26. match,
  27. rule,
  28. filematch,
  29. )
  30. errors += 1
  31. return errors
  32. @task
  33. def check(ctx):
  34. exitcode = 0
  35. excludes = ("tasks/", "templates/", ".nox/")
  36. full_filelist = [path.relative_to(CODE_DIR) for path in CODE_DIR.rglob("*.py")]
  37. filelist = [
  38. str(path) for path in full_filelist if not str(path).startswith(excludes)
  39. ]
  40. filename_map = yaml.safe_load(FILENAME_MAP_PATH.read_text())
  41. checked = set()
  42. for rule, matches in filename_map.items():
  43. if rule == "*":
  44. exitcode += _check_matches(rule, matches)
  45. elif "|" in rule:
  46. # This is regex
  47. for filepath in filelist:
  48. if re.match(rule, filepath):
  49. # Found at least one match, stop looking
  50. break
  51. else:
  52. utils.error(
  53. "Could not find a matching file in the salt repo for the rule '{}'",
  54. rule,
  55. )
  56. exitcode += 1
  57. continue
  58. exitcode += _check_matches(rule, matches)
  59. elif "*" in rule or "\\" in rule:
  60. # Glob matching
  61. process_matches = True
  62. for filerule in CODE_DIR.glob(rule):
  63. if not filerule.exists():
  64. utils.error(
  65. "The rule '{}' points to a non existing path: {}",
  66. rule,
  67. filerule,
  68. )
  69. exitcode += 1
  70. process_matches = False
  71. if process_matches:
  72. exitcode += _check_matches(rule, matches)
  73. else:
  74. # Direct file paths as rules
  75. filerule = pathlib.Path(rule)
  76. if not filerule.exists():
  77. utils.error(
  78. "The rule '{}' points to a non existing path: {}", rule, filerule
  79. )
  80. exitcode += 1
  81. continue
  82. exitcode += _check_matches(rule, matches)
  83. if exitcode:
  84. utils.error("Found {} errors", exitcode)
  85. utils.exit_invoke(exitcode)