Validate that package is correctly installed using exception-style recovery. This uses exception-based validation - we only fail if we encounter actual exceptions when reading package metadata. No arbitrary prechecks (like file counts) are performed, as these cause false positives with
(package_dir: Path)
| 16 | |
| 17 | |
| 18 | def validate_package(package_dir: Path) -> tuple[bool, str]: |
| 19 | """Validate that package is correctly installed using exception-style recovery. |
| 20 | |
| 21 | This uses exception-based validation - we only fail if we encounter actual |
| 22 | exceptions when reading package metadata. No arbitrary prechecks (like file |
| 23 | counts) are performed, as these cause false positives with wrapper packages. |
| 24 | |
| 25 | Args: |
| 26 | package_dir: Path to package directory |
| 27 | |
| 28 | Returns: |
| 29 | (is_valid, error_message) |
| 30 | """ |
| 31 | try: |
| 32 | # Try to read package.json - this is the critical test |
| 33 | # If we can successfully parse it, the package is usable |
| 34 | package_json = package_dir / "package.json" |
| 35 | |
| 36 | with open(package_json, "r") as f: |
| 37 | data = json.load(f) |
| 38 | |
| 39 | # Verify essential fields are present |
| 40 | required_fields = ["name", "version"] |
| 41 | for field in required_fields: |
| 42 | if field not in data: |
| 43 | return False, f"Missing '{field}' in {package_dir.name}/package.json" |
| 44 | |
| 45 | # Success - package.json is readable and valid |
| 46 | return True, "" |
| 47 | |
| 48 | except FileNotFoundError: |
| 49 | return False, f"Missing package.json in {package_dir.name}" |
| 50 | except json.JSONDecodeError as e: |
| 51 | return False, f"Corrupted package.json in {package_dir.name}: {e}" |
| 52 | except KeyboardInterrupt as ki: |
| 53 | handle_keyboard_interrupt(ki) |
| 54 | raise |
| 55 | except Exception as e: |
| 56 | return False, f"Cannot read package.json in {package_dir.name}: {e}" |
| 57 | |
| 58 | |
| 59 | def get_required_packages(project_dir: Path, environment: str) -> list[str]: |
no test coverage detected