- Modular installer with gum-based TUI - Fresh-install detection with auto GPU driver selection - Preflight module for system detection (Intel/AMD/NVIDIA) - Core modules: packages, dotfiles, services, SDDM - Optional software installer (Obsidian, Neovim, VS Code, etc.) - Homelab config module with dynamic AGS integration - Two complete themes: Forest Neon and Rose Night - 19 Hyprland control scripts + 4 AGS widgets - Idempotent dotfile deployment with automatic backup - YAML-based configuration, extensible module system - Full logging to ~/.local/share/omeron/
129 lines
2.9 KiB
Bash
Executable File
129 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
OMERON_CONFIG_DIR="${OMERON_CONFIG_DIR:-$HOME/.config/omeron}"
|
|
OMERON_PROJECT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
config_load() {
|
|
local config_file="$1"
|
|
|
|
if [[ ! -f "$config_file" ]]; then
|
|
log_warn "Configuration not found: $config_file"
|
|
return 1
|
|
fi
|
|
|
|
if command -v yq >/dev/null 2>&1; then
|
|
config_parse_yq "$config_file"
|
|
elif command -v python3 >/dev/null 2>&1; then
|
|
config_parse_python "$config_file"
|
|
else
|
|
config_parse_shell "$config_file"
|
|
fi
|
|
}
|
|
|
|
config_parse_yq() {
|
|
local config_file="$1"
|
|
local key
|
|
|
|
while IFS='=' read -r key value; do
|
|
[[ -z "$key" ]] && continue
|
|
printf 'export OMERON_CFG_%s="%s"\n' "$key" "$value"
|
|
done < <(yq -o shell "$config_file" 2>/dev/null)
|
|
}
|
|
|
|
config_parse_python() {
|
|
local config_file="$1"
|
|
|
|
python3 -c "
|
|
import yaml, os, sys
|
|
|
|
with open('$config_file') as f:
|
|
data = yaml.safe_load(f)
|
|
|
|
if not data:
|
|
sys.exit(0)
|
|
|
|
def flatten(d, prefix=''):
|
|
for k, v in d.items():
|
|
key = f'{prefix}_{k}' if prefix else k
|
|
if isinstance(v, dict):
|
|
flatten(v, key)
|
|
elif isinstance(v, list):
|
|
print(f'export OMERON_CFG_{key}=\"{chr(32).join(str(x) for x in v)}\"')
|
|
else:
|
|
print(f'export OMERON_CFG_{key}=\"{v}\"')
|
|
|
|
flatten(data)
|
|
" 2>/dev/null || config_parse_shell "$config_file"
|
|
}
|
|
|
|
config_parse_shell() {
|
|
local config_file="$1"
|
|
local line key value
|
|
|
|
while IFS= read -r line; do
|
|
line="${line%%#*}"
|
|
[[ -z "$line" ]] && continue
|
|
if [[ "$line" =~ ^[[:space:]]*([a-zA-Z_][a-zA-Z0-9_]*):[[:space:]]*(.*) ]]; then
|
|
key="${BASH_REMATCH[1]}"
|
|
value="${BASH_REMATCH[2]}"
|
|
value="${value#[\"\']}"
|
|
value="${value%[\"\']}"
|
|
printf 'export OMERON_CFG_%s="%s"\n' "$key" "$value"
|
|
fi
|
|
done < "$config_file"
|
|
}
|
|
|
|
config_save() {
|
|
local config_file="$1"
|
|
local key value
|
|
|
|
mkdir -p "$(dirname "$config_file")"
|
|
|
|
{
|
|
printf '# Omeron Configuration\n'
|
|
printf '# Generated: %s\n\n' "$(date --rfc-3339=seconds)"
|
|
for entry in "$@"; do
|
|
key="${entry%%=*}"
|
|
value="${entry#*=}"
|
|
printf '%s: "%s"\n' "$key" "$value"
|
|
done
|
|
} > "$config_file"
|
|
}
|
|
|
|
config_get() {
|
|
local key="$1"
|
|
local var_name="OMERON_CFG_${key}"
|
|
|
|
printf '%s' "${!var_name:-}"
|
|
}
|
|
|
|
config_merge() {
|
|
local base_file="$1"
|
|
local override_file="$2"
|
|
|
|
if command -v yq >/dev/null 2>&1; then
|
|
yq eval-all '. as $item ireduce ({}; . * $item)' "$base_file" "$override_file"
|
|
elif command -v python3 >/dev/null 2>&1; then
|
|
python3 -c "
|
|
import yaml, sys
|
|
|
|
with open('$base_file') as f:
|
|
base = yaml.safe_load(f) or {}
|
|
with open('$override_file') as f:
|
|
override = yaml.safe_load(f) or {}
|
|
|
|
def merge(a, b):
|
|
for k in b:
|
|
if k in a and isinstance(a[k], dict) and isinstance(b[k], dict):
|
|
merge(a[k], b[k])
|
|
else:
|
|
a[k] = b[k]
|
|
return a
|
|
|
|
print(yaml.dump(merge(base, override), default_flow_style=False))
|
|
" 2>/dev/null || cat "$base_file"
|
|
else
|
|
cat "$base_file"
|
|
fi
|
|
}
|