check_rules_components_patterns.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. from typing import List, Set
  10. import yaml
  11. from idf_ci_utils import IDF_PATH
  12. RULES_FILE = os.path.join(IDF_PATH, '.gitlab', 'ci', 'rules.yml')
  13. def get_component_files_from_patterns(patterns: List[str]) -> Set[str]:
  14. files: Set[str] = set()
  15. for pattern in patterns:
  16. # NOTE: version 3.10: Added the root_dir and dir_fd parameters.
  17. files = files | set(glob.iglob(pattern, recursive=True))
  18. return files
  19. def get_components_submodule_files(submodules: List[str]) -> Set[str]:
  20. patterns = [f'{submodule}/**/*' for submodule in submodules]
  21. return get_component_files_from_patterns(patterns)
  22. def get_components_test_files() -> Set[str]:
  23. patterns = [
  24. 'components/*/test/**/*',
  25. 'components/*/test_apps/**/*',
  26. 'components/*/host_test/**/*',
  27. # other test files
  28. 'components/efuse/test_efuse_host/**/*',
  29. 'components/esp_coex/test_md5/**/*',
  30. 'components/esp_gdbstub/test_gdbstub_host/**/*',
  31. 'components/esp_system/test_eh_frame_parser/**/*',
  32. 'components/esp_wifi/test_md5/**/*',
  33. 'components/fatfs/test_fatfsgen/**/*',
  34. 'components/heap/test_multi_heap_host/**/*',
  35. 'components/nvs_flash/test_nvs_host/**/*',
  36. 'components/partition_table/test_gen_esp32part_host/**/*',
  37. 'components/spiffs/test_spiffsgen/**/*',
  38. ]
  39. return get_component_files_from_patterns(patterns)
  40. def get_all_components_files() -> Set[str]:
  41. return get_component_files_from_patterns(['components/**/*'])
  42. def main() -> None:
  43. with open(RULES_FILE, 'r') as f:
  44. rules = yaml.load(f.read(), Loader=yaml.FullLoader)
  45. patterns_components = [p for p in rules['.patterns-build_components'] if p.startswith('components/')]
  46. submodules = [p for p in rules['.patterns-submodule'] if p.startswith('components/')]
  47. # resolve components in patterns_components
  48. patterns_components = [f'{p}/**/*' if p in submodules else p for p in patterns_components]
  49. # get different components files
  50. submodule_files = get_components_submodule_files(submodules)
  51. rules_files = get_component_files_from_patterns(patterns_components)
  52. # first check submodules in rules_files
  53. if check_submodule_res := submodule_files.difference(rules_files):
  54. # only show one file in the failure message
  55. print(f'Found submodule should in .patterns-build_components but not: {check_submodule_res.pop()}')
  56. exit(1)
  57. rules_files = rules_files.difference(submodule_files)
  58. components_test_files = get_components_test_files().difference(submodule_files)
  59. components_build_files = get_all_components_files().difference(submodule_files).difference(components_test_files)
  60. if check_test_files := components_test_files & rules_files:
  61. # rules should not include test files
  62. print(f'Found test files should not in .patterns-build_components: {check_test_files.pop()}')
  63. exit(1)
  64. if check_difference := components_build_files.difference(rules_files):
  65. # rules should include all build files
  66. print(f'Found components files should in .patterns-build_components but not: {check_difference.pop()}')
  67. exit(1)
  68. if check_difference := rules_files.difference(components_build_files):
  69. print(f'Found components files should not in .patterns-build_components: {check_difference.pop()}')
  70. exit(1)
  71. if __name__ == '__main__':
  72. main()