#!/usr/bin/env python3 """ Test runner for skill scripts Validates that all scripts in a skill are properly structured and executable. Usage: test_skill_scripts.py """ import argparse import subprocess import sys from pathlib import Path def test_python_scripts(scripts_dir): """Test Python scripts for syntax and executability.""" results = [] for script in scripts_dir.glob("*.py"): if script.name.startswith("test_") or script.name == "__init__.py": continue # Check if executable is_executable = script.stat().st_mode & 0o111 # Check syntax try: subprocess.run( [sys.executable, "-m", "py_compile", str(script)], capture_output=True, check=True ) syntax_ok = True except subprocess.CalledProcessError: syntax_ok = False results.append({ 'name': script.name, 'type': 'python', 'executable': is_executable, 'syntax_ok': syntax_ok }) return results def test_go_scripts(scripts_dir): """Test Go scripts for compilation.""" results = [] for script in scripts_dir.glob("*.go"): # Try to compile try: result = subprocess.run( ["go", "build", "-o", "/dev/null", str(script)], capture_output=True, check=True ) compiles = True error = None except subprocess.CalledProcessError as e: compiles = False error = e.stderr.decode() except FileNotFoundError: compiles = None # Go not installed error = "Go compiler not found" results.append({ 'name': script.name, 'type': 'go', 'compiles': compiles, 'error': error }) return results def test_bash_scripts(scripts_dir): """Test Bash scripts for syntax.""" results = [] for script in scripts_dir.glob("*.sh"): # Check if executable is_executable = script.stat().st_mode & 0o111 # Check syntax try: subprocess.run( ["bash", "-n", str(script)], capture_output=True, check=True ) syntax_ok = True except subprocess.CalledProcessError: syntax_ok = False results.append({ 'name': script.name, 'type': 'bash', 'executable': is_executable, 'syntax_ok': syntax_ok }) return results def print_results(results): """Print test results.""" print("\n" + "="*70) print("SCRIPT TEST RESULTS") print("="*70 + "\n") all_passed = True for result in results: name = result['name'] script_type = result['type'] print(f"{name} ({script_type})") if script_type == 'python': if result['syntax_ok']: print(" ✅ Syntax: OK") else: print(" ❌ Syntax: FAILED") all_passed = False if result['executable']: print(" ✅ Executable: Yes") else: print(" ⚠️ Executable: No (run: chmod +x)") elif script_type == 'go': if result['compiles'] is None: print(" ⚠️ Go compiler not found (skipped)") elif result['compiles']: print(" ✅ Compiles: OK") else: print(" ❌ Compiles: FAILED") if result['error']: print(f" Error: {result['error'][:100]}") all_passed = False elif script_type == 'bash': if result['syntax_ok']: print(" ✅ Syntax: OK") else: print(" ❌ Syntax: FAILED") all_passed = False if result['executable']: print(" ✅ Executable: Yes") else: print(" ⚠️ Executable: No (run: chmod +x)") print() return all_passed def main(): parser = argparse.ArgumentParser( description='Test all scripts in a skill directory' ) parser.add_argument('skill_path', help='Path to skill directory') args = parser.parse_args() skill_path = Path(args.skill_path).resolve() scripts_dir = skill_path / 'scripts' if not scripts_dir.exists(): print(f"Error: scripts directory not found: {scripts_dir}") sys.exit(1) print(f"Testing scripts in: {scripts_dir}") results = [] results.extend(test_python_scripts(scripts_dir)) results.extend(test_go_scripts(scripts_dir)) results.extend(test_bash_scripts(scripts_dir)) if not results: print("No scripts found to test") sys.exit(0) all_passed = print_results(results) if all_passed: print("✅ All tests passed!") sys.exit(0) else: print("❌ Some tests failed") sys.exit(1) if __name__ == '__main__': main()