11"""Main CLI tool for document operations."""
22
3+ from docbuild .cli .cmd_metadata import stdout
4+ import logging
35from pathlib import Path
46import sys
5- import logging
7+ from typing import Any , cast
8+
69import click
10+ from pydantic import ValidationError
711import rich .console
812import rich .logging
913from rich .pretty import install
1014from rich .traceback import install as install_traceback
11- from pydantic import ValidationError
12- from typing import Any , cast
1315
1416from ..__about__ import __version__
15- from ..config .app import replace_placeholders
17+ from ..config .app import PlaceholderResolutionError , replace_placeholders
1618from ..config .load import handle_config
1719from ..models .config_model .app import AppConfig
18- from ..models .config_model .env import EnvConfig
20+ from ..models .config_model .env import EnvConfig
1921
2022from ..constants import (
2123 APP_CONFIG_BASENAMES ,
2628 PROJECT_LEVEL_APP_CONFIG_FILENAMES ,
2729)
2830from ..logging import setup_logging
29- from ..utils .pidlock import PidFileLock , LockAcquisitionError
31+ from ..models .config_model .app import AppConfig
32+ from ..utils .pidlock import LockAcquisitionError , PidFileLock
3033from .cmd_build import build
3134from .cmd_c14n import c14n
3235from .cmd_config import config
@@ -127,9 +130,9 @@ def cli(
127130 context .verbose = verbose
128131 context .dry_run = dry_run
129132 context .debug = debug
130-
133+
131134 # --- PHASE 1: Load and Validate Application Config (and setup logging) ---
132-
135+
133136 # 1. Load the raw application config dictionary
134137 (
135138 context .appconfigfiles ,
@@ -150,6 +153,7 @@ def cli(
150153 try :
151154 # Pydantic validation also handles placeholder replacement via @model_validator
152155 context .appconfig = AppConfig .from_dict (raw_appconfig )
156+
153157 except (ValueError , ValidationError ) as e :
154158 log .error ("Application configuration failed validation:" )
155159 log .error ("Error in config file(s): %s" , context .appconfigfiles )
@@ -162,7 +166,7 @@ def cli(
162166 setup_logging (cliverbosity = verbose , user_config = {'logging' : logging_config })
163167
164168 # --- PHASE 2: Load Environment Config, Validate, and Acquire Lock ---
165-
169+
166170 # 1. Load raw Environment Config
167171 (
168172 context .envconfigfiles ,
@@ -175,10 +179,10 @@ def cli(
175179 DEFAULT_ENV_CONFIG_FILENAME ,
176180 DEFAULT_ENV_CONFIG ,
177181 )
178-
182+
179183 # Explicitly cast the raw_envconfig type to silence Pylance
180184 raw_envconfig = cast (dict [str , Any ], raw_envconfig )
181-
185+
182186 # 2. VALIDATE the raw environment config dictionary using Pydantic
183187 try :
184188 # Pydantic validation handles placeholder replacement via @model_validator
@@ -191,14 +195,14 @@ def cli(
191195 context .envconfigfiles , e
192196 )
193197 ctx .exit (1 )
194-
198+
195199 env_config_path = context .envconfigfiles [0 ] if context .envconfigfiles else None
196-
200+
197201 # --- CONCURRENCY CONTROL: Use explicit __enter__ and cleanup registration ---
198202 if env_config_path :
199203 # 1. Instantiate the lock object
200204 ctx .obj .env_lock = PidFileLock (resource_path = env_config_path )
201-
205+
202206 try :
203207 # 2. Acquire the lock by explicitly calling the __enter__ method.
204208 ctx .obj .env_lock .__enter__ ()
@@ -212,16 +216,16 @@ def cli(
212216 # Handles critical errors
213217 log .error ("Failed to set up environment lock: %s" , e )
214218 ctx .exit (1 )
215-
219+
216220 # 3. Register the lock's __exit__ method to be called when the context terminates.
217221 # We use a lambda to supply the three mandatory positional arguments (None)
218222 # expected by __exit__, satisfying the click.call_on_close requirement.
219223 ctx .call_on_close (lambda : ctx .obj .env_lock .__exit__ (None , None , None ))
220-
224+
221225# Add subcommand
222226cli .add_command (build )
223227cli .add_command (c14n )
224228cli .add_command (config )
225229cli .add_command (repo )
226230cli .add_command (metadata )
227- cli .add_command (validate )
231+ cli .add_command (validate )
0 commit comments