#!/usr/bin/env python3 from __future__ import annotations import argparse import concurrent.futures import json import os import os.path import subprocess import sys EXCLUDED = { ('windows-latest', 'r'), # no r on windows ('windows-latest', 'swift'), # no swift on windows } ALLOWED_LANGUAGES = {'python', 'pipenv'} def _always_run() -> set[str]: return { 'pre_commit/languages/all.py', 'pre_commit/languages/helpers.py', 'pre_commit/languages/__init__.py', 'pre_commit/languages/python.py', # python is a base for other languages 'pre_commit/languages/pipenv.py', # our new language } def _lang_files(lang: str) -> set[str]: cmd = ('git', 'grep', '-l', '') env = dict(os.environ, GIT_LITERAL_PATHSPECS='1') out = subprocess.check_output( (*cmd, f':(glob,top)pre_commit/languages/{lang}.py'), env=env, ).decode() ret = set(out.splitlines()) ret.add(f'tests/languages/{lang}_test.py') return ret def main() -> int: parser = argparse.ArgumentParser() parser.add_argument('--all', action='store_true') args = parser.parse_args() langs = [ lang for lang in ALLOWED_LANGUAGES if os.path.exists(f'pre_commit/languages/{lang}.py') ] triggers_all = _always_run() for fname in triggers_all: assert os.path.exists(fname), fname if not args.all: with concurrent.futures.ThreadPoolExecutor(os.cpu_count()) as exe: by_lang = { lang: files | triggers_all for lang, files in zip(langs, exe.map(_lang_files, langs)) } diff_cmd = ('git', 'diff', '--name-only', 'origin/main...HEAD') files = set(subprocess.check_output(diff_cmd).decode().splitlines()) langs = [ lang for lang, lang_files in by_lang.items() if lang_files & files ] matched = [ {'os': os, 'language': lang} for os in ('windows-latest', 'ubuntu-latest') for lang in langs if (os, lang) not in EXCLUDED ] with open(os.environ['GITHUB_OUTPUT'], 'a') as f: f.write(f'languages={json.dumps(matched)}\n') return 0 if __name__ == '__main__': raise SystemExit(main())