--- /dev/null
+#!/usr/bin/python3
+
+"""Update modules.d rules in .github/labeler.py."""
+
+import argparse
+import difflib
+import os
+import pathlib
+import re
+import sys
+
+
+def generate_diff(before: str, after: str, filename: str) -> str:
+ """Generate a unified diff between the two given file contents."""
+ before_lines = before.splitlines(keepends=True)
+ after_lines = after.splitlines(keepends=True)
+ diff = difflib.unified_diff(
+ before_lines, after_lines, fromfile=f"a/{filename}", tofile=f"b/{filename}"
+ )
+ return "".join(diff)
+
+
+def generate_labeler_yaml(modules: list[str], header: str) -> str:
+ """Generate a labeler YAML file from the given list of Dracut modules."""
+ script_name = pathlib.Path(__file__).relative_to(os.getcwd())
+ comment = f"# The following lines were generated by {script_name}\n"
+ return header + comment + "\n".join(f"""\
+{module}:
+ - changed-files:
+ - any-glob-to-any-file: 'modules.d/[0-9][0-9]{module}/*'
+""" for module in modules)
+
+
+def get_modules_names(modules_dir: pathlib.Path) -> list[str]:
+ """List module names (without their numbers) in the given modules.d directory."""
+ return sorted(
+ x.name[2:] for x in modules_dir.iterdir() if x.is_dir() and not x.is_symlink()
+ )
+
+
+def remove_generated_part(yaml_content: str) -> str:
+ """Remove the part of the labeler YAML that was generated by this script."""
+ return re.sub(
+ "# The following lines were generated.*$", "", yaml_content, flags=re.DOTALL
+ )
+
+
+def main() -> int:
+ """Update modules.d rules in .github/labeler.py."""
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-c", "--check", action="store_true")
+ parser.add_argument("--labeler", default=".github/labeler.yml")
+ args = parser.parse_args()
+
+ modules = get_modules_names(pathlib.Path("modules.d"))
+ current_labeler_yaml = pathlib.Path(args.labeler).read_text("utf-8")
+ header = remove_generated_part(current_labeler_yaml)
+ new_labeler_yaml = generate_labeler_yaml(modules, header)
+ diff = generate_diff(current_labeler_yaml, new_labeler_yaml, args.labeler)
+ if not diff:
+ return 0
+
+ if args.check:
+ print(diff, end="")
+ return 1
+
+ pathlib.Path(args.labeler).write_text(new_labeler_yaml, "utf-8")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())