11"""ConfigDrift CLI entry point."""
22
3- from pathlib import Path
4- from typing import Dict , Any , Optional
5- from enum import Enum
6-
73import typer
4+ from enum import Enum
5+ from pathlib import Path
86from rich .console import Console
97from rich .table import Table
8+ from typing import Any
109
1110try :
1211 from revenueholdings_license import require_license
@@ -17,13 +16,11 @@ def require_license(product: str) -> None: # type: ignore[misc]
1716 pass
1817
1918from configdrift import __version__
20- from configdrift .loader import load_file
2119from configdrift .diff import (
22- ChangeType ,
2320 Severity ,
24- diff_configs ,
2521 diff_environments ,
2622)
23+ from configdrift .loader import load_file
2724
2825app = typer .Typer (
2926 name = "configdrift" ,
@@ -62,7 +59,9 @@ class OutputFormat(str, Enum):
6259@app .command ()
6360def check (
6461 files : list [str ] = typer .Argument (..., help = "Config files to compare (2+ files)." ),
65- baseline : str = typer .Option ("dev" , "--baseline" , "-b" , help = "Baseline environment name (used as label for first file in 2-file mode)." ),
62+ baseline : str = typer .Option (
63+ "dev" , "--baseline" , "-b" , help = "Baseline environment name (1st file label in 2-file mode)."
64+ ),
6665 target : str = typer .Option ("target" , "--target" , "-t" , help = "Target environment label for second file." ),
6766 output : OutputFormat = typer .Option (OutputFormat .TABLE , "--output" , "-o" , help = "Output format." ),
6867):
@@ -71,20 +70,20 @@ def check(
7170 console .print ("[red]ERROR: Provide at least 2 config files to compare.[/red]" )
7271 raise typer .Exit (code = 1 )
7372
74- env_configs : Dict [str , Dict [str , Any ]] = {}
73+ env_configs : dict [str , dict [str , Any ]] = {}
7574 env_labels = []
7675
7776 if len (files ) == 2 :
7877 env_labels = [baseline , target ]
7978 else :
8079 env_labels = [f"file_{ i + 1 } " for i in range (len (files ))]
8180
82- for label , filepath in zip (env_labels , files ):
81+ for label , filepath in zip (env_labels , files , strict = False ):
8382 try :
8483 env_configs [label ] = load_file (filepath )
8584 except Exception as e :
8685 console .print (f"[red]Error loading { filepath } : { e } [/red]" )
87- raise typer .Exit (code = 1 )
86+ raise typer .Exit (code = 1 ) from None
8887
8988 baseline_env = env_labels [0 ]
9089 results = diff_environments (env_configs , baseline_env = baseline_env )
@@ -103,7 +102,7 @@ def check(
103102 raise typer .Exit (code = 1 )
104103
105104
106- def _output_table (results : Dict [str , Any ], baseline_env : str ):
105+ def _output_table (results : dict [str , Any ], baseline_env : str ):
107106 for env_name , diff_result in results .items ():
108107 if not diff_result .changes :
109108 continue
@@ -119,7 +118,11 @@ def _output_table(results: Dict[str, Any], baseline_env: str):
119118 symbol = {"added" : "+" , "removed" : "-" , "changed" : "~" }[change .change_type .value ]
120119 old_str = str (change .old_value ) if change .old_value is not None else ""
121120 new_str = str (change .new_value ) if change .new_value is not None else ""
122- sev_style = "red" if change .severity == Severity .BREAKING else "yellow" if change .severity == Severity .WARNING else "white"
121+ sev_style = (
122+ "red"
123+ if change .severity == Severity .BREAKING
124+ else "yellow" if change .severity == Severity .WARNING else "white"
125+ )
123126 table .add_row (
124127 change .key ,
125128 f"{ symbol } { change .change_type .value } " ,
@@ -135,7 +138,7 @@ def _output_table(results: Dict[str, Any], baseline_env: str):
135138 console .print ()
136139
137140
138- def _output_json (results : Dict [str , Any ]):
141+ def _output_json (results : dict [str , Any ]):
139142 import json
140143 output = {}
141144 for env_name , diff_result in results .items ():
@@ -158,16 +161,18 @@ def _output_json(results: Dict[str, Any]):
158161
159162@app .command ()
160163def scan (
161- dirs : Optional [list [str ]] = typer .Argument (None , help = "Directories containing config files. Each dir is treated as an environment." ),
164+ dirs : list [str ] | None = typer .Argument (
165+ None , help = "Directories of config files to compare (each = one env)."
166+ ),
162167 baseline : str = typer .Option ("dev" , "--baseline" , "-b" , help = "Baseline directory name for comparison." ),
163- config : Optional [ str ] = typer .Option (None , "--config" , "-c" , help = "Path to .configdrift.yaml config file." ),
168+ config : str | None = typer .Option (None , "--config" , "-c" , help = "Path to .configdrift.yaml config file." ),
164169 output : OutputFormat = typer .Option (OutputFormat .TABLE , "--output" , "-o" , help = "Output format." ),
165170):
166171 """Scan directories of config files and compare environments."""
167172 if config :
168173 # Load config file for directory → env mapping (raw, not flattened)
169174 import yaml as _yaml
170- with open (config , "r" , encoding = "utf-8" ) as _f :
175+ with open (config , encoding = "utf-8" ) as _f :
171176 cfg_data = _yaml .safe_load (_f ) or {}
172177 dir_mapping = cfg_data .get ("environments" , {})
173178 elif dirs :
@@ -184,7 +189,7 @@ def scan(
184189 console .print (f"[red]Baseline environment '{ baseline } ' not found.[/red]" )
185190 raise typer .Exit (code = 1 )
186191
187- env_configs : Dict [str , Dict [str , Any ]] = {}
192+ env_configs : dict [str , dict [str , Any ]] = {}
188193 for env_name , dir_path in dir_mapping .items ():
189194 env_configs [env_name ] = {}
190195 p = Path (dir_path )
0 commit comments