mirror of
https://oauth2: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@github.com/m1ngsama/chopsticks.git
synced 2026-05-10 19:10:59 +08:00
Add bootstrap dry-run safety checks
This commit is contained in:
parent
ddb4c691b9
commit
1b9e8b3999
5 changed files with 80 additions and 7 deletions
23
.github/workflows/test.yml
vendored
23
.github/workflows/test.yml
vendored
|
|
@ -180,6 +180,29 @@ jobs:
|
||||||
XDG_CONFIG_HOME=/tmp/chopsticks-default ./install.sh --configure-only --yes
|
XDG_CONFIG_HOME=/tmp/chopsticks-default ./install.sh --configure-only --yes
|
||||||
grep -q "let g:chopsticks_profile = 'engineer'" /tmp/chopsticks-default/chopsticks.vim
|
grep -q "let g:chopsticks_profile = 'engineer'" /tmp/chopsticks-default/chopsticks.vim
|
||||||
|
|
||||||
|
- name: Verify bootstrap dry-run safety
|
||||||
|
run: |
|
||||||
|
CHOPSTICKS_DEST=/tmp/chopsticks-bootstrap ./get.sh --dry-run --profile=minimal \
|
||||||
|
| tee /tmp/chopsticks-get-dry-run.txt
|
||||||
|
grep -q 'Would clone' /tmp/chopsticks-get-dry-run.txt
|
||||||
|
test ! -e /tmp/chopsticks-bootstrap
|
||||||
|
|
||||||
|
mkdir -p /tmp/not-chopsticks
|
||||||
|
git init /tmp/not-chopsticks
|
||||||
|
git -C /tmp/not-chopsticks remote add origin https://github.com/example/not-chopsticks.git
|
||||||
|
if CHOPSTICKS_DEST=/tmp/not-chopsticks ./get.sh --dry-run; then
|
||||||
|
echo "Expected get.sh to reject non-chopsticks repo"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /tmp/chopsticks-existing
|
||||||
|
git init /tmp/chopsticks-existing
|
||||||
|
git -C /tmp/chopsticks-existing remote add origin https://github.com/m1ngsama/chopsticks.git
|
||||||
|
touch /tmp/chopsticks-existing/install.sh /tmp/chopsticks-existing/.vimrc
|
||||||
|
CHOPSTICKS_DEST=/tmp/chopsticks-existing ./get.sh --dry-run --yes \
|
||||||
|
| tee /tmp/chopsticks-get-existing.txt
|
||||||
|
grep -q 'Would update existing chopsticks repo' /tmp/chopsticks-get-existing.txt
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
- `install.sh --profile=minimal|engineer|full` for scripted profile selection
|
- `install.sh --profile=minimal|engineer|full` for scripted profile selection
|
||||||
- `install.sh --dry-run` to show the resolved profile/config path without writes
|
- `install.sh --dry-run` to show the resolved profile/config path without writes
|
||||||
- `install.sh --configure-only` to update local profile config without reinstalling
|
- `install.sh --configure-only` to update local profile config without reinstalling
|
||||||
|
- `get.sh --dry-run` for safe bootstrap previews before clone/update/install
|
||||||
|
- `CHOPSTICKS_DEST=/absolute/path` to test or install the bootstrap target elsewhere
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
@ -53,6 +55,7 @@
|
||||||
- tmux integration is written as a managed block so future installer runs can
|
- tmux integration is written as a managed block so future installer runs can
|
||||||
update it without appending duplicate bindings
|
update it without appending duplicate bindings
|
||||||
- Installer cleanup now restores the cursor after interrupted checkbox menus
|
- Installer cleanup now restores the cursor after interrupted checkbox menus
|
||||||
|
- Bootstrap dry-run now refuses unrelated existing git repos before any writes
|
||||||
- Skip 2 more built-in plugins: openPlugin, manpager (10 → 12 total)
|
- Skip 2 more built-in plugins: openPlugin, manpager (10 → 12 total)
|
||||||
- Remove deprecated `set ttyfast` (no-op since Vim 8)
|
- Remove deprecated `set ttyfast` (no-op since Vim 8)
|
||||||
- Add `grepprg=rg --vimgrep` — `:grep` now uses ripgrep + quickfix
|
- Add `grepprg=rg --vimgrep` — `:grep` now uses ripgrep + quickfix
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ Five minutes from zero to a working Vim setup.
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --profile=minimal
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --profile=minimal
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --dry-run --profile=full
|
||||||
```
|
```
|
||||||
|
|
||||||
Open vim. First launch auto-installs plugins — **wait 30-60s, don't close vim**. Restart when done.
|
Open vim. First launch auto-installs plugins — **wait 30-60s, don't close vim**. Restart when done.
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ chopsticks gives you a production-ready Vim config in one command. Pure VimScrip
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --profile=minimal
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --profile=minimal
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --dry-run --profile=full
|
||||||
```
|
```
|
||||||
|
|
||||||
Or manually:
|
Or manually:
|
||||||
|
|
@ -60,6 +61,8 @@ cd ~/.vim && ./install.sh --profile=engineer
|
||||||
```
|
```
|
||||||
|
|
||||||
Supports macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
|
Supports macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
|
||||||
|
Set `CHOPSTICKS_DEST=/absolute/path` before running `get.sh` to install
|
||||||
|
somewhere other than `~/.vim`.
|
||||||
|
|
||||||
First launch installs plugins automatically (30-60s). Restart vim when done.
|
First launch installs plugins automatically (30-60s). Restart vim when done.
|
||||||
Use `./install.sh --dry-run --profile=full` to inspect the resolved profile and
|
Use `./install.sh --dry-run --profile=full` to inspect the resolved profile and
|
||||||
|
|
|
||||||
57
get.sh
Normal file → Executable file
57
get.sh
Normal file → Executable file
|
|
@ -4,11 +4,37 @@
|
||||||
# Usage:
|
# Usage:
|
||||||
# curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
# curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
# curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes
|
# curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes
|
||||||
|
# CHOPSTICKS_DEST=/absolute/path bash get.sh --dry-run
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
REPO="https://github.com/m1ngsama/chopsticks.git"
|
REPO="https://github.com/m1ngsama/chopsticks.git"
|
||||||
DEST="$HOME/.vim"
|
DEST="${CHOPSTICKS_DEST:-$HOME/.vim}"
|
||||||
|
DRY_RUN=0
|
||||||
|
INSTALLER_ARGS=()
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage: get.sh [OPTIONS] [INSTALLER_OPTIONS]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--dry-run Show what would happen without cloning, pulling, or installing
|
||||||
|
--help, -h Show this help and exit
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
CHOPSTICKS_DEST Absolute install path (default: ~/.vim)
|
||||||
|
|
||||||
|
All other options are passed to install.sh after clone/update.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--dry-run) DRY_RUN=1 ;;
|
||||||
|
--help|-h) usage; exit 0 ;;
|
||||||
|
*) INSTALLER_ARGS+=("$arg") ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then
|
if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then
|
||||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m'
|
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m'
|
||||||
|
|
@ -19,6 +45,12 @@ ok() { echo -e "${GREEN}[OK]${NC} $1"; }
|
||||||
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
||||||
die() { echo -e "${RED}[FATAL]${NC} $1" >&2; exit 1; }
|
die() { echo -e "${RED}[FATAL]${NC} $1" >&2; exit 1; }
|
||||||
step() { echo -e "\n${BOLD}==> $1${NC}"; }
|
step() { echo -e "\n${BOLD}==> $1${NC}"; }
|
||||||
|
info() { echo " $1"; }
|
||||||
|
|
||||||
|
case "$DEST" in
|
||||||
|
/*) ;;
|
||||||
|
*) die "CHOPSTICKS_DEST must be an absolute path: $DEST" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
repo_origin() {
|
repo_origin() {
|
||||||
git -C "$DEST" config --get remote.origin.url 2>/dev/null || true
|
git -C "$DEST" config --get remote.origin.url 2>/dev/null || true
|
||||||
|
|
@ -42,6 +74,7 @@ echo -e "${BOLD}chopsticks — One-command installer${NC}"
|
||||||
echo "----------------------------------"
|
echo "----------------------------------"
|
||||||
echo " Repo: $REPO"
|
echo " Repo: $REPO"
|
||||||
echo " Dest: $DEST"
|
echo " Dest: $DEST"
|
||||||
|
[[ $DRY_RUN -eq 1 ]] && echo " Mode: dry-run"
|
||||||
|
|
||||||
# ── git ───────────────────────────────────────────────────────────────────────
|
# ── git ───────────────────────────────────────────────────────────────────────
|
||||||
step "Checking for git"
|
step "Checking for git"
|
||||||
|
|
@ -65,22 +98,32 @@ if [[ -d "$DEST/.git" ]]; then
|
||||||
if ! is_chopsticks_repo "$ORIGIN"; then
|
if ! is_chopsticks_repo "$ORIGIN"; then
|
||||||
die "$DEST is a git repo, but it does not look like chopsticks.
|
die "$DEST is a git repo, but it does not look like chopsticks.
|
||||||
origin: ${ORIGIN:-none}
|
origin: ${ORIGIN:-none}
|
||||||
Back it up first: mv ~/.vim ~/.vim.bak
|
Back it up first: mv \"$DEST\" \"$DEST.bak\"
|
||||||
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
||||||
fi
|
fi
|
||||||
[[ -f "$DEST/install.sh" && -f "$DEST/.vimrc" ]] || \
|
[[ -f "$DEST/install.sh" && -f "$DEST/.vimrc" ]] || \
|
||||||
die "$DEST looks incomplete. Expected install.sh and .vimrc.
|
die "$DEST looks incomplete. Expected install.sh and .vimrc.
|
||||||
Back it up first: mv ~/.vim ~/.vim.bak
|
Back it up first: mv \"$DEST\" \"$DEST.bak\"
|
||||||
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
info "Would update existing chopsticks repo at $DEST"
|
||||||
|
info "Would run: bash install.sh ${INSTALLER_ARGS[*]:-(no installer options)}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
warn "$DEST already exists — pulling latest changes"
|
warn "$DEST already exists — pulling latest changes"
|
||||||
git -C "$DEST" pull --ff-only origin main 2>/dev/null || \
|
git -C "$DEST" pull --ff-only origin main 2>/dev/null || \
|
||||||
warn "Could not pull latest — using existing version (run: git -C ~/.vim pull)"
|
warn "Could not pull latest — using existing version (run: git -C ~/.vim pull)"
|
||||||
ok "Repository updated ($(git -C "$DEST" describe --tags 2>/dev/null || git -C "$DEST" rev-parse --short HEAD))"
|
ok "Repository updated ($(git -C "$DEST" describe --tags 2>/dev/null || git -C "$DEST" rev-parse --short HEAD))"
|
||||||
elif [[ -d "$DEST" ]]; then
|
elif [[ -d "$DEST" ]]; then
|
||||||
die "$HOME/.vim exists but is not a chopsticks git repo.
|
die "$DEST exists but is not a chopsticks git repo.
|
||||||
Back it up first: mv ~/.vim ~/.vim.bak
|
Back it up first: mv \"$DEST\" \"$DEST.bak\"
|
||||||
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
||||||
else
|
else
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
info "Would clone $REPO to $DEST"
|
||||||
|
info "Would run: bash install.sh ${INSTALLER_ARGS[*]:-(no installer options)}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
git clone --depth=1 "$REPO" "$DEST" || \
|
git clone --depth=1 "$REPO" "$DEST" || \
|
||||||
die "Clone failed — check your network connection"
|
die "Clone failed — check your network connection"
|
||||||
ok "Cloned to $DEST ($(git -C "$DEST" describe --tags 2>/dev/null || git -C "$DEST" rev-parse --short HEAD))"
|
ok "Cloned to $DEST ($(git -C "$DEST" describe --tags 2>/dev/null || git -C "$DEST" rev-parse --short HEAD))"
|
||||||
|
|
@ -96,7 +139,7 @@ cd "$DEST"
|
||||||
# Use a test-open to check /dev/tty is actually accessible (it may exist but be
|
# Use a test-open to check /dev/tty is actually accessible (it may exist but be
|
||||||
# unusable in non-interactive SSH sessions or container environments).
|
# unusable in non-interactive SSH sessions or container environments).
|
||||||
if { true </dev/tty; } 2>/dev/null; then
|
if { true </dev/tty; } 2>/dev/null; then
|
||||||
exec bash install.sh "$@" </dev/tty
|
exec bash install.sh "${INSTALLER_ARGS[@]}" </dev/tty
|
||||||
else
|
else
|
||||||
exec bash install.sh "$@"
|
exec bash install.sh "${INSTALLER_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue