Skip to content

Commit 43d6223

Browse files
committed
feat(guide): add 'a' (always) option for automatic updates
- Add 'a' option to upgrade prompt that installs immediately AND enables auto-update for future runs (no more prompting for that tool) - Add set_auto_update.sh script to manage auto_update flag on tools - Fix npm_global.sh to use @latest suffix to force latest version - Fix ruby-build version detection to use --version instead of git log - Update install_ruby.sh fallback to Ruby 4.0.0 (now stable) - Enable auto_update for claude and prettier per user selection
1 parent 23006b4 commit 43d6223

7 files changed

Lines changed: 139 additions & 11 deletions

File tree

catalog/claude.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
"category": "ai",
44
"install_method": "npm_global",
55
"description": "Anthropic's Claude Code CLI - AI-powered development assistant",
6-
"homepage": "https://claude.com/claude-code",
7-
"github_repo": "anthropics/claude-code",
6+
"homepage": "https://www.npmjs.com/package/@anthropic-ai/claude-code",
87
"binary_name": "claude",
98
"package_name": "@anthropic-ai/claude-code",
109
"guide": {
1110
"display_name": "Claude Code",
1211
"install_action": "upgrade",
1312
"order": 400
14-
}
13+
},
14+
"auto_update": true
1515
}

catalog/prettier.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"description": "Opinionated code formatter",
66
"homepage": "https://prettier.io",
77
"package_name": "prettier",
8-
"notes": "Prettier is a JavaScript/Node.js tool installed via npm"
8+
"notes": "Prettier is a JavaScript/Node.js tool installed via npm",
9+
"auto_update": true
910
}

