diff --git a/tools/check_python_dependencies.py b/tools/check_python_dependencies.py index 1c290b4b7c..35df9ea392 100755 --- a/tools/check_python_dependencies.py +++ b/tools/check_python_dependencies.py @@ -37,6 +37,21 @@ except ImportError: PYTHON_PACKAGE_RE = re.compile(r'[^<>=~]+') +def validate_requirement_list(file_path: str) -> str: + """Validate that a requirement file exists and is readable.""" + if not os.path.isfile(file_path): + raise argparse.ArgumentTypeError( + f'Requirement file {file_path} not found\n' + 'Please make sure the file path is correct.\n' + 'In case the file was removed, please run the export script again, to update the environment.' + ) + try: + open(file_path, encoding='utf-8').close() + except IOError as e: + raise argparse.ArgumentTypeError(f'Cannot read requirement file {file_path}: {e}') + return file_path + + # The version and requires function from importlib.metadata in python prior # 3.10 does perform distribution name normalization before searching for # package distribution. This might cause problems for package with dot in its @@ -66,12 +81,21 @@ def get_requires(name: str) -> Optional[list]: if __name__ == '__main__': parser = argparse.ArgumentParser(description='ESP-IDF Python package dependency checker') - parser.add_argument('--requirements', '-r', - help='Path to a requirements file (can be used multiple times)', - action='append', default=[]) - parser.add_argument('--constraints', '-c', default=[], - help='Path to a constraints file (can be used multiple times)', - action='append') + parser.add_argument( + '--requirements', + '-r', + help='Path to a requirements file (can be used multiple times)', + action='append', + default=[], + type=validate_requirement_list, + ) + parser.add_argument( + '--constraints', + '-c', + default=[], + help='Path to a constraints file (can be used multiple times)', + action='append', + ) args = parser.parse_args() required_set = set() diff --git a/tools/idf_tools.py b/tools/idf_tools.py index 7bb759ce94..a83e026391 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -1203,6 +1203,25 @@ class IDFRecord: features.add('core') self._features = list(features) + def check_feature_requirements_files(self) -> None: + """ + Check if feature requirements files exist. + If not, remove the feature from the features list. + """ + features_to_remove: Tuple[str, ...] = () + for feature in self._features: + if not os.path.isfile(feature_to_requirements_path(feature)): + info( + '\n'.join( + [ + f"Feature file '{feature_to_requirements_path(feature)}' does not exist.", + f'Removing feature {feature}', + ] + ) + ) + features_to_remove += (feature,) + self.update_features(remove=features_to_remove) + @property def targets(self) -> List[str]: return self._targets @@ -1540,6 +1559,7 @@ def process_and_check_features(idf_env_obj, features_str): # type: (IDFEnv, str raise SystemExit(1) idf_env_obj.get_active_idf_record().update_features(tuple(new_features), tuple(remove_features)) + idf_env_obj.get_active_idf_record().check_feature_requirements_files() return idf_env_obj.get_active_idf_record().features