#!/usr/bin/env python3 import json import sys import argparse import os from typing import Dict, Any, Optional # Constants VIEW_JSON_FILENAME = 'view.json' def load_json_file(file_path: str) -> Optional[Dict[str, Any]]: """Loads JSON data from a file path. Returns the loaded dict or None on error.""" if not os.path.exists(file_path): # This might be expected if a corresponding file doesn't exist in the baseline # print(f"Warning: File not found: '{file_path}'", file=sys.stderr) return None try: with open(file_path, 'r') as f: data = json.load(f) if not isinstance(data, dict): print(f"Error: Expected JSON root to be an object/dictionary in '{file_path}'", file=sys.stderr) return None # Treat as error return data except json.JSONDecodeError: print(f"Error: Invalid JSON format in file: '{file_path}'", file=sys.stderr) return None # Treat as error except IOError as e: print(f"Error reading file '{file_path}': {e}", file=sys.stderr) return None # Treat as error except Exception as e: print(f"An unexpected error occurred while loading '{file_path}': {e}", file=sys.stderr) return None # Treat as error def compare_directories(dir1: str, dir2: str): """Compares view.json files found in subdirectories of dir1 with corresponding files in dir2.""" print(f"Comparing '{VIEW_JSON_FILENAME}' files:") print(f" Directory 1 (Modified): {dir1}") print(f" Directory 2 (Baseline): {dir2}\n") differences_found = 0 files_compared = 0 errors_loading = 0 baseline_missing = 0 for root, _, files in os.walk(dir1): if VIEW_JSON_FILENAME in files: relative_path = os.path.relpath(root, dir1) file1_path = os.path.join(root, VIEW_JSON_FILENAME) file2_path = os.path.join(dir2, relative_path, VIEW_JSON_FILENAME) print(f"Comparing: {os.path.join(relative_path, VIEW_JSON_FILENAME)}") files_compared += 1 data1 = load_json_file(file1_path) data2 = load_json_file(file2_path) if data1 is None: print(f" - Error loading modified file: {file1_path}") errors_loading += 1 continue # Cannot compare if modified file fails if data2 is None: # Check if the baseline file *should* exist if os.path.exists(os.path.dirname(file2_path)): print(f" - Baseline file missing or errored: {file2_path}") baseline_missing += 1 # Decide if this counts as a difference? Yes, likely. differences_found += 1 else: print(f" - Baseline directory structure missing for: {os.path.join(relative_path, VIEW_JSON_FILENAME)}. Cannot compare.") baseline_missing += 1 # Count as missing baseline structure continue # Cannot compare if baseline is missing/errored # Perform the comparison if data1 == data2: print(" - Identical") else: print(" - DIFFERENCE FOUND") differences_found += 1 print("\n--- Comparison Summary ---") print(f" View files compared: {files_compared}") print(f" Files with differences: {differences_found}") print(f" Errors loading modified files: {errors_loading}") print(f" Baseline files missing/errored: {baseline_missing}") if differences_found == 0 and errors_loading == 0 and baseline_missing == 0: print("\nSuccess: All corresponding view.json files are logically identical.") return 0 # Exit code 0 for success else: print("\nCheck Complete: Differences or errors were encountered.") return 1 # Exit code 1 for differences/errors def main(): parser = argparse.ArgumentParser( description=f"Compares {VIEW_JSON_FILENAME} files between two directory structures.", formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument("dir1", help="Path to the first directory (e.g., the modified one).") parser.add_argument("dir2", help="Path to the second directory (e.g., the baseline/original one).") args = parser.parse_args() # Validate directories exist if not os.path.isdir(args.dir1): print(f"Error: Directory 1 not found: '{args.dir1}'", file=sys.stderr) sys.exit(1) if not os.path.isdir(args.dir2): print(f"Error: Directory 2 not found: '{args.dir2}'", file=sys.stderr) sys.exit(1) exit_code = compare_directories(args.dir1, args.dir2) sys.exit(exit_code) if __name__ == "__main__": main()