fix update

This commit is contained in:
2026-10-19 13:56:54 -06:00
parent a15eac4240
commit a65f07c22e
21 changed files with 241 additions and 64 deletions
+1
View File
@@ -0,0 +1 @@
gnome/.gnome-settings.md5
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
export SSH_AUTH_SOCK="$HOME/.bitwarden-ssh-agent.sock"
LINE='export SSH_AUTH_SOCK="$HOME/.bitwarden-ssh-agent.sock"'
if grep -qF "$LINE" ~/.bashrc; then
echo "Bitwarden SSH agent already configured in .bashrc"
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
#
# Purpose : Apply gnome-settings.dconf only if it has changed since last applied
# (tracked via an MD5 checksum so user tweaks aren't overwritten every run)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
SRC="$SCRIPT_DIR/gnome-settings.dconf"
CHECKSUM_FILE="$SCRIPT_DIR/.gnome-settings.md5"
if [ ! -f "$SRC" ]; then
echo "Error: $SRC not found."
exit 1
fi
CURRENT_SUM=$(md5sum "$SRC" | awk '{print $1}')
STORED_SUM=$(cat "$CHECKSUM_FILE" 2>/dev/null)
if [ "$CURRENT_SUM" != "$STORED_SUM" ]; then
echo "GNOME settings have changed, applying..."
dconf load /org/gnome/shell/extensions/ < "$SRC"
echo "$CURRENT_SUM" > "$CHECKSUM_FILE"
else
echo "GNOME settings unchanged, skipping."
fi
-1
View File
@@ -2,6 +2,5 @@
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
gsettings set org.gnome.desktop.interface gtk-theme "Adwaita-dark"
echo "setting wallpaper to ${SCRIPT_DIR}/wallpaper.jpeg"
gsettings set org.gnome.desktop.background picture-uri-dark "file://${SCRIPT_DIR}/wallpaper.jpeg"
gsettings set org.gnome.desktop.background picture-options 'zoom'
+2 -36
View File
@@ -105,9 +105,6 @@ install_packages "${MAINTENANCE[@]}"
echo "Installing desktop environment..."
install_packages "${DESKTOP[@]}"
echo "Installing office packages..."
install_packages "${OFFICE[@]}"
echo "Installing media packages..."
install_packages "${MEDIA[@]}"
@@ -117,14 +114,7 @@ install_packages "${FONTS[@]}"
# Enable all systemd services listed in SERVICES array, then register the SSH
# Avahi service so the machine is discoverable over mDNS
echo "Configuring services..."
for service in "${SERVICES[@]}"; do
if ! systemctl is-enabled "$service" &> /dev/null; then
echo "Enabling $service..."
sudo systemctl enable "$service"
else
echo "$service is already enabled."
fi
done
enable_services "${SERVICES[@]}"
sudo cp /usr/share/doc/avahi/ssh.service /etc/avahi/services/
cd ~/.local/share/coredesktop
@@ -178,31 +168,7 @@ if ! systemctl is-active tailscaled &> /dev/null; then
fi
# Apply GNOME dconf settings only if the settings file has changed since last run
# (tracked via an MD5 checksum to avoid redundant writes)
SRC="$HOME/.local/share/coredesktop/gnome/gnome-settings.dconf"
CHECKSUM_FILE="$HOME/.local/share/coredesktop/gnome/.gnome-settings.md5"
if [ ! -f "$SRC" ]; then
echo "Error: $SRC not found, exiting."
exit 1
fi
CURRENT_SUM=$(md5sum "$SRC" | awk '{print $1}')
if [ -f "$CHECKSUM_FILE" ]; then
STORED_SUM=$(cat "$CHECKSUM_FILE")
else
STORED_SUM=""
fi
if [ "$CURRENT_SUM" != "$STORED_SUM" ]; then
echo "GNOME settings have changed, applying..."
dconf load /org/gnome/shell/extensions/ < "$SRC"
echo "$CURRENT_SUM" > "$CHECKSUM_FILE"
echo "Done."
else
echo "GNOME settings unchanged, skipping."
fi
bash ~/.local/share/coredesktop/gnome/apply-gnome-settings.sh
# Fix mDNS configuration if systemd-resolved is managing DNS on this system
if systemctl is-enabled systemd-resolved.service &> /dev/null; then
+2
View File
@@ -96,6 +96,7 @@ MAINTENANCE=(
gnome-disk-utility
gnome-extra
gnome-keyring
pacman-contrib
)
# Desktop environment
@@ -134,6 +135,7 @@ SERVICES=(
avahi-daemon.service
bluetooth.service
cups.service
fwupd-refresh.timer
gdm.service
NetworkManager.service
sshd.service
+25 -11
View File
@@ -12,10 +12,12 @@ during its own install step.
When a user runs `update`:
1. The coredesktop repo at `~/.local/share/coredesktop` is pulled.
2. All `*.sh` files in `updates.d/` are **sourced** (not executed as subprocesses)
2. All `*.sh` files in `updates.d/` are **sourced**, each in its own subshell,
in lexicographic order.
3. Each script runs in the same shell context, with access to `$COREDESKTOP` and
anything sourced before it (e.g. `utils.sh`).
3. Each script can see `$COREDESKTOP`, but nothing defined by earlier hooks —
source `utils.sh` yourself if you need its helpers. A `cd`, `set -e` or `exit`
in one hook can't affect the others.
4. A hook that exits non-zero is listed in the summary at the end of `update`.
Because the scripts are sourced from within the cloned repo directory, any file
placed there by a sibling project's installer will **survive `git pull`** — git
@@ -26,16 +28,27 @@ does not delete untracked files on pull.
Existing coredesktop hooks use a numeric prefix to control execution order:
| File | Purpose |
|------------------|---------------------|
|---------------------------|-----------------------------------------|
| `00-rename-migration.sh` | Legacy command renames |
| `10-pacman.sh` | Arch system update |
| `15-services.sh` | Enable new systemd services |
| `20-aur.sh` | AUR packages |
| `30-flatpak.sh` | Flatpak apps |
| `40-ruby.sh` | Ruby/gems |
| `50-bitwarden.sh`| Bitwarden CLI |
| `40-ruby.sh` | mise, Ruby/gems |
| `45-tmux.sh` | TPM and tmux plugins |
| `46-neovim.sh` | Neovim plugins |
| `50-bitwarden.sh` | Bitwarden SSH agent |
| `60-pipx.sh` | pipx packages |
| `65-migrate.sh` | Migrate backup tool |
| `70-claude.sh` | Claude Code setup |
| `80-gnome-extensions.sh` | GNOME extensions |
| `85-gnome-settings.sh` | GNOME extension settings |
| `90-firmware.sh` | Firmware update check |
| `95-cleanup.sh` | Flatpak/pacman cache cleanup |
| `99-reboot-check.sh` | Reboot-needed notice |
Sibling projects should use **70 or higher** to run after all coredesktop
updates complete.
Sibling projects should use an unused number from **71–79** so they run after
the core updates but before coredesktop's end-of-run hooks (80+).
## What to Add to a Sibling Project
@@ -68,8 +81,9 @@ run on the machine.
## Available Helpers
Since hooks are sourced in the same shell, they can use any function or variable
already defined by earlier scripts. The most useful are in `utils.sh`:
Hooks don't inherit functions from earlier hooks, so source `utils.sh` for its
helpers. Do this before defining your own `is_installed`, because `utils.sh` has
a pacman-specific function with the same name:
```bash
source "$COREDESKTOP/utils.sh"
@@ -86,5 +100,5 @@ remove_packages "${MY_REMOVE_PACKAGES[@]}"
- [ ] Create `updates.d/7X-<project>.sh` in the sibling repo
- [ ] Hook script echoes its name so progress is visible during `update`
- [ ] Install step copies the hook to `~/.local/share/coredesktop/updates.d/`
- [ ] Numeric prefix is 70+ (does not conflict with coredesktop's own hooks)
- [ ] Numeric prefix is an unused number in 71–79
- [ ] Script is idempotent — safe to run multiple times without side effects
+22 -5
View File
@@ -23,18 +23,28 @@ print_logo
COREDESKTOP="$HOME/.local/share/coredesktop"
echo "Updating CoreDesktop..."
git -C "$COREDESKTOP" pull
if [[ -z "$UPDATE_REEXECED" ]] && ! git -C "$COREDESKTOP" pull; then
echo "WARNING: could not pull the latest CoreDesktop; running the update hooks already on disk."
export UPDATE_PULL_FAILED=1
fi
mkdir -p "$COREDESKTOP/updates.d"
sudo cp "$COREDESKTOP/update" ~/.local/bin/update
sudo cp "$COREDESKTOP/refresh" ~/.local/bin/refresh
# --remove-destination replaces copies left root-owned by older versions of this script
cp --remove-destination "$COREDESKTOP/update" ~/.local/bin/update
cp --remove-destination "$COREDESKTOP/refresh" ~/.local/bin/refresh
if [[ -z "$UPDATE_REEXECED" ]]; then
export UPDATE_REEXECED=1
exec ~/.local/bin/update
fi
FAILED=()
[[ -n "$UPDATE_PULL_FAILED" ]] && FAILED+=("git pull")
# Each hook runs in its own subshell so a cd, set -e, exit, or stray variable
# in one hook can't leak into or abort the hooks after it.
for plugin in "$COREDESKTOP/updates.d/"*.sh; do
if [ -f "$plugin" ]; then
[ -f "$plugin" ] || continue
(
unset -f is_installed run_update
source "$plugin"
if declare -f run_update > /dev/null; then
@@ -42,7 +52,14 @@ for plugin in "$COREDESKTOP/updates.d/"*.sh; do
run_update
fi
fi
fi
)
# Checked separately: under `( ... ) ||`, bash would ignore set -e inside the hook
[ $? -eq 0 ] || FAILED+=("$(basename "$plugin")")
done
if (( ${#FAILED[@]} > 0 )); then
echo "Done, with errors in: ${FAILED[*]}"
exit 1
fi
echo "Done."
+2 -2
View File
@@ -4,12 +4,12 @@ COREDESKTOP="$HOME/.local/share/coredesktop"
if [ -f ~/.local/bin/coreupdate ]; then
echo "Migrating coreupdate -> update..."
sudo cp "$COREDESKTOP/update" ~/.local/bin/update
cp --remove-destination "$COREDESKTOP/update" ~/.local/bin/update
sudo rm -f ~/.local/bin/coreupdate
fi
if [ -f ~/.local/bin/corerefresh ]; then
echo "Migrating corerefresh -> refresh..."
sudo cp "$COREDESKTOP/refresh" ~/.local/bin/refresh
cp --remove-destination "$COREDESKTOP/refresh" ~/.local/bin/refresh
sudo rm -f ~/.local/bin/corerefresh
fi
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
COREDESKTOP="$HOME/.local/share/coredesktop"
source "$COREDESKTOP/utils.sh"
source "$COREDESKTOP/packages.conf"
echo "Checking for new services..."
enable_services "${SERVICES[@]}"
+3
View File
@@ -1,5 +1,8 @@
#!/bin/bash
echo "Updating mise..."
mise self-update -y
echo "Updating Ruby and Rails..."
mise upgrade --bump ruby
mise reshim
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
is_installed() {
[ -d "$HOME/.tmux/plugins/tpm" ]
}
run_update() {
echo "Updating TPM and tmux plugins..."
local failed=0
for plugin in "$HOME/.tmux/plugins/"*/; do
[ -d "$plugin/.git" ] || continue
echo " $(basename "$plugin")"
git -C "$plugin" pull --ff-only --quiet || failed=1
done
return $failed
}
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
# Only the plugins are updated; the kickstart.nvim config itself is the user's to edit.
is_installed() {
command -v nvim &>/dev/null && [ -d "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/lazy/lazy.nvim" ]
}
run_update() {
echo "Updating Neovim plugins..."
nvim --headless "+Lazy! sync" +qa
}
+16 -2
View File
@@ -1,4 +1,18 @@
#!/bin/bash
echo "Updating pipx applications..."
pipx upgrade-all
# pipx venvs are tied to the Python they were built with, so a Python upgrade
# breaks them in a way `pipx upgrade-all` can't repair. Rebuild them when the
# Python version changes, or when an upgrade fails.
STAMP="$HOME/.local/state/coredesktop/pipx-python-version"
CURRENT_PYTHON="$(python3 -c 'import sys; print("%d.%d" % sys.version_info[:2])')"
if [ "$(cat "$STAMP" 2>/dev/null)" != "$CURRENT_PYTHON" ]; then
echo "Python changed to $CURRENT_PYTHON, reinstalling pipx applications..."
pipx reinstall-all
else
echo "Updating pipx applications..."
if ! pipx upgrade-all; then
echo "pipx upgrade-all failed, reinstalling pipx applications..."
pipx reinstall-all
fi
fi && mkdir -p "$(dirname "$STAMP")" && echo "$CURRENT_PYTHON" > "$STAMP"
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
is_installed() {
[ -f "$HOME/.local/bin/migrate" ]
}
run_update() {
echo "Updating Migrate..."
local tmp
tmp="$(mktemp)"
if curl -fsSL -o "$tmp" https://github.com/CyphrRiot/Migrate/raw/main/bin/migrate && [ -s "$tmp" ]; then
chmod +x "$tmp"
mv "$tmp" "$HOME/.local/bin/migrate"
else
rm -f "$tmp"
echo "Could not download Migrate; keeping the current version."
return 1
fi
}
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
is_installed() {
command -v gnome-shell &>/dev/null
}
run_update() {
echo "Updating GNOME extensions..."
# Reinstall gext if missing or broken (e.g. its pipx venv went stale after a Python upgrade)
if ! ~/.local/bin/gext --version &> /dev/null; then
echo "gext missing or broken, reinstalling..."
pipx uninstall gnome-extensions-cli 2>/dev/null || true
pipx install --python "$(which python3)" gnome-extensions-cli --system-site-packages
fi
# Update every enabled user extension to the latest version for this GNOME Shell.
# The filesystem backend writes directly to ~/.local/share/gnome-shell/extensions;
# GNOME Shell picks up the new code at next login.
if ~/.local/bin/gext --filesystem update --user --yes; then
echo "GNOME extensions up to date. Log out and back in to load any updated extensions."
else
echo "gext update failed; GNOME extensions were not updated."
fi
}
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
COREDESKTOP="$HOME/.local/share/coredesktop"
is_installed() {
command -v dconf &>/dev/null
}
run_update() {
bash "$COREDESKTOP/gnome/apply-gnome-settings.sh"
}
+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash
# Firmware updates often need a reboot, so this only reports what's available.
is_installed() {
command -v fwupdmgr &>/dev/null
}
run_update() {
echo "Checking for firmware updates..."
fwupdmgr refresh &>/dev/null
# get-updates exits 2 when there is nothing to update
if fwupdmgr get-updates --no-unreported-check 2>/dev/null; then
echo "Firmware updates are available. Run 'fwupdmgr update' to install them."
else
echo "No firmware updates available."
fi
return 0
}
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
echo "Removing unused Flatpak runtimes..."
flatpak uninstall --unused -y --noninteractive
if command -v paccache &>/dev/null; then
echo "Trimming pacman package cache..."
sudo paccache -rk2
sudo paccache -ruk0
fi
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
# If the running kernel's modules are gone, a newer kernel was installed
if [ ! -d "/usr/lib/modules/$(uname -r)" ]; then
echo "A newer kernel has been installed. Please reboot when convenient."
fi
+12
View File
@@ -60,3 +60,15 @@ remove_flatpaks() {
flatpak uninstall --noninteractive "${to_remove[@]}"
fi
}
# Function to enable systemd services if not already enabled
enable_services() {
for service in "$@"; do
if ! systemctl is-enabled "$service" &> /dev/null; then
echo "Enabling $service..."
sudo systemctl enable "$service"
else
echo "$service is already enabled."
fi
done
}