catalog/ruby-build.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"github_repo": "rbenv/ruby-build",
88
"binary_name": "ruby-build",
99
"clone_path": "~/.rbenv/plugins/ruby-build",
10-
"version_command": "cd ~/.rbenv/plugins/ruby-build && git log -1 --format='%s' | grep -oP 'ruby-build \\K[0-9]+'",
10+
"version_command": "~/.rbenv/plugins/ruby-build/bin/ruby-build --version | grep -oE '[0-9]+'",
1111
"notes": "Installs as rbenv plugin. Requires rbenv to be installed first.",
1212
"guide": {
1313
"display_name": "ruby-build",

scripts/guide.sh

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ process_tool() {
134134
local install_action="$(catalog_get_guide_property "$tool" install_action "")"
135135
local description="$(catalog_get_property "$tool" description)"
136136
local homepage="$(catalog_get_property "$tool" homepage)"
137+
local auto_update="$(catalog_get_property "$tool" auto_update)"
137138

138139
# Check if up-to-date
139140
if [ -n "$is_up_to_date" ] && [ -n "$installed" ]; then
@@ -144,6 +145,36 @@ process_tool() {
144145
return 0
145146
fi
146147

148+
# Check if auto_update is enabled - install without prompting
149+
if [ "$auto_update" = "true" ]; then
150+
printf "\n==> %s %s [auto-update]\n" "$icon" "$display"
151+
printf " installed: %s via %s\n" "${installed:-<none>}" "${method:-unknown}"
152+
printf " target: %s\n" "$(osc8 "$url" "${latest:-<unknown>}")"
153+
printf " auto-updating...\n"
154+
155+
# Build install command from catalog metadata
156+
local install_cmd="install_tool.sh $tool"
157+
if [ -n "$install_action" ]; then
158+
install_cmd="install_tool.sh $tool $install_action"
159+
elif [ -n "$installed" ]; then
160+
install_cmd="install_tool.sh $tool update"
161+
fi
162+
163+
# Execute the install
164+
if [ "$tool" = "python" ]; then
165+
UV_PYTHON_SPEC="$latest" "$ROOT"/scripts/$install_cmd || true
166+
elif [ "$tool" = "ruby" ]; then
167+
RUBY_VERSION="$latest" "$ROOT"/scripts/$install_cmd || true
168+
else
169+
"$ROOT"/scripts/$install_cmd || true
170+
fi
171+
172+
# Re-audit with fresh collection for this specific tool
173+
CLI_AUDIT_JSON=1 CLI_AUDIT_COLLECT=1 CLI_AUDIT_MERGE=1 "$CLI" audit.py "$tool" >/dev/null 2>&1 || true
174+
AUDIT_JSON="$(cd "$ROOT" && CLI_AUDIT_JSON=1 CLI_AUDIT_RENDER=1 "$CLI" audit.py || true)"
175+
return 0
176+
fi
177+
147178
# Prompt for installation/update
148179
printf "\n==> %s %s\n" "$icon" "$display"
149180
[ -n "$description" ] && printf " %s\n" "$description"
@@ -164,6 +195,7 @@ process_tool() {
164195
# Prompt with options explained
165196
printf " Options:\n"
166197
printf " y = Install/upgrade now\n"
198+
printf " a = Always update (install now + auto-update in future)\n"
167199
printf " N = Skip (ask again next time)\n"
168200
if [ -n "$installed" ]; then
169201
printf " s = Skip version %s (ask again if newer available)\n" "$latest"
@@ -173,7 +205,7 @@ process_tool() {
173205
printf " p = Never install (permanently skip this tool)\n"
174206
fi
175207

176-
local prompt_text="Install/update? [y/N/s/p] "
208+
local prompt_text="Install/update? [y/a/N/s/p] "
177209

178210
local ans=""
179211
if [ -t 0 ]; then
@@ -218,6 +250,41 @@ process_tool() {
218250
fi
219251
fi
220252
;;
253+
[Aa])
254+
# Install/upgrade AND enable auto-update for future
255+
printf " Enabling auto-update for future upgrades...\n"
256+
"$ROOT"/scripts/set_auto_update.sh "$tool" true >/dev/null 2>&1 || true
257+
258+
# Handle tool-specific version environment variables
259+
local upgrade_success_a=0
260+
if [ "$tool" = "python" ]; then
261+
UV_PYTHON_SPEC="$latest" "$ROOT"/scripts/$install_cmd && upgrade_success_a=1 || true
262+
elif [ "$tool" = "ruby" ]; then
263+
RUBY_VERSION="$latest" "$ROOT"/scripts/$install_cmd && upgrade_success_a=1 || true
264+
else
265+
"$ROOT"/scripts/$install_cmd && upgrade_success_a=1 || true
266+
fi
267+
268+
# Re-audit with fresh collection for this specific tool
269+
CLI_AUDIT_JSON=1 CLI_AUDIT_COLLECT=1 CLI_AUDIT_MERGE=1 "$CLI" audit.py "$tool" >/dev/null 2>&1 || true
270+
AUDIT_JSON="$(cd "$ROOT" && CLI_AUDIT_JSON=1 CLI_AUDIT_RENDER=1 "$CLI" audit.py || true)"
271+
272+
# Check if upgrade succeeded
273+
local new_installed_a="$(json_field "$tool" installed)"
274+
if [ "$upgrade_success_a" = "0" ] || [ "$new_installed_a" = "$installed" ]; then
275+
printf "\n ⚠️ Upgrade did not succeed (version unchanged)\n"
276+
printf " Auto-update is still enabled - will try again next time.\n"
277+
else
278+
printf " ✓ Auto-update enabled. This tool will update automatically in future.\n"
279+
# Remove any existing pin
280+
if catalog_has_tool "$tool"; then
281+
local existing_pin_a="$(catalog_get_property "$tool" pinned_version)"
282+
if [ -n "$existing_pin_a" ]; then
283+
"$ROOT"/scripts/unpin_version.sh "$tool" || true
284+
fi
285+
fi
286+
fi
287+
;;
221288
[Ss])
222289
# Skip this specific version
223290
printf " Skipping version %s (will prompt again if newer version available)\n" "$latest"

scripts/install_ruby.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ ensure_rbenv_loaded() {
3434

3535
get_latest_ruby_version() {
3636
ensure_rbenv
37-
# Get latest stable Ruby version from rbenv
38-
rbenv install --list 2>/dev/null | grep -E '^\s*[0-9]+\.[0-9]+\.[0-9]+$' | tail -1 | tr -d ' ' || echo "3.3.6"
37+
# Get latest stable Ruby version from rbenv (MRI Ruby only, excludes jruby/mruby/truffleruby)
38+
rbenv install --list 2>/dev/null | grep -E '^\s*[0-9]+\.[0-9]+\.[0-9]+$' | tail -1 | tr -d ' ' || echo "4.0.0"
3939
}
4040

4141
install_ruby() {

scripts/installers/npm_global.sh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,22 @@ fi
5757
echo "[$TOOL] Installing package globally via $PKG_MANAGER: $PACKAGE_NAME" >&2
5858
case "$PKG_MANAGER" in
5959
pnpm)
60-
pnpm add -g "$PACKAGE_NAME" || {
60+
# Use @latest to ensure we get the newest version
61+
pnpm add -g "${PACKAGE_NAME}@latest" || {
6162
echo "[$TOOL] Error: pnpm install failed" >&2
6263
exit 1
6364
}
6465
;;
6566
npm)
66-
npm install -g "$PACKAGE_NAME" || {
67+
# Use @latest to ensure we get the newest version (bypasses npm cache issues)
68+
npm install -g "${PACKAGE_NAME}@latest" || {
6769
echo "[$TOOL] Error: npm install failed" >&2
6870
exit 1
6971
}
7072
;;
7173
yarn)
72-
yarn global add "$PACKAGE_NAME" || {
74+
# Use @latest to ensure we get the newest version
75+
yarn global add "${PACKAGE_NAME}@latest" || {
7376
echo "[$TOOL] Error: yarn install failed" >&2
7477
exit 1
7578
}

scripts/set_auto_update.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env bash
2+
# set_auto_update.sh - Enable/disable automatic updates for a tool
3+
set -euo pipefail
4+
5+
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
ROOT="$(cd "$DIR/.." && pwd)"
7+
8+
TOOL="${1:-}"
9+
VALUE="${2:-true}" # true or false
10+
11+
if [ -z "$TOOL" ]; then
12+
echo "Usage: $0 TOOL_NAME [true|false]" >&2
13+
echo "" >&2
14+
echo "Enable or disable automatic updates for a tool." >&2
15+
echo "When enabled, 'make upgrade' will update the tool without asking." >&2
16+
echo "" >&2
17+
echo "Examples:" >&2
18+
echo " $0 prettier # Enable auto-update for prettier" >&2
19+
echo " $0 prettier true # Enable auto-update for prettier" >&2
20+
echo " $0 prettier false # Disable auto-update for prettier" >&2
21+
exit 1
22+
fi
23+
24+
CATALOG_FILE="$ROOT/catalog/$TOOL.json"
25+
if [ ! -f "$CATALOG_FILE" ]; then
26+
echo "Error: Tool '$TOOL' not found in catalog" >&2
27+
exit 1
28+
fi
29+
30+
# Normalize value
31+
case "$VALUE" in
32+
true|1|yes|on) VALUE="true" ;;
33+
false|0|no|off) VALUE="false" ;;
34+
*)
35+
echo "Error: Invalid value '$VALUE'. Use 'true' or 'false'" >&2
36+
exit 1
37+
;;
38+
esac
39+
40+
if [ "$VALUE" = "true" ]; then
41+
echo "Enabling automatic updates for '$TOOL'..."
42+
TMP_FILE=$(mktemp)
43+
jq '. + {auto_update: true}' "$CATALOG_FILE" > "$TMP_FILE"
44+
mv "$TMP_FILE" "$CATALOG_FILE"
45+
echo "✓ Auto-update enabled for '$TOOL'"
46+
echo ""
47+
echo "This tool will be automatically updated during 'make upgrade' without prompting."
48+
echo "To disable: $0 $TOOL false"
49+
else
50+
echo "Disabling automatic updates for '$TOOL'..."
51+
TMP_FILE=$(mktemp)
52+
jq 'del(.auto_update)' "$CATALOG_FILE" > "$TMP_FILE"
53+
mv "$TMP_FILE" "$CATALOG_FILE"
54+
echo "✓ Auto-update disabled for '$TOOL'"
55+
echo ""
56+
echo "You will be prompted before updating this tool."
57+
fi

0 commit comments

Comments
 (0)