Skip to content

Commit dc31b1a

Browse files
committed
refactor(scripts): improve install and tool logic
- Update bootstrap.sh to support custom TARGET_DIR and prevent accidental overwrites of existing dotfiles directories. - Fix a common issue in install.sh where interactive prompts were skipped by forcing read to use /dev/tty for user input. - Export logging functions (info, success, etc.) and colors to ensure consistent output across all sub-scripts like macos.sh. - Modify mise configuration for ruff and taplo-cli to use pipx and cargo backends respectively, fixing @latest resolution issues. - Adjust macOS InitialKeyRepeat to 15 (225ms) and add standalone logging support to macos.sh. - Refine local fish configuration examples and update README wording. BREAKING CHANGE: bootstrap.sh now exits with an error if the target directory already exists, rather than attempting to update it.
1 parent 0f43eea commit dc31b1a

7 files changed

Lines changed: 57 additions & 46 deletions

File tree

LICENSE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2026-present windvalley
3+
Copyright (c) 2026 windvalley
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
SOFTWARE.
22+

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
[![License](https://img.shields.io/github/license/windvalley/dotfiles)](https://github.com/windvalley/dotfiles/blob/main/LICENSE)
1212

1313

14-
本项目是一套 **现代、高效、精炼、开箱即用** 的 macOS 终端开发环境,所有配置集中版本控制,通过 GNU Stow 一键部署。
14+
本项目是一套 **现代、高效、开箱即用** 的 macOS 终端开发环境,所有配置集中版本控制,通过 GNU Stow 一键部署。
1515

1616
核心工具栈:Ghostty(终端)+ Zellij(复用器)+ Fish(Shell)+ Helix(编辑器)+ Mise(版本管理),视觉与交互风格全栈统一。
1717

@@ -67,7 +67,6 @@
6767
最简单的方法是使用一键安装脚本(Bootstrap):
6868

6969
```sh
70-
# 直接运行以下命令,会自动完成克隆仓库并执行安装脚本
7170
bash -c "$(curl -fsSL https://raw.githubusercontent.com/windvalley/dotfiles/main/bootstrap.sh)"
7271
```
7372

bootstrap.sh

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/bin/bash
2-
32
# dotfiles bootstrap script
43
# curl -fsSL https://raw.githubusercontent.com/windvalley/dotfiles/main/bootstrap.sh | bash
54

@@ -8,6 +7,7 @@ set -euo pipefail
87
RED='\033[0;31m'
98
GREEN='\033[0;32m'
109
BLUE='\033[0;34m'
10+
YELLOW='\033[1;33m'
1111
NC='\033[0m'
1212

1313
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
@@ -33,18 +33,25 @@ if ! command -v git &> /dev/null; then
3333
success "Git installed successfully."
3434
fi
3535

36-
if [ -d "$DOTFILES_DIR" ]; then
37-
info "Dotfiles directory already exists at $DOTFILES_DIR. Updating..."
38-
cd "$DOTFILES_DIR"
39-
git pull origin main
40-
else
41-
info "Cloning dotfiles repository to $DOTFILES_DIR..."
42-
git clone "$REPO_URL" "$DOTFILES_DIR"
36+
# Allow user to specify a custom target directory via DOTFILES_DIR environment variable
37+
TARGET_DIR="${DOTFILES_DIR:-$HOME/dotfiles}"
38+
39+
if [ -d "$TARGET_DIR" ]; then
40+
error "Target directory already exists at $TARGET_DIR."
41+
error "The bootstrap script is designed for first-time installation only."
42+
echo -e "${YELLOW}[WARN]${NC} If you want to reinstall, please remove the existing directory:"
43+
echo " rm -rf $TARGET_DIR"
44+
echo -e "${YELLOW}[WARN]${NC} Or specify a different location by running:"
45+
echo " export DOTFILES_DIR=~/some_other_path; curl ... | bash"
46+
exit 1
4347
fi
4448

45-
cd "$DOTFILES_DIR"
49+
info "Cloning dotfiles repository to $TARGET_DIR..."
50+
git clone "$REPO_URL" "$TARGET_DIR"
51+
52+
cd "$TARGET_DIR"
4653

4754
info "Executing install.sh..."
4855
bash install.sh "$@"
4956

50-
success "Bootstrap completed successfully!"
57+
success "Bootstrap completed successfully!"

install.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ GREEN='\033[0;32m'
88
BLUE='\033[0;34m'
99
YELLOW='\033[1;33m'
1010
NC='\033[0m'
11+
export RED GREEN BLUE YELLOW NC
1112

1213
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
1314
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
1415
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
1516
error() { echo -e "${RED}[ERROR]${NC} $1"; }
17+
export -f info success warn error
1618

1719

1820

@@ -39,7 +41,9 @@ ask_yes_no() {
3941
info "${prompt} (auto-yes)"
4042
return 0
4143
else
42-
read -p "$prompt " -n 1 -r
44+
# 从 /dev/tty 直接读取终端输入,避免上一步命令(brew/zsh/fish 等)
45+
# 向 stdin 写入残留字节导致 read 跳过用户输入的问题
46+
read -p "$prompt " -n 1 -r REPLY < /dev/tty
4347
echo
4448
if [[ $REPLY =~ ^[Yy]$ ]]; then
4549
return 0
@@ -254,12 +258,11 @@ else
254258
fi
255259

256260
if [[ "$(uname)" == "Darwin" ]]; then
257-
if [ "$NON_INTERACTIVE" = true ]; then
258-
info "Skipping macOS system preferences in non-interactive mode."
259-
elif ask_yes_no "Do you want to apply macOS system preferences (macos.sh)? (y/n)"; then
261+
if ask_yes_no "Do you want to apply macOS system preferences (macos.sh)? (y/n)"; then
260262
info "Applying macOS system preferences..."
261263
bash "$DOTFILES_DIR/macos.sh"
262264
fi
265+
263266
fi
264267

265268
success "Installation complete!"

local/config.local.fish.example

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,26 @@
77
#
88
# 使用方法:
99
# cp config.local.fish.example ~/.config/fish/config.local.fish
10-
# 重启 fish 即可生效。
10+
# 执行 exec fish 即可生效。
1111
# ============================================================
1212

1313
# --- 敏感环境变量 ---
14-
# 例如:LLM API 密钥,Homebrew 个人授权 token 等
14+
# 例如:OpenAI API 密钥
1515
# set -gx OPENAI_API_KEY "sk-xxxxxxxxx"
16-
# set -gx HOMEBREW_GITHUB_API_TOKEN "ghp_xxxxxxxx"
17-
#
18-
# 覆盖config.fish 中的 AI_CMD 默认配置
16+
17+
# 强烈建议配置,用于提升 mise/Homebrew 等工具调用 GitHub API 的频率限制
18+
# 获取方式:https://github.com/settings/tokens (申请 Classic Token,无需勾选任何权限即可)
19+
# set -gx GITHUB_TOKEN "ghp_xxxxxxxx"
20+
21+
# --- AI 命令行工具 ---
22+
# 覆盖 config.fish 中的 AI_CMD 默认配置
1923
# set -gx AI_CMD "opencode run -m google/antigravity-gemini-3-flash"
2024

2125
# --- 机器特定别名 (Aliases) ---
2226
# 例如:某些只存在于这台 Mac 上的启动守护进程命令 / 脚本快捷方式
2327
# abbr -a -g restart-work-vpn "sudo launchctl restart com.corp.vpn"
2428

25-
# --- 本机路径注入 ---
26-
# 虽然 install.sh 已经做了通用路径集成,如果你有特定工具仅安装在本机:
27-
# test -d "$HOME/.cargo/bin"; and fish_add_path --path "$HOME/.cargo/bin"
29+
# --- 本机特有路径注入 ---
30+
# 例如:公司内网 SDK 或手动解压的第三方工具,无法通过 mise/brew 管理的私有二进制
31+
# test -d "/opt/company-sdk/bin"; and fish_add_path --path "/opt/company-sdk/bin"
32+

macos.sh

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
set -euo pipefail
44

5+
# Fallback logging functions when run standalone (not via install.sh)
6+
if ! declare -f warn > /dev/null 2>&1; then
7+
YELLOW='\033[1;33m'
8+
NC='\033[0m'
9+
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
10+
fi
11+
512
# ==============================================================================
613
# 🍎 macOS 系统偏好设置
714
# ==============================================================================
@@ -13,21 +20,7 @@ set -euo pipefail
1320
osascript -e 'tell application "System Settings" to quit' 2>/dev/null || true
1421
osascript -e 'tell application "System Preferences" to quit' 2>/dev/null || true
1522

16-
# 预先请求管理员密码
17-
sudo -v
18-
19-
# 保持 sudo 权限:后台续期,脚本结束时自动清理
20-
sudo_keepalive() {
21-
while kill -0 "$$" 2>/dev/null; do
22-
sudo -n true
23-
sleep 50
24-
done
25-
}
26-
sudo_keepalive &
27-
SUDO_PID=$!
28-
trap 'kill $SUDO_PID 2>/dev/null; sudo -k' EXIT
29-
30-
echo "正在配置 macOS..."
23+
echo "Configuring macOS..."
3124

3225
###############################################################################
3326
# 通用界面与用户体验 #
@@ -38,8 +31,8 @@ echo "正在配置 macOS..."
3831
# 系统设置 UI 面板允许的最快极限值:KeyRepeat = 2 (30ms),InitialKeyRepeat = 15 (225ms)
3932
# KeyRepeat:重复速率(数字越小越快,1 是最快)
4033
defaults write NSGlobalDomain KeyRepeat -int 1
41-
# InitialKeyRepeat:首次重复前的延迟(单位:毫秒,约 150ms)
42-
defaults write NSGlobalDomain InitialKeyRepeat -int 10
34+
# InitialKeyRepeat:首次重复前的延迟
35+
defaults write NSGlobalDomain InitialKeyRepeat -int 15
4336

4437
# 禁用按键长按功能,改为重复输入该按键(对 Vim 用户很有用)
4538
# 默认值:true(启用长按显示特殊字符选择菜单)
@@ -182,4 +175,5 @@ for app in "Activity Monitor" \
182175
killall "${app}" &> /dev/null || true
183176
done
184177

185-
echo "完成。注意:部分更改需要注销或重启后才能生效。"
178+
echo "Done."
179+
warn "Some changes will only take effect after restarting your Mac."

mise/dot-config/mise/config.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ rust = "latest"
6262
"go:github.com/golangci/golangci-lint/cmd/golangci-lint" = "latest"
6363

6464
# --- Python 生态 ---
65-
ruff = "latest" # Linter/Formatter/LSP (使用 native 预编译版更轻快)
66-
"npm:pyright" = "latest" # Type Checker LSP (由 npm 分发更快更稳)
65+
# ruff: 默认 aqua backend 无法正确解析 @latest,改用 pipx 通过 PyPI 获取
66+
"pipx:ruff" = "latest" # Linter/Formatter/LSP
67+
"npm:pyright" = "latest" # Type Checker LSP
6768

6869
# --- Web 生态 (TS/JS/CSS/HTML/JSON) ---
6970
"npm:@vtsls/language-server" = "latest"
@@ -72,7 +73,8 @@ ruff = "latest" # Linter/Formatter/LSP (使用 native 预编译版
7273
"npm:@tailwindcss/language-server" = "latest"
7374

7475
# --- Rust 生态 ---
75-
taplo = "latest" # TOML Formatter/LSP (使用 native 预编译版,告别 cargo 编译)
76+
# taplo: 仅有 aqua/cargo 两个 backend;aqua 无法正确解析 @latest,cargo 为官方推荐,首次编译后有缓存
77+
"cargo:taplo-cli" = "latest" # TOML Formatter/LSP
7678
# 注意: 不通过 mise 管理 rust-analyzer 的原因
7779
# 1. 它是 Rust 官方工具链的一部分,强依赖底层的 rustc 和特定平台的系统级 API。
7880
# 2. 从源码通过 cargo 编译安装极其耗时,且容易因为 C 依赖报错。

0 commit comments

Comments
 (0)