check_deprecated_kconfigs.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env python
  2. #
  3. # Copyright 2019 Espressif Systems (Shanghai) PTE LTD
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. from __future__ import print_function, unicode_literals
  17. import argparse
  18. import os
  19. import sys
  20. from io import open
  21. from check_kconfigs import valid_directory
  22. from idf_ci_utils import get_submodule_dirs
  23. # FILES_TO_CHECK used as "startswith" pattern to match sdkconfig.defaults variants
  24. FILES_TO_CHECK = ('sdkconfig.ci', 'sdkconfig.defaults')
  25. # ignored directories (makes sense only when run on IDF_PATH)
  26. # Note: IGNORE_DIRS is a tuple in order to be able to use it directly with the startswith() built-in function which
  27. # accepts tuples but no lists.
  28. IGNORE_DIRS = (
  29. )
  30. def _parse_path(path, sep=None):
  31. ret = set()
  32. with open(path, 'r', encoding='utf-8') as f:
  33. for line in f:
  34. line = line.strip()
  35. if not line.startswith('#') and len(line) > 0:
  36. ret.add(line.split(sep)[0])
  37. return ret
  38. def _valid_directory(path):
  39. if not os.path.isdir(path):
  40. raise argparse.ArgumentTypeError('{} is not a valid directory!'.format(path))
  41. return path
  42. def main():
  43. parser = argparse.ArgumentParser(description='Kconfig options checker')
  44. parser.add_argument('files', nargs='*',
  45. help='Kconfig files')
  46. parser.add_argument('--includes', '-d', nargs='*',
  47. help='Extra paths for recursively searching Kconfig files. (for example $IDF_PATH)',
  48. type=valid_directory)
  49. parser.add_argument('--exclude-submodules', action='store_true',
  50. help='Exclude submodules')
  51. args = parser.parse_args()
  52. success_counter = 0
  53. failure_counter = 0
  54. ignore_counter = 0
  55. deprecated_options = set()
  56. ignore_dirs = IGNORE_DIRS
  57. if args.exclude_submodules:
  58. for submodule in get_submodule_dirs(full_path=True):
  59. ignore_dirs = ignore_dirs + tuple(submodule)
  60. files = [os.path.abspath(file_path) for file_path in args.files]
  61. if args.includes:
  62. for directory in args.includes:
  63. for root, dirnames, filenames in os.walk(directory):
  64. for filename in filenames:
  65. full_path = os.path.join(root, filename)
  66. if filename.startswith(FILES_TO_CHECK):
  67. files.append(full_path)
  68. elif filename == 'sdkconfig.rename':
  69. deprecated_options |= _parse_path(full_path)
  70. for full_path in files:
  71. if full_path.startswith(ignore_dirs):
  72. print('{}: Ignored'.format(full_path))
  73. ignore_counter += 1
  74. continue
  75. used_options = _parse_path(full_path, '=')
  76. used_deprecated_options = deprecated_options & used_options
  77. if len(used_deprecated_options) > 0:
  78. print('{}: The following options are deprecated: {}'
  79. .format(full_path, ', '.join(used_deprecated_options)))
  80. failure_counter += 1
  81. else:
  82. print('{}: OK'.format(full_path))
  83. success_counter += 1
  84. if ignore_counter > 0:
  85. print('{} files have been ignored.'.format(ignore_counter))
  86. if success_counter > 0:
  87. print('{} files have been successfully checked.'.format(success_counter))
  88. if failure_counter > 0:
  89. print('{} files have errors. Please take a look at the log.'.format(failure_counter))
  90. return 1
  91. if not files:
  92. print('WARNING: no files specified. Please specify files or use '
  93. '"--includes" to search Kconfig files recursively')
  94. return 0
  95. if __name__ == '__main__':
  96. sys.exit(main())