check_rules_components_patterns.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/env python
  2. # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. # SPDX-License-Identifier: Apache-2.0
  4. """
  5. Check patterns-build_components including all components files except 'test*/'
  6. """
  7. import glob
  8. import os
  9. import subprocess
  10. from functools import lru_cache
  11. from typing import List, Set
  12. import yaml
  13. from idf_ci_utils import IDF_PATH
  14. RULES_FILE = os.path.join(IDF_PATH, '.gitlab', 'ci', 'rules.yml')
  15. @lru_cache(1)
  16. def get_component_git_files() -> Set[str]:
  17. output = subprocess.check_output(['git', 'ls-files', 'components/'], cwd=IDF_PATH).decode()
  18. component_git_files = set((_l.strip() for _l in output.strip().splitlines()))
  19. assert component_git_files, 'Can not list git files'
  20. return component_git_files
  21. def get_component_files_from_patterns(patterns: List[str]) -> Set[str]:
  22. files: Set[str] = set()
  23. for pattern in patterns:
  24. # NOTE: version 3.11: Added the include_hidden parameter.
  25. # NOTE: version 3.10: Added the root_dir and dir_fd parameters.
  26. try:
  27. _files = set(glob.iglob(pattern, root_dir=IDF_PATH, recursive=True, include_hidden=True)) # type: ignore
  28. except TypeError:
  29. _files = set(glob.iglob(pattern, recursive=True))
  30. files = files | _files
  31. # ignore files not in git repo
  32. files &= get_component_git_files()
  33. return files
  34. def get_components_test_files() -> Set[str]:
  35. patterns = [
  36. 'components/*/test/**/*',
  37. 'components/*/test_apps/**/*',
  38. 'components/*/host_test/**/*',
  39. # other test files
  40. 'components/efuse/test_efuse_host/**/*',
  41. 'components/esp_coex/test_md5/**/*',
  42. 'components/esp_gdbstub/test_gdbstub_host/**/*',
  43. 'components/esp_system/test_eh_frame_parser/**/*',
  44. 'components/esp_wifi/test_md5/**/*',
  45. 'components/fatfs/test_fatfsgen/**/*',
  46. 'components/heap/test_multi_heap_host/**/*',
  47. 'components/nvs_flash/test_nvs_host/**/*',
  48. 'components/partition_table/test_gen_esp32part_host/**/*',
  49. 'components/spiffs/test_spiffsgen/**/*',
  50. ]
  51. return get_component_files_from_patterns(patterns)
  52. def get_all_components_files() -> Set[str]:
  53. return get_component_files_from_patterns(['components/**/*'])
  54. def main() -> None:
  55. with open(RULES_FILE, 'r') as f:
  56. rules = yaml.load(f.read(), Loader=yaml.FullLoader)
  57. patterns_components = [p for p in rules['.patterns-build_components'] if p.startswith('components/')]
  58. submodules = [p for p in rules['.patterns-submodule'] if p.startswith('components/')]
  59. # resolve components in patterns_components
  60. patterns_components = [f'{p}/**/*' if p in submodules else p for p in patterns_components]
  61. # get different components files
  62. rules_files = get_component_files_from_patterns(patterns_components)
  63. components_test_files = get_components_test_files()
  64. components_build_files = get_all_components_files().difference(components_test_files)
  65. if check_test_files := components_test_files & rules_files:
  66. # rules should not include test files
  67. print(f'Found test files should not in .patterns-build_components: {check_test_files.pop()}')
  68. exit(1)
  69. if check_difference := components_build_files.difference(rules_files):
  70. # rules should include all build files
  71. print(f'Found components files should in .patterns-build_components but not: {check_difference.pop()}')
  72. exit(1)
  73. if check_difference := rules_files.difference(components_build_files):
  74. print(f'Found components files should not in .patterns-build_components: {check_difference.pop()}')
  75. exit(1)
  76. if __name__ == '__main__':
  77. main()