Source code for configbuddy.cli.cli

# Copyright (c) 2024 Harim Kang
# SPDX-License-Identifier: MIT

import argparse
from pathlib import Path

from rich.console import Console

from configbuddy import CONFIGBUDDY_LOGO, Config, __version__

from .help_formatter import CustomHelpFormatter


[docs] class CLI: def __init__(self, args: list[str] | None = None) -> None: self.console = Console() self.parser = self.init_parser() self.add_subcommands() self.args = self.parser.parse_args(args) self.execute()
[docs] def init_parser(self) -> argparse.ArgumentParser: parser = argparse.ArgumentParser( description="ConfigBuddy: Configuration Management Tool", formatter_class=CustomHelpFormatter, ) parser.add_argument( "-v", "--version", action="version", version=f"%(prog)s {__version__}", help="Display configbuddy version number", ) return parser
[docs] def add_subcommands(self) -> None: subparsers = self.parser.add_subparsers( dest="command", required=True, title="commands", description="available commands", ) # 1. visualize visualize_parser = subparsers.add_parser( "visualize", help="Visualize configuration in tree format", formatter_class=CustomHelpFormatter, ) visualize_parser.add_argument("config", type=Path, help="Configuration file to visualize") # 2. diff diff_parser = subparsers.add_parser( "diff", help="Compare two configurations", formatter_class=CustomHelpFormatter, ) diff_parser.add_argument("config", type=Path, help="Base configuration file") diff_parser.add_argument("--compare", type=Path, help="Other configuration file") # 3. merge merge_parser = subparsers.add_parser("merge", help="Merge configurations", formatter_class=CustomHelpFormatter) merge_parser.add_argument("configs", type=Path, nargs="+", help="Configuration files to merge") merge_parser.add_argument("--output", "-o", type=Path, help="Output file path") merge_parser.add_argument( "--strategy", choices=["deep", "shallow"], default="deep", help="Merge strategy (default: deep)", ) # 4. validate validate_parser = subparsers.add_parser( "validate", help="Validate configuration", formatter_class=CustomHelpFormatter, ) validate_parser.add_argument("config", type=Path, help="Configuration file to validate") validate_parser.add_argument("--schema", type=Path, help="JSON schema file") # 5. Generate Schema generate_schema_parser = subparsers.add_parser( "generate-schema", help="Generate schema from configuration", formatter_class=CustomHelpFormatter, ) generate_schema_parser.add_argument("config", type=Path, help="Configuration file to generate schema") generate_schema_parser.add_argument("--output", "-o", type=Path, help="Output file path")
[docs] def execute(self) -> None: self.console.print(CONFIGBUDDY_LOGO, style="blue") if self.args.command == "visualize": config = Config.from_file(self.args.config) config.visualize() elif self.args.command == "diff": config1 = Config.from_file(self.args.config) config2 = Config.from_file(self.args.compare) result = config1.diff_with(config2) result.visualize() elif self.args.command == "merge": configs = [Config.from_file(path) for path in self.args.configs] base_config = configs[0] for config in configs[1:]: merged_config, conflicts = base_config.merge_with(config) base_config = merged_config if conflicts: self.console.print("[yellow]Merge conflicts detected:[/]") for conflict in conflicts: self.console.print(f" - {conflict}") base_config.save(self.args.output) self.console.print(f"[green]Merged configuration saved to {self.args.output}[/]") elif self.args.command == "validate": config = Config.from_file(self.args.config) errors = config.validate(self.args.schema) if errors: self.console.print("[red]Validation errors:[/red]") for error in errors: self.console.print(f" - {error}", style="red") else: self.console.print("[green]Configuration is valid.[/green]") elif self.args.command == "generate-schema": from configbuddy.core.validator import ConfigValidator ConfigValidator.from_config(Config.from_file(self.args.config)).save_schema(self.args.output) self.console.print(f"[green]Schema generated and saved to {self.args.output}[/green]")