mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
* added matugen 3 terminal templates and logic fixed version check and light terminal check refactored json generation fixed syntax keep tmp debug fixed file outputs fixed syntax issues and implicit passing added debug stderr output * moved calls to matugen after template is built correctly added --json hex disabled debug message cleaned up code into modular functions, re-added second full matugen call fixed args added shift commented vs code section debug changes * arg format fixes fixed json import flag fixed string quotation fix arg order * cleaned up fix cfg naming * removed mt2.0 templates and refactored worker removed/replaced matugen 2 templates fix formatter diffs + consistent styling * fixed last json output * fixed syntax error * vs code templates * matugen: inject all stock/custom theme colors as overrides - also some general architectural changes * dank16: remove vscode enrich option --------- Co-authored-by: bbedward
276 lines
9.9 KiB
Bash
Executable File
276 lines
9.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -uo pipefail
|
|
|
|
log() { echo "[matugen-worker] $*" >&2; }
|
|
err() { echo "[matugen-worker] ERROR: $*" >&2; }
|
|
|
|
[[ $# -lt 6 ]] && { echo "Usage: $0 STATE_DIR SHELL_DIR CONFIG_DIR SYNC_MODE_WITH_PORTAL TERMINALS_ALWAYS_DARK --run" >&2; exit 1; }
|
|
|
|
STATE_DIR="$1"
|
|
SHELL_DIR="$2"
|
|
CONFIG_DIR="$3"
|
|
SYNC_MODE_WITH_PORTAL="$4"
|
|
TERMINALS_ALWAYS_DARK="$5"
|
|
shift 5
|
|
[[ "${1:-}" != "--run" ]] && { echo "Usage: $0 ... --run" >&2; exit 1; }
|
|
|
|
[[ ! -d "$STATE_DIR" ]] && { err "STATE_DIR '$STATE_DIR' does not exist"; exit 1; }
|
|
[[ ! -d "$SHELL_DIR" ]] && { err "SHELL_DIR '$SHELL_DIR' does not exist"; exit 1; }
|
|
[[ ! -d "$CONFIG_DIR" ]] && { err "CONFIG_DIR '$CONFIG_DIR' does not exist"; exit 1; }
|
|
|
|
DESIRED_JSON="$STATE_DIR/matugen.desired.json"
|
|
BUILT_KEY="$STATE_DIR/matugen.key"
|
|
LOCK="$STATE_DIR/matugen-worker.lock"
|
|
COLORS_OUTPUT="$STATE_DIR/dms-colors.json"
|
|
|
|
exec 9>"$LOCK"
|
|
flock 9
|
|
rm -f "$BUILT_KEY"
|
|
|
|
read_json_field() {
|
|
local json="$1" field="$2"
|
|
echo "$json" | sed -n "s/.*\"$field\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -1
|
|
}
|
|
|
|
read_json_escaped_field() {
|
|
local json="$1" field="$2"
|
|
local after="${json#*\"$field\":\"}"
|
|
[[ "$after" == "$json" ]] && return
|
|
local result=""
|
|
while [[ -n "$after" ]]; do
|
|
local char="${after:0:1}"
|
|
after="${after:1}"
|
|
[[ "$char" == '"' ]] && break
|
|
[[ "$char" == '\' ]] && { result+="${after:0:1}"; after="${after:1}"; continue; }
|
|
result+="$char"
|
|
done
|
|
echo "$result"
|
|
}
|
|
|
|
read_json_bool() {
|
|
local json="$1" field="$2"
|
|
echo "$json" | sed -n "s/.*\"$field\"[[:space:]]*:[[:space:]]*\([^,}]*\).*/\1/p" | head -1 | tr -d ' '
|
|
}
|
|
|
|
compute_key() {
|
|
local json="$1"
|
|
local kind=$(read_json_field "$json" "kind")
|
|
local value=$(read_json_field "$json" "value")
|
|
local mode=$(read_json_field "$json" "mode")
|
|
local icon=$(read_json_field "$json" "iconTheme")
|
|
local mtype=$(read_json_field "$json" "matugenType")
|
|
local run_user=$(read_json_bool "$json" "runUserTemplates")
|
|
local stock_colors=$(read_json_escaped_field "$json" "stockColors")
|
|
echo "${kind}|${value}|${mode}|${icon:-default}|${mtype:-scheme-tonal-spot}|${run_user:-true}|${stock_colors:-}" | sha256sum | cut -d' ' -f1
|
|
}
|
|
|
|
append_config() {
|
|
local check_cmd="$1" file_name="$2" cfg_file="$3"
|
|
local target="$SHELL_DIR/matugen/configs/$file_name"
|
|
[[ ! -f "$target" ]] && return
|
|
[[ "$check_cmd" != "skip" ]] && ! command -v "$check_cmd" >/dev/null 2>&1 && return
|
|
sed "s|'SHELL_DIR/|'$SHELL_DIR/|g" "$target" >> "$cfg_file"
|
|
echo "" >> "$cfg_file"
|
|
}
|
|
|
|
build_merged_config() {
|
|
local mode="$1" run_user="$2" cfg_file="$3"
|
|
|
|
if [[ "$run_user" == "true" && -f "$CONFIG_DIR/matugen/config.toml" ]]; then
|
|
awk '/^\[config\]/{p=1} /^\[templates\]/{p=0} p' "$CONFIG_DIR/matugen/config.toml" >> "$cfg_file"
|
|
else
|
|
echo "[config]" >> "$cfg_file"
|
|
fi
|
|
echo "" >> "$cfg_file"
|
|
|
|
grep -v '^\[config\]' "$SHELL_DIR/matugen/configs/base.toml" | sed "s|'SHELL_DIR/|'$SHELL_DIR/|g" >> "$cfg_file"
|
|
echo "" >> "$cfg_file"
|
|
|
|
cat >> "$cfg_file" << EOF
|
|
[templates.dank]
|
|
input_path = '$SHELL_DIR/matugen/templates/dank.json'
|
|
output_path = '$COLORS_OUTPUT'
|
|
|
|
EOF
|
|
|
|
[[ "$mode" == "light" ]] && append_config "skip" "gtk3-light.toml" "$cfg_file" || append_config "skip" "gtk3-dark.toml" "$cfg_file"
|
|
|
|
append_config "niri" "niri.toml" "$cfg_file"
|
|
append_config "qt5ct" "qt5ct.toml" "$cfg_file"
|
|
append_config "qt6ct" "qt6ct.toml" "$cfg_file"
|
|
append_config "firefox" "firefox.toml" "$cfg_file"
|
|
append_config "pywalfox" "pywalfox.toml" "$cfg_file"
|
|
append_config "vesktop" "vesktop.toml" "$cfg_file"
|
|
append_config "ghostty" "ghostty.toml" "$cfg_file"
|
|
append_config "kitty" "kitty.toml" "$cfg_file"
|
|
append_config "foot" "foot.toml" "$cfg_file"
|
|
append_config "alacritty" "alacritty.toml" "$cfg_file"
|
|
append_config "wezterm" "wezterm.toml" "$cfg_file"
|
|
append_config "dgop" "dgop.toml" "$cfg_file"
|
|
append_config "code" "vscode.toml" "$cfg_file"
|
|
append_config "codium" "codium.toml" "$cfg_file"
|
|
|
|
if [[ "$run_user" == "true" && -f "$CONFIG_DIR/matugen/config.toml" ]]; then
|
|
awk '/^\[templates\]/{p=1} p' "$CONFIG_DIR/matugen/config.toml" >> "$cfg_file"
|
|
echo "" >> "$cfg_file"
|
|
fi
|
|
|
|
if [[ -d "$CONFIG_DIR/matugen/dms/configs" ]]; then
|
|
for config in "$CONFIG_DIR/matugen/dms/configs"/*.toml; do
|
|
[[ -f "$config" ]] || continue
|
|
cat "$config" >> "$cfg_file"
|
|
echo "" >> "$cfg_file"
|
|
done
|
|
fi
|
|
}
|
|
|
|
generate_dank16() {
|
|
local primary="$1" surface="$2" light_flag="$3"
|
|
local args=("$primary" --json)
|
|
[[ -n "$light_flag" ]] && args+=("$light_flag")
|
|
[[ -n "$surface" ]] && args+=(--background "$surface")
|
|
dms dank16 "${args[@]}" 2>/dev/null || echo '{}'
|
|
}
|
|
|
|
set_system_color_scheme() {
|
|
[[ "$SYNC_MODE_WITH_PORTAL" != "true" ]] && return
|
|
local mode="$1"
|
|
local scheme="prefer-dark"
|
|
[[ "$mode" == "light" ]] && scheme="default"
|
|
gsettings set org.gnome.desktop.interface color-scheme "$scheme" 2>/dev/null || \
|
|
dconf write /org/gnome/desktop/interface/color-scheme "'$scheme'" 2>/dev/null || true
|
|
}
|
|
|
|
refresh_gtk() {
|
|
local mode="$1"
|
|
local gtk_css="$CONFIG_DIR/gtk-3.0/gtk.css"
|
|
[[ ! -e "$gtk_css" ]] && return
|
|
local should_run=false
|
|
if [[ -L "$gtk_css" ]]; then
|
|
[[ "$(readlink "$gtk_css")" == *"dank-colors.css"* ]] && should_run=true
|
|
elif grep -q "dank-colors.css" "$gtk_css" 2>/dev/null; then
|
|
should_run=true
|
|
fi
|
|
[[ "$should_run" != "true" ]] && return
|
|
gsettings set org.gnome.desktop.interface gtk-theme "" 2>/dev/null || true
|
|
gsettings set org.gnome.desktop.interface gtk-theme "adw-gtk3-${mode}" 2>/dev/null || true
|
|
}
|
|
|
|
setup_vscode_extension() {
|
|
local cmd="$1" ext_dir="$2" config_dir="$3"
|
|
command -v "$cmd" >/dev/null 2>&1 || return
|
|
[[ ! -d "$config_dir" ]] && return
|
|
local theme_dir="$ext_dir/themes"
|
|
mkdir -p "$theme_dir"
|
|
cp "$SHELL_DIR/matugen/templates/vscode-package.json" "$ext_dir/package.json" 2>/dev/null || true
|
|
cp "$SHELL_DIR/matugen/templates/vscode-vsixmanifest.xml" "$ext_dir/.vsixmanifest" 2>/dev/null || true
|
|
}
|
|
|
|
signal_terminals() {
|
|
pgrep -x kitty >/dev/null 2>&1 && pkill -USR1 kitty
|
|
pgrep -x ghostty >/dev/null 2>&1 && pkill -USR2 ghostty
|
|
}
|
|
|
|
build_once() {
|
|
local json="$1"
|
|
local kind=$(read_json_field "$json" "kind")
|
|
local value=$(read_json_field "$json" "value")
|
|
local mode=$(read_json_field "$json" "mode")
|
|
local mtype=$(read_json_field "$json" "matugenType")
|
|
local run_user=$(read_json_bool "$json" "runUserTemplates")
|
|
local stock_colors=$(read_json_escaped_field "$json" "stockColors")
|
|
|
|
[[ -z "$mtype" ]] && mtype="scheme-tonal-spot"
|
|
[[ -z "$run_user" ]] && run_user="true"
|
|
|
|
local TMP_CFG=$(mktemp)
|
|
trap "rm -f '$TMP_CFG'" RETURN
|
|
|
|
build_merged_config "$mode" "$run_user" "$TMP_CFG"
|
|
|
|
local light_flag=""
|
|
[[ "$mode" == "light" ]] && light_flag="--light"
|
|
|
|
local primary surface dank16_dark dank16_light import_args=()
|
|
|
|
if [[ -n "$stock_colors" ]]; then
|
|
log "Using stock/custom theme colors with matugen base"
|
|
primary=$(echo "$stock_colors" | sed -n 's/.*"primary"[^{]*{[^}]*"dark"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
|
|
surface=$(echo "$stock_colors" | sed -n 's/.*"surface"[^{]*{[^}]*"dark"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
|
|
|
|
[[ -z "$primary" ]] && { err "Failed to extract primary from stock colors"; return 1; }
|
|
|
|
dank16_dark=$(generate_dank16 "$primary" "$surface" "")
|
|
dank16_light=$(generate_dank16 "$primary" "$surface" "--light")
|
|
|
|
local dank16_current
|
|
[[ "$mode" == "light" ]] && dank16_current="$dank16_light" || dank16_current="$dank16_dark"
|
|
[[ "$TERMINALS_ALWAYS_DARK" == "true" && "$mode" == "light" ]] && dank16_current="$dank16_dark"
|
|
|
|
import_args+=(--import-json-string "{\"colors\": $stock_colors, \"dank16\": $dank16_current}")
|
|
|
|
log "Running matugen color hex with stock color overrides"
|
|
if ! matugen color hex "$primary" -m "$mode" -t "${mtype:-scheme-tonal-spot}" -c "$TMP_CFG" "${import_args[@]}"; then
|
|
err "matugen failed"
|
|
return 1
|
|
fi
|
|
else
|
|
log "Using dynamic theme from $kind: $value"
|
|
|
|
local matugen_cmd=("matugen")
|
|
[[ "$kind" == "hex" ]] && matugen_cmd+=("color" "hex") || matugen_cmd+=("$kind")
|
|
matugen_cmd+=("$value")
|
|
|
|
local mat_json
|
|
mat_json=$("${matugen_cmd[@]}" -m dark -t "$mtype" --json hex --dry-run 2>/dev/null | tr -d '\n')
|
|
[[ -z "$mat_json" ]] && { err "matugen dry-run failed"; return 1; }
|
|
|
|
primary=$(echo "$mat_json" | sed -n 's/.*"primary"[[:space:]]*:[[:space:]]*{[^}]*"dark"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
surface=$(echo "$mat_json" | sed -n 's/.*"surface"[[:space:]]*:[[:space:]]*{[^}]*"dark"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
|
|
[[ -z "$primary" ]] && { err "Failed to extract primary color"; return 1; }
|
|
|
|
dank16_dark=$(generate_dank16 "$primary" "$surface" "")
|
|
dank16_light=$(generate_dank16 "$primary" "$surface" "--light")
|
|
|
|
local dank16_current
|
|
[[ "$mode" == "light" ]] && dank16_current="$dank16_light" || dank16_current="$dank16_dark"
|
|
[[ "$TERMINALS_ALWAYS_DARK" == "true" && "$mode" == "light" ]] && dank16_current="$dank16_dark"
|
|
|
|
import_args+=(--import-json-string "{\"dank16\": $dank16_current}")
|
|
|
|
log "Running matugen $kind with dank16 injection"
|
|
if ! "${matugen_cmd[@]}" -m "$mode" -t "$mtype" -c "$TMP_CFG" "${import_args[@]}"; then
|
|
err "matugen failed"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
refresh_gtk "$mode"
|
|
setup_vscode_extension "code" "$HOME/.vscode/extensions/local.dynamic-base16-dankshell-0.0.1" "$HOME/.vscode"
|
|
setup_vscode_extension "codium" "$HOME/.vscode-oss/extensions/local.dynamic-base16-dankshell-0.0.1" "$HOME/.vscode-oss"
|
|
set_system_color_scheme "$mode"
|
|
signal_terminals
|
|
|
|
return 0
|
|
}
|
|
|
|
[[ ! -f "$DESIRED_JSON" ]] && { log "No desired state file"; exit 0; }
|
|
|
|
DESIRED=$(cat "$DESIRED_JSON")
|
|
WANT_KEY=$(compute_key "$DESIRED")
|
|
HAVE_KEY=""
|
|
[[ -f "$BUILT_KEY" ]] && HAVE_KEY=$(cat "$BUILT_KEY" 2>/dev/null || true)
|
|
|
|
[[ "$WANT_KEY" == "$HAVE_KEY" ]] && { log "Already up to date"; exit 0; }
|
|
|
|
log "Building theme (key: ${WANT_KEY:0:12}...)"
|
|
if build_once "$DESIRED"; then
|
|
echo "$WANT_KEY" > "$BUILT_KEY"
|
|
log "Done"
|
|
exit 0
|
|
else
|
|
err "Build failed"
|
|
exit 2
|
|
fi
|