diff --git a/install-flatpaks.sh b/install-flatpaks.sh index 8c6f68e..36b452b 100755 --- a/install-flatpaks.sh +++ b/install-flatpaks.sh @@ -9,7 +9,7 @@ FLATPAKS=( "com.logseq.Logseq" "org.gnome.gitlab.somas.Apostrophe" "org.signal.Signal" - "org.mozilla.Thunderbird" + "org.mozilla.thunderbird_esr" "dev.deedles.Trayscale" "com.vivaldi.Vivaldi" "org.telegram.desktop" diff --git a/migrations/1794160046.sh b/migrations/1794160046.sh new file mode 100644 index 0000000..1e09221 --- /dev/null +++ b/migrations/1794160046.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Flathub retired org.mozilla.Thunderbird in favor of org.mozilla.thunderbird_esr, +# and flatpak update moves existing installs over itself. A skip-packages entry +# for the old ID would no longer keep Thunderbird from being installed, so +# carry it over to the new one. +SKIP_PACKAGES="$HOME/.config/coredesktop/skip-packages" +[ -f "$SKIP_PACKAGES" ] || exit 0 +grep -qE '^org\.mozilla\.Thunderbird([[:space:]]|$)' "$SKIP_PACKAGES" || exit 0 +grep -qE '^org\.mozilla\.thunderbird_esr([[:space:]]|$)' "$SKIP_PACKAGES" && exit 0 +# Start a new line if the file doesn't end with one +[ -n "$(tail -c 1 "$SKIP_PACKAGES")" ] && echo >> "$SKIP_PACKAGES" +echo "org.mozilla.thunderbird_esr" >> "$SKIP_PACKAGES" diff --git a/tests/migrations.bats b/tests/migrations.bats new file mode 100644 index 0000000..ed5557e --- /dev/null +++ b/tests/migrations.bats @@ -0,0 +1,34 @@ +#!/usr/bin/env bats + +load test_helper + +# Migrations that change files in the user's home + +SKIP="$BATS_TEST_TMPDIR/home/.config/coredesktop/skip-packages" +THUNDERBIRD="$REPO/migrations/1794160046.sh" + +skip_list() { + mkdir -p "$(dirname "$SKIP")" + printf "$1" > "$SKIP" +} + +@test "skipping the old Thunderbird ID carries over to the new one" { + skip_list 'foo\norg.mozilla.Thunderbird # no mail' + run bash "$THUNDERBIRD" + [ "$status" -eq 0 ] + [ "$(cat "$SKIP")" = "$(printf 'foo\norg.mozilla.Thunderbird # no mail\norg.mozilla.thunderbird_esr')" ] +} + +@test "the Thunderbird migration leaves other skip lists alone" { + for list in 'org.mozilla.ThunderbirdX\n' 'org.mozilla.Thunderbird\norg.mozilla.thunderbird_esr\n'; do + skip_list "$list" + before="$(cat "$SKIP")" + run bash "$THUNDERBIRD" + [ "$status" -eq 0 ] + [ "$(cat "$SKIP")" = "$before" ] + done + rm -f "$SKIP" + run bash "$THUNDERBIRD" + [ "$status" -eq 0 ] + [ ! -e "$SKIP" ] +} diff --git a/tests/neovim.bats b/tests/neovim.bats new file mode 100644 index 0000000..347cb3c --- /dev/null +++ b/tests/neovim.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load test_helper + +# updates.d/46-neovim.sh, with real git repositories standing in for the +# plugins lazy.nvim cloned + +setup() { + common_setup + export XDG_DATA_HOME="$HOME/.local/share" + LAZY="$XDG_DATA_HOME/nvim/lazy" + mkdir -p "$LAZY" + export GIT_AUTHOR_NAME=test GIT_AUTHOR_EMAIL=test@example.com + export GIT_COMMITTER_NAME=test GIT_COMMITTER_EMAIL=test@example.com + stub nvim 'echo "nvim ran" >> "$BATS_TEST_TMPDIR/nvim.log"' +} + +# plugin NAME: a plugin checkout with one committed file +plugin() { + git init -q "$LAZY/$1" + echo original > "$LAZY/$1/README.md" + git -C "$LAZY/$1" add README.md + git -C "$LAZY/$1" commit -q -m initial +} + +update_neovim() { + source "$REPO/updates.d/46-neovim.sh" + run_update +} + +@test "a plugin with local changes is stashed so lazy.nvim can update it" { + plugin LuaSnip + echo changed > "$LAZY/LuaSnip/README.md" + echo build output > "$LAZY/LuaSnip/untracked.so" + + run update_neovim + [ "$status" -eq 0 ] + [[ "$output" == *"LuaSnip had local changes"* ]] + [ -z "$(git -C "$LAZY/LuaSnip" ls-files -d -m)" ] + [ "$(cat "$LAZY/LuaSnip/README.md")" = original ] + # The changes can be got back, and untracked build output is left alone + git -C "$LAZY/LuaSnip" stash list | grep -q "Stashed by CoreDesktop's update" + [ -f "$LAZY/LuaSnip/untracked.so" ] + grep -q "nvim ran" "$BATS_TEST_TMPDIR/nvim.log" +} + +@test "plugins without local changes are left as they are" { + plugin lazy.nvim + echo build output > "$LAZY/lazy.nvim/untracked.so" + + run update_neovim + [ "$status" -eq 0 ] + [[ "$output" != *"local changes"* ]] + [ -z "$(git -C "$LAZY/lazy.nvim" stash list)" ] +} diff --git a/updates.d/46-neovim.sh b/updates.d/46-neovim.sh index 1081714..d59966d 100755 --- a/updates.d/46-neovim.sh +++ b/updates.d/46-neovim.sh @@ -1,11 +1,29 @@ #!/bin/bash # Only the plugins are updated; the kickstart.nvim config itself is the user's to edit. +LAZY_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/nvim/lazy" + is_installed() { - command -v nvim &>/dev/null && [ -d "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/lazy/lazy.nvim" ] + command -v nvim &>/dev/null && [ -d "$LAZY_DIR/lazy.nvim" ] +} + +# lazy.nvim won't update a plugin whose tracked files differ from its checkout +# (it checks with `git ls-files -d -m`), which an interrupted update can leave +# behind. Stash those changes, so the plugin updates and they can still be +# recovered with `git stash pop` in its folder, and put its submodules back. +restore_plugins() { + local dir + for dir in "$LAZY_DIR"/*/; do + [ -d "$dir/.git" ] || continue + [ -n "$(git -C "$dir" ls-files -d -m 2> /dev/null)" ] || continue + echo " $(basename "$dir") had local changes; stashing them so it can update." + git -C "$dir" stash push -q -m "Stashed by CoreDesktop's update" \ + && git -C "$dir" submodule update -q --init --recursive --force + done } run_update() { echo "Updating Neovim plugins..." + restore_plugins nvim --headless "+Lazy! sync" +qa }