diff --git a/tools/check_python_dependencies.py b/tools/check_python_dependencies.py index da7bb4f47b..77bace591e 100755 --- a/tools/check_python_dependencies.py +++ b/tools/check_python_dependencies.py @@ -40,6 +40,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 @@ -75,6 +90,7 @@ if __name__ == '__main__': help='Path to a requirements file (can be used multiple times)', action='append', default=[], + type=validate_requirement_list, ) parser.add_argument( '--constraints', diff --git a/tools/idf_tools.py b/tools/idf_tools.py index 7bd77d1e50..2922f1845c 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -1559,6 +1559,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 @@ -1947,6 +1966,7 @@ def process_and_check_features(idf_env_obj: IDFEnv, features_str: str) -> List[s 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