Add DMS configuration and helper scripts

- Introduced a new `justfile` for managing DMS-related tasks, including a recipe for syncing live DMS configuration.
- Added a `devshell.nix` file to set up a development environment with necessary packages and shell hooks for DMS.
- Updated DMS settings to replace `defaultSettingsFile` with `defaultSeedDir` for improved configuration management.
- Created a new script `sync-seed.sh` to facilitate syncing DMS settings from the live configuration to host-specific directories.
- Enhanced documentation and examples for DMS configuration and usage.
This commit is contained in:
2026-06-21 04:45:30 -03:00
parent 4ca225ed60
commit 8b66fa8665
10 changed files with 484 additions and 51 deletions
@@ -1,6 +1,8 @@
# Generic defaults written once to ~/.config/DankMaterialShell/settings.json on first login.
# Hosts can override via `chiasson.desktop.shells.dms.defaultSettingsFile` (see 14900k).
# Hosts can override via `chiasson.desktop.shells.dms.defaultSeedDir` (see 14900k).
# After seeding, DMS settings are owned by the UI — rebuilds do not overwrite them.
#
# To refresh host seeds from live DMS config: `just sync-dms`
{
lib,
gpuTempEnabled ? true,
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env bash
# Sync live DMS config into modules/hosts/<host>/_private/dms-defaults/ (see defaultSeedDir).
set -euo pipefail
usage() {
cat <<EOF
Usage: $(basename "$0") [options] [host]
Copy ~/.config/DankMaterialShell/{settings,plugin_settings}.json into the
host seed directory (pretty-printed). Host defaults to this machine's hostname.
Options:
--settings-only Skip plugin_settings.json
-n, --dry-run Preview without writing
-h, --help
Examples:
just sync-dms
$(basename "$0") --dry-run ideapad
EOF
}
find_repo_root() {
local dir="${1:-$PWD}"
while [[ "$dir" != "/" ]]; do
if [[ -f "$dir/flake.nix" && -d "$dir/modules/hosts" ]]; then
printf '%s\n' "$dir"
return 0
fi
dir="$(dirname "$dir")"
done
return 1
}
resolve_host_module() {
local hn="$1" repo_root="$2"
local hosts_dir="${repo_root}/modules/hosts" dir name
if [[ -d "${hosts_dir}/${hn}/_private" ]]; then
printf '%s' "$hn"
return 0
fi
for dir in "${hosts_dir}"/*/; do
name="$(basename "$dir")"
[[ -f "${dir}configuration.nix" ]] \
&& grep -qF "hostName = \"${hn}\";" "${dir}configuration.nix" \
&& { printf '%s' "$name"; return 0; }
done
echo "error: no host module for hostname '${hn}' (pass module name explicitly)" >&2
return 1
}
sync_json() {
local source="$1" dest="$2" label="$3"
[[ -f "$source" ]] || { echo "skip: $label not found" >&2; return 0; }
jq empty "$source"
if [[ "$DRY_RUN" -eq 1 ]]; then
echo " $source -> $dest"
return 0
fi
local tmp
tmp="$(mktemp)"
jq . "$source" >"$tmp"
mv "$tmp" "$dest"
echo "Updated $dest"
UPDATED+=("$dest")
}
DRY_RUN=0
SETTINGS_ONLY=0
HOST=""
UPDATED=()
while [[ $# -gt 0 ]]; do
case "$1" in
-n | --dry-run) DRY_RUN=1; shift ;;
--settings-only) SETTINGS_ONLY=1; shift ;;
-h | --help) usage; exit 0 ;;
-*) echo "error: unknown option: $1" >&2; usage >&2; exit 1 ;;
*) HOST="$1"; shift ;;
esac
done
REPO_ROOT="${CHIASSON_NIX_ROOT:-$(find_repo_root "$PWD" || true)}"
[[ -n "$REPO_ROOT" ]] || { echo "error: run from chiasson-nix repo root" >&2; exit 1; }
command -v jq >/dev/null || { echo "error: jq required" >&2; exit 1; }
if [[ -z "$HOST" ]]; then
SYSTEM_HOSTNAME="$(hostname -s 2>/dev/null || hostname)"
HOST="$(resolve_host_module "$SYSTEM_HOSTNAME" "$REPO_ROOT")"
[[ "$HOST" == "$SYSTEM_HOSTNAME" ]] \
&& echo "Using host module: $HOST" \
|| echo "Using host module: $HOST (hostname: $SYSTEM_HOSTNAME)"
fi
HOST_PRIVATE="${REPO_ROOT}/modules/hosts/${HOST}/_private"
SEED_DIR="${HOST_PRIVATE}/dms-defaults"
DMS_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/DankMaterialShell"
[[ -d "$HOST_PRIVATE" ]] || { echo "error: missing $HOST_PRIVATE" >&2; exit 1; }
[[ -f "${DMS_CONFIG}/settings.json" ]] || {
echo "error: missing ${DMS_CONFIG}/settings.json" >&2
exit 1
}
[[ "$DRY_RUN" -eq 1 ]] && echo "Would sync into $SEED_DIR:"
[[ "$DRY_RUN" -eq 0 ]] && mkdir -p "$SEED_DIR"
sync_json "${DMS_CONFIG}/settings.json" "${SEED_DIR}/settings.json" settings.json
[[ "$SETTINGS_ONLY" -eq 0 ]] \
&& sync_json "${DMS_CONFIG}/plugin_settings.json" "${SEED_DIR}/plugin_settings.json" plugin_settings.json
[[ "$DRY_RUN" -eq 1 || ${#UPDATED[@]} -eq 0 ]] && exit 0
git -C "$REPO_ROOT" diff --stat -- "${UPDATED[@]}" 2>/dev/null || true
+6 -5
View File
@@ -38,13 +38,15 @@
example = [ "sudo" "nixos-rebuild" "switch" "--flake" ".#14900k" ];
description = "Command used by DMS nix-monitor widget for rebuild actions.";
};
defaultSettingsFile = lib.mkOption {
defaultSeedDir = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = ./dms-default-settings.json;
example = ./dms-defaults;
description = ''
Host-specific first-run `settings.json` seed. When set, replaces the bundled
`default-settings.nix` template on fresh profiles.
Host-specific first-run DMS config seed directory. When set, copies
`settings.json` (required) and `plugin_settings.json` (optional) from this
directory into `~/.config/DankMaterialShell/` on fresh profiles.
Replaces the bundled `default-settings.nix` template for `settings.json`.
'';
};
bundleThirdPartyPlugins = lib.mkOption {
@@ -101,7 +103,6 @@
])
++ (cfg.extraRightBarWidgets or [ ]);
programs.nix-monitor.rebuildCommand = rebuildCommand;
dms.defaultSettingsFile = cfg.defaultSettingsFile or null;
dms.bundleThirdPartyPlugins = cfg.bundleThirdPartyPlugins or true;
};
};
@@ -59,16 +59,26 @@
'';
jsonFormat = pkgs.formats.json { };
dmsSeedSettings =
if cfg.defaultSettingsFile != null then
builtins.fromJSON (builtins.readFile cfg.defaultSettingsFile)
dmsConfigDir = "${config.xdg.configHome}/DankMaterialShell";
defaultSeedDir = lib.attrByPath [ "chiasson" "desktop" "shells" "dms" "defaultSeedDir" ] null osConfig;
dmsSeedSources =
if defaultSeedDir != null then
{
"settings.json" = defaultSeedDir + "/settings.json";
}
// lib.optionalAttrs (builtins.pathExists (defaultSeedDir + "/plugin_settings.json")) {
"plugin_settings.json" = defaultSeedDir + "/plugin_settings.json";
}
else
import ../_private/default-settings.nix {
inherit lib gpuTempEnabled;
extraRightBarWidgets = cfg.extraRightBarWidgets;
{
"settings.json" = jsonFormat.generate "dms-settings-seed.json" (
import ../_private/default-settings.nix {
inherit lib gpuTempEnabled;
extraRightBarWidgets = cfg.extraRightBarWidgets;
}
);
};
dmsSeedFile = jsonFormat.generate "dms-settings-seed.json" dmsSeedSettings;
dmsSettingsPath = "${config.xdg.configHome}/DankMaterialShell/settings.json";
# Directory name must match each plugin's `id` in plugin.json.
thirdPartyPlugins = {
@@ -158,15 +168,6 @@ in {
Ship rbw-lock-toggle into `~/.config/DankMaterialShell/plugins/rbwLockToggle/` (directory name matches plugin id; Bitwarden vault lock/unlock in the bar).
'';
dms.defaultSettingsFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Host-specific first-run `settings.json` seed. When set, replaces the bundled
`default-settings.nix` template on fresh profiles.
'';
};
dms.bundleThirdPartyPlugins = lib.mkOption {
type = lib.types.bool;
default = true;
@@ -270,22 +271,25 @@ in {
session = { };
};
# Detach store symlink so UI edits survive rebuilds; seed defaults only on a fresh profile.
home.activation.dmsMaterializeSettings = lib.hm.dag.entryBefore [ "writeBoundary" ] ''
settingsFile=${lib.escapeShellArg dmsSettingsPath}
if [ -L "$settingsFile" ]; then
mkdir -p "$(dirname "$settingsFile")"
${pkgs.coreutils}/bin/cp --remove-destination -L "$settingsFile" "$settingsFile"
fi
'';
home.activation.dmsSeedSettings = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
settingsFile=${lib.escapeShellArg dmsSettingsPath}
mkdir -p "$(dirname "$settingsFile")"
if [ ! -e "$settingsFile" ]; then
${pkgs.coreutils}/bin/cp ${lib.escapeShellArg dmsSeedFile} "$settingsFile"
chmod u+w "$settingsFile"
fi
# Detach store symlinks so UI edits survive rebuilds; seed defaults only on a fresh profile.
home.activation.dmsSeedConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
${lib.concatMapStringsSep "\n" (
fileName:
let
dest = "${dmsConfigDir}/${fileName}";
src = dmsSeedSources.${fileName};
in ''
dest=${lib.escapeShellArg dest}
mkdir -p "$(dirname "$dest")"
if [ -L "$dest" ]; then
${pkgs.coreutils}/bin/cp --remove-destination -L "$dest" "$dest"
fi
if [ ! -e "$dest" ]; then
${pkgs.coreutils}/bin/cp ${lib.escapeShellArg src} "$dest"
chmod u+w "$dest"
fi
''
) (lib.attrNames dmsSeedSources)}
'';
# matugen won't create missing output_path parents; run before DMS theme generation.