1+ #!/usr/bin/env python3
2+ """
3+ Script to generate a custom tox configuration for testing changed files.
4+ Used by GitHub Actions workflow for PR testing.
5+ """
6+ import os
7+ import sys
8+
9+
10+ def generate_tox_config (changed_files , output_file = 'tox_pr.ini' ):
11+ """
12+ Generate a customized tox configuration for testing changed files.
13+
14+ Args:
15+ changed_files: List of changed Python files
16+ output_file: Path to write the tox configuration to
17+ """
18+ with open (output_file , 'w' ) as tox_file :
19+ # Write tox section
20+ tox_file .write ('[tox]\n ' )
21+ tox_file .write ('envlist = py312\n ' )
22+ tox_file .write ('skip_missing_interpreters = true\n \n ' )
23+
24+ # Write testenv section
25+ tox_file .write ('[testenv]\n ' )
26+ tox_file .write ('setenv =\n ' )
27+ tox_file .write (' COVERAGE_FILE = .coverage.{envname}\n ' )
28+ tox_file .write ('deps =\n ' )
29+ tox_file .write (' -r requirements-dev.txt\n ' )
30+ tox_file .write ('allowlist_externals =\n ' )
31+ tox_file .write (' pytest\n ' )
32+ tox_file .write (' coverage\n ' )
33+ tox_file .write ('commands =\n ' )
34+
35+ # Always run a baseline test with coverage
36+ tox_file .write (' pytest -xvs --cov=patterns tests/ --cov-report=term-missing\n ' )
37+
38+ # Add test commands for changed files
39+ tox_file .write (' # Run specific tests for changed files\n ' )
40+
41+ for file in changed_files :
42+ if file .endswith ('.py' ):
43+ # Handle implementation files
44+ if file .startswith ('patterns/' ):
45+ module_name = os .path .basename (file )[:- 3 ] # Remove .py extension
46+ pattern_dir = os .path .dirname (file ).split ('/' , 1 )[1 ] if '/' in os .path .dirname (file ) else ''
47+
48+ tox_file .write (f' # Testing { file } \n ' )
49+
50+ # Check for specific test file and add it conditionally
51+ test_file = f'tests/{ pattern_dir } /test_{ module_name } .py'
52+ # Use conditional for test file
53+ tox_file .write (f' python -c "import os.path; test_path=\' { test_file } \' ; print(f\' Test file {{test_path}} exists: {{os.path.exists(test_path)}}\' )" \n ' )
54+ tox_file .write (f' pytest -xvs --cov=patterns --cov-append tests/{ pattern_dir } / -k "{ module_name } "\n ' )
55+
56+ # Run test files directly if modified
57+ if file .startswith ('tests/' ):
58+ tox_file .write (f' pytest -xvs --cov=patterns --cov-append { file } \n ' )
59+
60+ # Run doctests on pattern files
61+ tox_file .write (' # Run doctests\n ' )
62+ for file in changed_files :
63+ if file .startswith ('patterns/' ) and file .endswith ('.py' ):
64+ tox_file .write (f' pytest --doctest-modules -v --cov=patterns --cov-append { file } \n ' )
65+
66+ # Add coverage report commands
67+ tox_file .write (' coverage combine\n ' )
68+ tox_file .write (' coverage report\n ' )
69+
70+
71+ if __name__ == "__main__" :
72+ # Get list of changed files from arguments
73+ changed_files = sys .argv [1 ].split () if len (sys .argv ) > 1 else []
74+
75+ # Generate the tox configuration
76+ generate_tox_config (changed_files )
77+
78+ # Print the configuration to stdout
79+ with open ('tox_pr.ini' , 'r' ) as f :
80+ print (f .read ())
0 commit comments