Reinstall a damaged Neovim plugin instead of only stashing its changes
shellcheck / shellcheck (push) Failing after 15s
shellcheck / shellcheck (push) Failing after 15s
Stashing a plugin's mismatched files wasn't enough for LuaSnip: the interrupted update had also left new files git won't overwrite and a half-cloned submodule, so lazy.nvim still couldn't check out the new version, and said nothing. Move such a plugin to ~/.local/state/coredesktop/nvim-plugins/ instead, so Lazy! sync installs it afresh and any edits to it are kept. A plugin the earlier version of this step stashed is moved the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+31
-14
@@ -7,12 +7,13 @@ load test_helper
|
|||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
common_setup
|
common_setup
|
||||||
export XDG_DATA_HOME="$HOME/.local/share"
|
export XDG_DATA_HOME="$HOME/.local/share" XDG_STATE_HOME="$HOME/.local/state"
|
||||||
LAZY="$XDG_DATA_HOME/nvim/lazy"
|
LAZY="$XDG_DATA_HOME/nvim/lazy"
|
||||||
|
BACKUPS="$XDG_STATE_HOME/coredesktop/nvim-plugins"
|
||||||
mkdir -p "$LAZY"
|
mkdir -p "$LAZY"
|
||||||
export GIT_AUTHOR_NAME=test GIT_AUTHOR_EMAIL=test@example.com
|
export GIT_AUTHOR_NAME=test GIT_AUTHOR_EMAIL=test@example.com
|
||||||
export GIT_COMMITTER_NAME=test GIT_COMMITTER_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"'
|
stub nvim
|
||||||
}
|
}
|
||||||
|
|
||||||
# plugin NAME: a plugin checkout with one committed file
|
# plugin NAME: a plugin checkout with one committed file
|
||||||
@@ -28,28 +29,44 @@ update_neovim() {
|
|||||||
run_update
|
run_update
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "a plugin with local changes is stashed so lazy.nvim can update it" {
|
@test "a plugin whose files don't match its checkout is set aside to be installed again" {
|
||||||
plugin LuaSnip
|
plugin LuaSnip
|
||||||
echo changed > "$LAZY/LuaSnip/README.md"
|
echo changed > "$LAZY/LuaSnip/README.md"
|
||||||
echo build output > "$LAZY/LuaSnip/untracked.so"
|
mkdir "$LAZY/LuaSnip/data"
|
||||||
|
echo leftover > "$LAZY/LuaSnip/data/new.md"
|
||||||
|
|
||||||
run update_neovim
|
run update_neovim
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" == *"LuaSnip had local changes"* ]]
|
[[ "$output" == *"LuaSnip's files didn't match its version"* ]]
|
||||||
[ -z "$(git -C "$LAZY/LuaSnip" ls-files -d -m)" ]
|
[ ! -e "$LAZY/LuaSnip" ]
|
||||||
[ "$(cat "$LAZY/LuaSnip/README.md")" = original ]
|
# The old copy, edits and all, is kept
|
||||||
# The changes can be got back, and untracked build output is left alone
|
copies=("$BACKUPS"/LuaSnip-*)
|
||||||
git -C "$LAZY/LuaSnip" stash list | grep -q "Stashed by CoreDesktop's update"
|
[ "${#copies[@]}" -eq 1 ]
|
||||||
[ -f "$LAZY/LuaSnip/untracked.so" ]
|
[ "$(cat "${copies[0]}/README.md")" = changed ]
|
||||||
grep -q "nvim ran" "$BATS_TEST_TMPDIR/nvim.log"
|
[ -f "${copies[0]}/data/new.md" ]
|
||||||
|
called nvim --headless "+Lazy! sync" +qa
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "plugins without local changes are left as they are" {
|
@test "a plugin an earlier update only stashed is set aside too" {
|
||||||
|
plugin LuaSnip
|
||||||
|
echo changed > "$LAZY/LuaSnip/README.md"
|
||||||
|
git -C "$LAZY/LuaSnip" stash push -q -m "Stashed by CoreDesktop's update"
|
||||||
|
|
||||||
|
run update_neovim
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ ! -e "$LAZY/LuaSnip" ]
|
||||||
|
[ -d "$(echo "$BACKUPS"/LuaSnip-*)" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "plugins that match their checkout are left as they are" {
|
||||||
plugin lazy.nvim
|
plugin lazy.nvim
|
||||||
echo build output > "$LAZY/lazy.nvim/untracked.so"
|
echo build output > "$LAZY/lazy.nvim/untracked.so"
|
||||||
|
echo changed > "$LAZY/lazy.nvim/README.md"
|
||||||
|
git -C "$LAZY/lazy.nvim" stash push -q -m "the user's own stash"
|
||||||
|
|
||||||
run update_neovim
|
run update_neovim
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" != *"local changes"* ]]
|
[[ "$output" != *"didn't match"* ]]
|
||||||
[ -z "$(git -C "$LAZY/lazy.nvim" stash list)" ]
|
[ -f "$LAZY/lazy.nvim/untracked.so" ]
|
||||||
|
[ ! -e "$BACKUPS" ]
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-10
@@ -2,28 +2,36 @@
|
|||||||
|
|
||||||
# Only the plugins are updated; the kickstart.nvim config itself is the user's to edit.
|
# 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"
|
LAZY_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/nvim/lazy"
|
||||||
|
PLUGIN_BACKUPS="${XDG_STATE_HOME:-$HOME/.local/state}/coredesktop/nvim-plugins"
|
||||||
|
|
||||||
is_installed() {
|
is_installed() {
|
||||||
command -v nvim &>/dev/null && [ -d "$LAZY_DIR/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
|
# 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
|
# (it checks with `git ls-files -d -m`). An interrupted update can leave a
|
||||||
# behind. Stash those changes, so the plugin updates and they can still be
|
# plugin like that, along with leftovers git won't overwrite, such as new files
|
||||||
# recovered with `git stash pop` in its folder, and put its submodules back.
|
# and half-cloned submodules (LuaSnip, 2026-10-20). Move such a plugin out of
|
||||||
restore_plugins() {
|
# the way, so `Lazy! sync` installs it afresh; any edits made to it are in the
|
||||||
local dir
|
# copy. So is a plugin an earlier version of this step only stashed.
|
||||||
|
set_aside_broken_plugins() {
|
||||||
|
local dir name dest
|
||||||
for dir in "$LAZY_DIR"/*/; do
|
for dir in "$LAZY_DIR"/*/; do
|
||||||
|
dir="${dir%/}"
|
||||||
[ -d "$dir/.git" ] || continue
|
[ -d "$dir/.git" ] || continue
|
||||||
[ -n "$(git -C "$dir" ls-files -d -m 2> /dev/null)" ] || continue
|
if [ -z "$(git -C "$dir" ls-files -d -m 2> /dev/null)" ] \
|
||||||
echo " $(basename "$dir") had local changes; stashing them so it can update."
|
&& ! git -C "$dir" stash list 2> /dev/null | grep -q "Stashed by CoreDesktop's update"; then
|
||||||
git -C "$dir" stash push -q -m "Stashed by CoreDesktop's update" \
|
continue
|
||||||
&& git -C "$dir" submodule update -q --init --recursive --force
|
fi
|
||||||
|
name="$(basename "$dir")"
|
||||||
|
dest="$PLUGIN_BACKUPS/$name-$(date +%Y-%m-%d-%H%M%S)"
|
||||||
|
mkdir -p "$PLUGIN_BACKUPS" && mv "$dir" "$dest" \
|
||||||
|
&& echo " $name's files didn't match its version, so it will be installed again. The old copy is in $dest"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
run_update() {
|
run_update() {
|
||||||
echo "Updating Neovim plugins..."
|
echo "Updating Neovim plugins..."
|
||||||
restore_plugins
|
set_aside_broken_plugins
|
||||||
nvim --headless "+Lazy! sync" +qa
|
nvim --headless "+Lazy! sync" +qa
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user