mirror of
https://github.com/mattpocock/skills.git
synced 2026-11-06 05:17:24 +00:00
fix(wizard): template.sh readline, .env quoting, symlinks, EOF and opener warning
Fixes #741 #770 #774 #811 #852. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6fd947921b
commit
868c4cf20c
3 files changed
+30
-22
No files matched your search
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"mattpocock-skills": patch
|
||||
---
|
||||
|
||||
`wizard` template fixes: `ask` uses Readline so arrow keys move the cursor (#741); `write_env` single-quotes values so spaces, `#`, `$` and quotes survive `source` and dotenv (#770); `open_url` prints the open-it-yourself warning when no browser opener exists (#774); `write_env` writes through a symlinked `.env` and keeps an existing file's mode (#811); `ask` and `ask_secret` fail at EOF instead of looping (#852).
|
||||
@@ -62,8 +62,6 @@ No. The agent writes a script; it doesn't run it. You run the script yourself, a
|
||||
|
||||
Not mid-run. There is no back button. The stages run forward, and a wrong answer on stage 3 means Ctrl-C and re-run. Re-running is cheap, because any value already written to `.env` is offered back as a default, so you press Enter through the stages you got right and retype only the wrong one. Users asked for this in launch week, and it is still open: "loved it! One thing though, is there a way to go back and correct what you've entered?"
|
||||
|
||||
There's a related open bug. Arrow keys in an `ask` prompt insert `^[[D` / `^[[C` instead of moving the cursor, because the prompt uses `read -r` rather than Readline ([issue #741](https://github.com/mattpocock/skills/issues/741)). Backspace works; arrow keys don't. Delete back to the mistake rather than moving the cursor into it.
|
||||
|
||||
**Does it know what I've already set up?**
|
||||
|
||||
Partly, and less than the launch reactions assumed. It reads the repo before it asks (your `.env` files, `docker-compose`, framework config, the `secrets.*` references in CI), so it scopes to values that are missing rather than starting from zero the way a README does. What it doesn't do is check the third-party service. If a key exists in your `.env` the wizard offers it back and Enter keeps it; if you already created the Stripe account but never saved the key, the wizard still sends you to the dashboard for it.
|
||||
|
||||
@@ -70,7 +70,7 @@ open_url() {
|
||||
elif command -v explorer.exe >/dev/null 2>&1; then explorer.exe "$url"
|
||||
elif command -v xdg-open >/dev/null 2>&1; then xdg-open "$url"
|
||||
elif command -v open >/dev/null 2>&1; then open "$url"
|
||||
else warn "couldn't open a browser; visit it manually: $url"; fi
|
||||
else false; fi
|
||||
} >/dev/null 2>&1 || warn "couldn't open a browser, so visit it manually: $url"
|
||||
}
|
||||
|
||||
@@ -88,52 +88,57 @@ confirm() {
|
||||
[[ "$reply" =~ ^[Yy] ]]
|
||||
}
|
||||
|
||||
# _existing KEY: current value of KEY in ENV_FILE, if any.
|
||||
# _existing KEY: current value of KEY in ENV_FILE, if any, with write_env's quoting undone.
|
||||
_existing() {
|
||||
[[ -f "$ENV_FILE" ]] || return 1
|
||||
local line; line=$(grep -E "^${1}=" "$ENV_FILE" | tail -n1) || return 1
|
||||
printf '%s' "${line#*=}"
|
||||
local line value sq="'\\''"; line=$(grep -E "^${1}=" "$ENV_FILE" | tail -n1) || return 1
|
||||
value="${line#*=}"
|
||||
if [[ "$value" == \'*\' ]]; then value="${value:1:${#value}-2}"; value="${value//"$sq"/\'}"; fi
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
# ask KEY "Prompt" reads a value into $KEY. Offers the existing .env value as
|
||||
# a default on re-runs (Enter keeps it). Visible input (non-secret).
|
||||
# a default on re-runs (Enter keeps it). Visible input (non-secret), edited
|
||||
# with Readline. Fails at EOF with no input.
|
||||
ask() {
|
||||
local key="$1" prompt="$2" current input
|
||||
local key="$1" prompt="$2" current input s=$'\001' e=$'\002' p rc=0
|
||||
current=$(_existing "$key" || true)
|
||||
if [[ -n "$current" ]]; then
|
||||
printf ' %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"
|
||||
else
|
||||
printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"
|
||||
fi
|
||||
read -r input || true
|
||||
# Readline needs the colour codes wrapped in \001..\002 to place the cursor.
|
||||
p=" $s$BOLD$e$prompt$s$RESET$e "
|
||||
[[ -n "$current" ]] && p+="$s$DIM$e[Enter keeps current]$s$RESET$e "
|
||||
read -e -r -p "$p" input || rc=1
|
||||
if (( rc )) && [[ -z "$input" ]]; then return 1; fi
|
||||
[[ -z "$input" && -n "$current" ]] && input="$current"
|
||||
printf -v "$key" '%s' "$input"
|
||||
}
|
||||
|
||||
# ask_secret KEY "Prompt" is like ask, but input is hidden.
|
||||
ask_secret() {
|
||||
local key="$1" prompt="$2" current input
|
||||
local key="$1" prompt="$2" current input rc=0
|
||||
current=$(_existing "$key" || true)
|
||||
if [[ -n "$current" ]]; then
|
||||
printf ' %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"
|
||||
else
|
||||
printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"
|
||||
fi
|
||||
read -rs input || true
|
||||
read -rs input || rc=1
|
||||
printf '\n'
|
||||
if (( rc )) && [[ -z "$input" ]]; then return 1; fi
|
||||
[[ -z "$input" && -n "$current" ]] && input="$current"
|
||||
printf -v "$key" '%s' "$input"
|
||||
}
|
||||
|
||||
# write_env KEY VALUE upserts KEY=VALUE into ENV_FILE (creates it; replaces
|
||||
# any existing line). Idempotent.
|
||||
# write_env KEY VALUE upserts KEY='VALUE' into ENV_FILE (replaces any existing
|
||||
# line). Idempotent. Creates ENV_FILE at mode 0600; writes through a symlink
|
||||
# and keeps an existing file's mode.
|
||||
write_env() {
|
||||
local key="$1" value="$2" tmp
|
||||
touch "$ENV_FILE"
|
||||
local key="$1" value="$2" tmp sq="'\\''"
|
||||
[[ -e "$ENV_FILE" ]] || (umask 077 && : > "$ENV_FILE")
|
||||
tmp=$(mktemp)
|
||||
grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || true
|
||||
printf '%s=%s\n' "$key" "$value" >> "$tmp"
|
||||
mv "$tmp" "$ENV_FILE"
|
||||
printf "%s='%s'\n" "$key" "${value//\'/$sq}" >> "$tmp"
|
||||
cat "$tmp" > "$ENV_FILE"
|
||||
rm -f "$tmp"
|
||||
WRITTEN_ENV+=("$key")
|
||||
printf ' %s✓ wrote%s %s → %s\n' "$GREEN" "$RESET" "$key" "$ENV_FILE"
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user