mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 00:58:34 +00:00
feat: adds config/db import functionality
This commit is contained in:
323
scripts/apply-config.py
Executable file
323
scripts/apply-config.py
Executable file
@@ -0,0 +1,323 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AzerothCore Configuration Manager
|
||||
|
||||
Reads server-overrides.conf and preset files to update actual .conf files
|
||||
while preserving comments and structure.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Set
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
"""Manages AzerothCore configuration file updates."""
|
||||
|
||||
def __init__(self, storage_path: str, overrides_file: str, dry_run: bool = False):
|
||||
self.storage_path = Path(storage_path)
|
||||
self.config_dir = self.storage_path / "config"
|
||||
self.modules_config_dir = self.storage_path / "config" / "modules"
|
||||
self.overrides_file = Path(overrides_file)
|
||||
self.dry_run = dry_run
|
||||
|
||||
if not self.config_dir.exists():
|
||||
raise FileNotFoundError(f"Config directory not found: {self.config_dir}")
|
||||
|
||||
def load_overrides(self) -> Dict[str, Dict[str, str]]:
|
||||
"""Load configuration overrides from INI-style file."""
|
||||
if not self.overrides_file.exists():
|
||||
print(f"⚠️ Override file not found: {self.overrides_file}")
|
||||
return {}
|
||||
|
||||
config = configparser.ConfigParser(interpolation=None)
|
||||
config.optionxform = str # Preserve case sensitivity
|
||||
|
||||
try:
|
||||
config.read(self.overrides_file, encoding='utf-8')
|
||||
except Exception as e:
|
||||
print(f"❌ Error reading override file: {e}")
|
||||
return {}
|
||||
|
||||
overrides = {}
|
||||
for section in config.sections():
|
||||
overrides[section] = dict(config.items(section))
|
||||
|
||||
return overrides
|
||||
|
||||
def find_conf_file(self, filename: str) -> Optional[Path]:
|
||||
"""Find a configuration file in the config directory."""
|
||||
# Check main config directory first (for core server configs)
|
||||
conf_file = self.config_dir / filename
|
||||
|
||||
if conf_file.exists():
|
||||
return conf_file
|
||||
|
||||
# Check modules config directory (for module configs)
|
||||
modules_conf_file = self.modules_config_dir / filename
|
||||
if modules_conf_file.exists():
|
||||
return modules_conf_file
|
||||
|
||||
# Try to create from .dist file in main config directory
|
||||
dist_file = self.config_dir / f"{filename}.dist"
|
||||
if dist_file.exists():
|
||||
print(f"📄 Creating {filename} from {filename}.dist")
|
||||
if not self.dry_run:
|
||||
shutil.copy2(dist_file, conf_file)
|
||||
return conf_file
|
||||
|
||||
# Try to create from .dist file in modules directory
|
||||
modules_dist_file = self.modules_config_dir / f"{filename}.dist"
|
||||
if modules_dist_file.exists():
|
||||
print(f"📄 Creating {filename} from modules/{filename}.dist")
|
||||
if not self.dry_run:
|
||||
if not self.modules_config_dir.exists():
|
||||
self.modules_config_dir.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(modules_dist_file, modules_conf_file)
|
||||
return modules_conf_file
|
||||
|
||||
return None
|
||||
|
||||
def update_conf_file(self, conf_file: Path, settings: Dict[str, str]) -> bool:
|
||||
"""Update a .conf file with new settings while preserving structure."""
|
||||
if not conf_file.exists():
|
||||
print(f"❌ Configuration file not found: {conf_file}")
|
||||
return False
|
||||
|
||||
try:
|
||||
with open(conf_file, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
except Exception as e:
|
||||
print(f"❌ Error reading {conf_file}: {e}")
|
||||
return False
|
||||
|
||||
updated_lines = []
|
||||
updated_keys = set()
|
||||
|
||||
# Process each line
|
||||
for line in lines:
|
||||
original_line = line
|
||||
stripped = line.strip()
|
||||
|
||||
# Skip empty lines and comments
|
||||
if not stripped or stripped.startswith('#'):
|
||||
updated_lines.append(original_line)
|
||||
continue
|
||||
|
||||
# Check if this line contains a setting we want to override
|
||||
setting_match = re.match(r'^([^=]+?)\s*=\s*(.*)$', stripped)
|
||||
if setting_match:
|
||||
key = setting_match.group(1).strip()
|
||||
|
||||
if key in settings:
|
||||
# Replace with our override value
|
||||
new_value = settings[key]
|
||||
# Preserve the original indentation
|
||||
indent = len(line) - len(line.lstrip())
|
||||
new_line = ' ' * indent + f"{key} = {new_value}\n"
|
||||
updated_lines.append(new_line)
|
||||
updated_keys.add(key)
|
||||
print(f" ✅ {key} = {new_value}")
|
||||
else:
|
||||
# Keep original line
|
||||
updated_lines.append(original_line)
|
||||
else:
|
||||
# Keep original line (could be section header or other content)
|
||||
updated_lines.append(original_line)
|
||||
|
||||
# Add any settings that weren't found in the file
|
||||
for key, value in settings.items():
|
||||
if key not in updated_keys:
|
||||
updated_lines.append(f"{key} = {value}\n")
|
||||
print(f" ➕ {key} = {value} (added)")
|
||||
|
||||
# Write the updated file
|
||||
if not self.dry_run:
|
||||
try:
|
||||
with open(conf_file, 'w', encoding='utf-8') as f:
|
||||
f.writelines(updated_lines)
|
||||
except Exception as e:
|
||||
print(f"❌ Error writing {conf_file}: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def apply_overrides(self, overrides: Dict[str, Dict[str, str]],
|
||||
filter_files: Optional[Set[str]] = None) -> bool:
|
||||
"""Apply all configuration overrides."""
|
||||
success = True
|
||||
|
||||
if not overrides:
|
||||
print("ℹ️ No configuration overrides to apply")
|
||||
return True
|
||||
|
||||
print(f"🔧 Applying configuration overrides{' (DRY RUN)' if self.dry_run else ''}...")
|
||||
|
||||
for conf_filename, settings in overrides.items():
|
||||
# Skip if we're filtering and this file isn't in the filter
|
||||
if filter_files and conf_filename not in filter_files:
|
||||
continue
|
||||
|
||||
if not settings:
|
||||
continue
|
||||
|
||||
print(f"\n📝 Updating {conf_filename}:")
|
||||
|
||||
# Find the configuration file
|
||||
conf_file = self.find_conf_file(conf_filename)
|
||||
if not conf_file:
|
||||
print(f" ⚠️ Configuration file not found: {conf_filename}")
|
||||
success = False
|
||||
continue
|
||||
|
||||
# Update the file
|
||||
if not self.update_conf_file(conf_file, settings):
|
||||
success = False
|
||||
|
||||
return success
|
||||
|
||||
|
||||
def load_preset(preset_file: Path) -> Dict[str, Dict[str, str]]:
|
||||
"""Load a preset configuration file."""
|
||||
if not preset_file.exists():
|
||||
raise FileNotFoundError(f"Preset file not found: {preset_file}")
|
||||
|
||||
config = configparser.ConfigParser(interpolation=None)
|
||||
config.optionxform = str # Preserve case sensitivity
|
||||
config.read(preset_file, encoding='utf-8')
|
||||
|
||||
overrides = {}
|
||||
for section in config.sections():
|
||||
overrides[section] = dict(config.items(section))
|
||||
|
||||
return overrides
|
||||
|
||||
|
||||
def list_available_presets(preset_dir: Path) -> List[str]:
|
||||
"""List available preset files."""
|
||||
if not preset_dir.exists():
|
||||
return []
|
||||
|
||||
presets = []
|
||||
for preset_file in preset_dir.glob("*.conf"):
|
||||
presets.append(preset_file.stem)
|
||||
|
||||
return sorted(presets)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Apply AzerothCore configuration overrides and presets"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--storage-path",
|
||||
default="./storage",
|
||||
help="Path to storage directory (default: ./storage)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--overrides-file",
|
||||
default="./config/server-overrides.conf",
|
||||
help="Path to server overrides file (default: ./config/server-overrides.conf)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--preset",
|
||||
help="Apply a preset from config/presets/<name>.conf"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--list-presets",
|
||||
action="store_true",
|
||||
help="List available presets"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--files",
|
||||
help="Comma-separated list of .conf files to update (default: all)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Show what would be changed without making modifications"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Handle list presets
|
||||
if args.list_presets:
|
||||
preset_dir = Path("./config/presets")
|
||||
presets = list_available_presets(preset_dir)
|
||||
|
||||
if presets:
|
||||
print("📋 Available presets:")
|
||||
for preset in presets:
|
||||
preset_file = preset_dir / f"{preset}.conf"
|
||||
print(f" • {preset}")
|
||||
# Try to read description from preset file
|
||||
if preset_file.exists():
|
||||
try:
|
||||
with open(preset_file, 'r') as f:
|
||||
first_line = f.readline().strip()
|
||||
if first_line.startswith('#') and len(first_line) > 1:
|
||||
description = first_line[1:].strip()
|
||||
print(f" {description}")
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
print("ℹ️ No presets found in config/presets/")
|
||||
return
|
||||
|
||||
try:
|
||||
# Initialize configuration manager
|
||||
config_manager = ConfigManager(
|
||||
storage_path=args.storage_path,
|
||||
overrides_file=args.overrides_file,
|
||||
dry_run=args.dry_run
|
||||
)
|
||||
|
||||
# Determine which files to filter (if any)
|
||||
filter_files = None
|
||||
if args.files:
|
||||
filter_files = set(f.strip() for f in args.files.split(','))
|
||||
|
||||
# Load configuration overrides
|
||||
overrides = {}
|
||||
|
||||
# Load preset if specified
|
||||
if args.preset:
|
||||
preset_file = Path(f"./config/presets/{args.preset}.conf")
|
||||
print(f"📦 Loading preset: {args.preset}")
|
||||
try:
|
||||
preset_overrides = load_preset(preset_file)
|
||||
overrides.update(preset_overrides)
|
||||
except FileNotFoundError as e:
|
||||
print(f"❌ {e}")
|
||||
return 1
|
||||
|
||||
# Load server overrides (this can override preset values)
|
||||
server_overrides = config_manager.load_overrides()
|
||||
overrides.update(server_overrides)
|
||||
|
||||
# Apply all overrides
|
||||
success = config_manager.apply_overrides(overrides, filter_files)
|
||||
|
||||
if success:
|
||||
if args.dry_run:
|
||||
print("\n✅ Configuration validation complete")
|
||||
else:
|
||||
print("\n✅ Configuration applied successfully")
|
||||
print("ℹ️ Restart your server to apply changes")
|
||||
return 0
|
||||
else:
|
||||
print("\n❌ Some configuration updates failed")
|
||||
return 1
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
162
scripts/configure-server.sh
Executable file
162
scripts/configure-server.sh
Executable file
@@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
# Simple wrapper script for server configuration management
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BLUE}🔧 AzerothCore Configuration Manager${NC}\n"
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $(basename "$0") [COMMAND] [OPTIONS]
|
||||
|
||||
Commands:
|
||||
apply Apply configuration overrides from config/server-overrides.conf
|
||||
preset <name> Apply a preset configuration
|
||||
list List available presets
|
||||
edit Open server-overrides.conf in editor
|
||||
status Show current configuration status
|
||||
|
||||
Examples:
|
||||
$(basename "$0") apply # Apply custom overrides
|
||||
$(basename "$0") preset fast-leveling # Apply fast-leveling preset
|
||||
$(basename "$0") list # Show available presets
|
||||
$(basename "$0") edit # Edit configuration file
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
edit_config() {
|
||||
local config_file="$PROJECT_DIR/config/server-overrides.conf"
|
||||
local editor="${EDITOR:-nano}"
|
||||
|
||||
echo -e "${YELLOW}📝 Opening configuration file in $editor...${NC}"
|
||||
|
||||
if [[ ! -f "$config_file" ]]; then
|
||||
echo -e "${YELLOW}⚠️ Configuration file doesn't exist. Creating template...${NC}"
|
||||
mkdir -p "$(dirname "$config_file")"
|
||||
# Create a minimal template if it doesn't exist
|
||||
cat > "$config_file" << 'EOF'
|
||||
# AzerothCore Server Configuration Overrides
|
||||
# Edit this file and run './scripts/configure-server.sh apply' to update settings
|
||||
|
||||
[worldserver.conf]
|
||||
# Example settings - uncomment and modify as needed
|
||||
# Rate.XP.Kill = 2.0
|
||||
# Rate.XP.Quest = 2.0
|
||||
# MaxPlayerLevel = 80
|
||||
|
||||
[playerbots.conf]
|
||||
# Example playerbot settings
|
||||
# AiPlayerbot.MinRandomBots = 100
|
||||
# AiPlayerbot.MaxRandomBots = 300
|
||||
EOF
|
||||
echo -e "${GREEN}✅ Created template configuration file${NC}"
|
||||
fi
|
||||
|
||||
"$editor" "$config_file"
|
||||
|
||||
echo -e "\n${YELLOW}Would you like to apply these changes now? (y/N)${NC}"
|
||||
read -r response
|
||||
if [[ "$response" =~ ^[Yy]$ ]]; then
|
||||
python3 "$SCRIPT_DIR/apply-config.py"
|
||||
else
|
||||
echo -e "${BLUE}ℹ️ Run '$(basename "$0") apply' when ready to apply changes${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
show_status() {
|
||||
echo -e "${BLUE}📊 Configuration Status${NC}\n"
|
||||
|
||||
# Check if config files exist
|
||||
local storage_path="${STORAGE_PATH:-./storage}"
|
||||
local config_dir="$storage_path/config"
|
||||
|
||||
if [[ -d "$config_dir" ]]; then
|
||||
echo -e "${GREEN}✅ Config directory found: $config_dir${NC}"
|
||||
|
||||
local conf_count
|
||||
conf_count=$(find "$config_dir" -name "*.conf" -type f | wc -l)
|
||||
echo -e "${GREEN}📄 Configuration files: $conf_count${NC}"
|
||||
|
||||
# Show some key files
|
||||
for conf in worldserver.conf authserver.conf playerbots.conf; do
|
||||
if [[ -f "$config_dir/$conf" ]]; then
|
||||
echo -e "${GREEN} ✅ $conf${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} ⚠️ $conf (missing)${NC}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo -e "${RED}❌ Config directory not found: $config_dir${NC}"
|
||||
echo -e "${YELLOW}ℹ️ Run './deploy.sh' first to initialize storage${NC}"
|
||||
fi
|
||||
|
||||
# Check override file
|
||||
local override_file="$PROJECT_DIR/config/server-overrides.conf"
|
||||
if [[ -f "$override_file" ]]; then
|
||||
echo -e "${GREEN}✅ Override file: $override_file${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Override file not found${NC}"
|
||||
echo -e "${BLUE}ℹ️ Run '$(basename "$0") edit' to create one${NC}"
|
||||
fi
|
||||
|
||||
# Show available presets
|
||||
echo -e "\n${BLUE}📋 Available Presets:${NC}"
|
||||
python3 "$SCRIPT_DIR/apply-config.py" --list-presets
|
||||
}
|
||||
|
||||
main() {
|
||||
print_header
|
||||
|
||||
case "${1:-}" in
|
||||
"apply")
|
||||
echo -e "${YELLOW}🔄 Applying configuration overrides...${NC}"
|
||||
python3 "$SCRIPT_DIR/apply-config.py" "${@:2}"
|
||||
echo -e "\n${GREEN}✅ Configuration applied!${NC}"
|
||||
echo -e "${YELLOW}ℹ️ Restart your server to apply changes:${NC} docker compose restart"
|
||||
;;
|
||||
"preset")
|
||||
if [[ -z "${2:-}" ]]; then
|
||||
echo -e "${RED}❌ Please specify a preset name${NC}"
|
||||
echo -e "Available presets:"
|
||||
python3 "$SCRIPT_DIR/apply-config.py" --list-presets
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${YELLOW}🎯 Applying preset: $2${NC}"
|
||||
python3 "$SCRIPT_DIR/apply-config.py" --preset "$2" "${@:3}"
|
||||
echo -e "\n${GREEN}✅ Preset '$2' applied!${NC}"
|
||||
echo -e "${YELLOW}ℹ️ Restart your server to apply changes:${NC} docker compose restart"
|
||||
;;
|
||||
"list")
|
||||
python3 "$SCRIPT_DIR/apply-config.py" --list-presets
|
||||
;;
|
||||
"edit")
|
||||
edit_config
|
||||
;;
|
||||
"status")
|
||||
show_status
|
||||
;;
|
||||
"help"|"--help"|"-h"|"")
|
||||
show_usage
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}❌ Unknown command: $1${NC}"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
68
scripts/import-database-files.sh
Executable file
68
scripts/import-database-files.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
# Copy user database files from database-import/ to backup system
|
||||
set -e
|
||||
|
||||
# Source environment variables
|
||||
if [ -f ".env" ]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
fi
|
||||
|
||||
IMPORT_DIR="./database-import"
|
||||
STORAGE_PATH="${STORAGE_PATH:-./storage}"
|
||||
STORAGE_PATH_LOCAL="${STORAGE_PATH_LOCAL:-./local-storage}"
|
||||
BACKUP_DIR="${STORAGE_PATH}/backups/daily"
|
||||
TIMESTAMP=$(date +%Y-%m-%d)
|
||||
|
||||
# Exit if no import directory or empty
|
||||
if [ ! -d "$IMPORT_DIR" ] || [ -z "$(ls -A "$IMPORT_DIR" 2>/dev/null | grep -E '\.(sql|sql\.gz)$')" ]; then
|
||||
echo "📁 No database files found in $IMPORT_DIR - skipping import"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Exit if backup system already has databases restored
|
||||
if [ -f "${STORAGE_PATH_LOCAL}/mysql-data/.restore-completed" ]; then
|
||||
echo "✅ Database already restored - skipping import"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📥 Found database files in $IMPORT_DIR"
|
||||
echo "📂 Copying to backup system for import..."
|
||||
|
||||
# Ensure backup directory exists
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Copy files with smart naming
|
||||
for file in "$IMPORT_DIR"/*.sql "$IMPORT_DIR"/*.sql.gz; do
|
||||
[ -f "$file" ] || continue
|
||||
|
||||
filename=$(basename "$file")
|
||||
|
||||
# Try to detect database type by filename
|
||||
if echo "$filename" | grep -qi "auth"; then
|
||||
target_name="acore_auth_${TIMESTAMP}.sql"
|
||||
elif echo "$filename" | grep -qi "world"; then
|
||||
target_name="acore_world_${TIMESTAMP}.sql"
|
||||
elif echo "$filename" | grep -qi "char"; then
|
||||
target_name="acore_characters_${TIMESTAMP}.sql"
|
||||
else
|
||||
# Fallback - use original name with timestamp
|
||||
base_name="${filename%.*}"
|
||||
ext="${filename##*.}"
|
||||
target_name="${base_name}_${TIMESTAMP}.${ext}"
|
||||
fi
|
||||
|
||||
# Add .gz extension if source is compressed
|
||||
if [[ "$filename" == *.sql.gz ]]; then
|
||||
target_name="${target_name}.gz"
|
||||
fi
|
||||
|
||||
target_path="$BACKUP_DIR/$target_name"
|
||||
|
||||
echo "📋 Copying $filename → $target_name"
|
||||
cp "$file" "$target_path"
|
||||
done
|
||||
|
||||
echo "✅ Database files copied to backup system"
|
||||
echo "💡 Files will be automatically imported during deployment"
|
||||
92
scripts/parse-config-presets.py
Executable file
92
scripts/parse-config-presets.py
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Parse configuration preset metadata for setup.sh
|
||||
"""
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def parse_preset_metadata(preset_file: Path):
|
||||
"""Parse CONFIG_NAME and CONFIG_DESCRIPTION from a preset file."""
|
||||
if not preset_file.exists():
|
||||
return None, None
|
||||
|
||||
config_name = None
|
||||
config_description = None
|
||||
|
||||
try:
|
||||
with open(preset_file, 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line.startswith('# CONFIG_NAME:'):
|
||||
config_name = line[14:].strip()
|
||||
elif line.startswith('# CONFIG_DESCRIPTION:'):
|
||||
config_description = line[21:].strip()
|
||||
elif not line.startswith('#'):
|
||||
# Stop at first non-comment line
|
||||
break
|
||||
except Exception:
|
||||
return None, None
|
||||
|
||||
return config_name, config_description
|
||||
|
||||
|
||||
def list_presets(presets_dir: Path):
|
||||
"""List all available presets with their metadata."""
|
||||
if not presets_dir.exists():
|
||||
return
|
||||
|
||||
presets = []
|
||||
for preset_file in presets_dir.glob("*.conf"):
|
||||
preset_key = preset_file.stem
|
||||
config_name, config_description = parse_preset_metadata(preset_file)
|
||||
|
||||
if config_name is None:
|
||||
config_name = preset_key.replace('-', ' ').title()
|
||||
if config_description is None:
|
||||
config_description = f"Configuration preset: {preset_key}"
|
||||
|
||||
presets.append((preset_key, config_name, config_description))
|
||||
|
||||
# Sort presets, but ensure 'none' comes first
|
||||
presets.sort(key=lambda x: (0 if x[0] == 'none' else 1, x[0]))
|
||||
|
||||
for preset_key, config_name, config_description in presets:
|
||||
print(f"{preset_key}\t{config_name}\t{config_description}")
|
||||
|
||||
|
||||
def get_preset_info(presets_dir: Path, preset_key: str):
|
||||
"""Get information for a specific preset."""
|
||||
preset_file = presets_dir / f"{preset_key}.conf"
|
||||
config_name, config_description = parse_preset_metadata(preset_file)
|
||||
|
||||
if config_name is None:
|
||||
config_name = preset_key.replace('-', ' ').title()
|
||||
if config_description is None:
|
||||
config_description = f"Configuration preset: {preset_key}"
|
||||
|
||||
print(f"{config_name}\t{config_description}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Parse configuration preset metadata")
|
||||
parser.add_argument("command", choices=["list", "info"], help="Command to execute")
|
||||
parser.add_argument("--presets-dir", default="./config/presets", help="Presets directory")
|
||||
parser.add_argument("--preset", help="Preset name for 'info' command")
|
||||
|
||||
args = parser.parse_args()
|
||||
presets_dir = Path(args.presets_dir)
|
||||
|
||||
if args.command == "list":
|
||||
list_presets(presets_dir)
|
||||
elif args.command == "info":
|
||||
if not args.preset:
|
||||
print("Error: --preset required for 'info' command", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
get_preset_info(presets_dir, args.preset)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user