-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·181 lines (156 loc) · 5.78 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·181 lines (156 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/bash
set -euo pipefail
# Dotfiles install script for fresh Linux dev boxes
# Run with: curl -fsSL <raw-url> | bash
# Or: ./install.sh
# Resolve dotfiles directory from script location (works whether run via
# ./install.sh or from a piped curl on a fresh machine)
DOTFILES_REPO="https://github.com/johnnymo87/dotfiles.git"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -d "$SCRIPT_DIR/.git" ]; then
DOTFILES_DIR="$SCRIPT_DIR"
else
# Piped install — clone to platform-appropriate location
if [ "$(uname)" = "Darwin" ]; then
DOTFILES_DIR="$HOME/Code/dotfiles"
else
DOTFILES_DIR="$HOME/projects/dotfiles"
fi
fi
echo "==> Installing dotfiles..."
if [ ! -d "$DOTFILES_DIR/.git" ]; then
mkdir -p "$(dirname "$DOTFILES_DIR")"
echo "==> Cloning dotfiles..."
git clone --recurse-submodules "$DOTFILES_REPO" "$DOTFILES_DIR"
else
echo "==> Dotfiles at $DOTFILES_DIR, pulling latest..."
cd "$DOTFILES_DIR" && git pull && git submodule update --init --recursive
fi
# Backup existing configs
echo "==> Backing up existing configs..."
mkdir -p "$HOME/.config-backup"
for f in .bashrc .bash_profile .gitconfig .gitignore_global .vimrc .tmux.conf; do
[ -f "$HOME/$f" ] && [ ! -L "$HOME/$f" ] && cp "$HOME/$f" "$HOME/.config-backup/${f}.bak" || true
done
# Create symlinks
echo "==> Creating symlinks..."
# Shell
ln -sf "$DOTFILES_DIR/.bashrc" "$HOME/.bashrc"
ln -sf "$DOTFILES_DIR/.bashrc.d" "$HOME/.bashrc.d"
ln -sf "$DOTFILES_DIR/.bash_profile" "$HOME/.bash_profile"
# Git
ln -sf "$DOTFILES_DIR/.gitconfig" "$HOME/.gitconfig"
ln -sf "$DOTFILES_DIR/.gitignore_global" "$HOME/.gitignore_global"
# Vim/Neovim
ln -sf "$DOTFILES_DIR/.vimrc" "$HOME/.vimrc"
mkdir -p "$HOME/.config"
# Create nvim as a real directory with child symlinks
# This allows home-manager to manage additional files (e.g., lua/ccremote.lua)
NVIM_HOME="$HOME/.config/nvim"
NVIM_SRC="$DOTFILES_DIR/.config/nvim"
# Helper: skip symlink creation if the target is already managed by
# home-manager (symlink pointing into /nix/store). This prevents
# install.sh from clobbering paths that home-manager owns.
is_nix_managed() {
[ -L "$1" ] && readlink "$1" | grep -q '^/nix/store/'
}
# Remove old monolithic symlink if it exists
if [ -L "$NVIM_HOME" ]; then
rm "$NVIM_HOME"
fi
mkdir -p "$NVIM_HOME"
# Symlink top-level files
for f in init.lua lazy-lock.json; do
target="$NVIM_HOME/$f"
is_nix_managed "$target" && continue
[ -f "$NVIM_SRC/$f" ] && ln -sf "$NVIM_SRC/$f" "$target"
done
# Symlink top-level directories (except lua/)
for d in autoload ftplugin; do
target="$NVIM_HOME/$d"
is_nix_managed "$target" && continue
[ -d "$NVIM_SRC/$d" ] && ln -sfn "$NVIM_SRC/$d" "$target"
done
# Create lua/ as real directory with child symlinks
mkdir -p "$NVIM_HOME/lua"
# Symlink lua/ subdirectories
for d in config plugins user; do
target="$NVIM_HOME/lua/$d"
is_nix_managed "$target" && continue
[ -d "$NVIM_SRC/lua/$d" ] && ln -sfn "$NVIM_SRC/lua/$d" "$target"
done
# Symlink top-level lua files (ccremote.lua, etc.)
# Skip files already managed by home-manager (nix store symlinks)
for f in "$NVIM_SRC/lua/"*.lua; do
target="$NVIM_HOME/lua/$(basename "$f")"
is_nix_managed "$target" && continue
[ -f "$f" ] && ln -sf "$f" "$target"
done
# Tmux
ln -sf "$DOTFILES_DIR/.tmux.conf" "$HOME/.tmux.conf"
ln -sf "$DOTFILES_DIR/.tmux" "$HOME/.tmux"
# Claude Code
mkdir -p "$HOME/.claude"
is_nix_managed "$HOME/.claude/settings.json" || \
ln -sf "$DOTFILES_DIR/.claude/settings.json" "$HOME/.claude/settings.json"
if ! is_nix_managed "$HOME/.claude/hooks"; then
rm -rf "$HOME/.claude/hooks" 2>/dev/null || true
ln -sf "$DOTFILES_DIR/.claude/hooks" "$HOME/.claude/hooks"
fi
is_nix_managed "$HOME/.claude/statusline.sh" || \
ln -sf "$DOTFILES_DIR/.claude/statusline.sh" "$HOME/.claude/statusline.sh"
# Claude skills (symlink each to allow private skills)
CLAUDE_SKILLS_HOME="$HOME/.claude/skills"
# Ensure this is a real directory. A legacy monolithic symlink here can cause
# self-referential links like skills/<name>/<name> when we link each skill.
if [ -L "$CLAUDE_SKILLS_HOME" ]; then
rm "$CLAUDE_SKILLS_HOME"
fi
mkdir -p "$CLAUDE_SKILLS_HOME"
for skill in "$DOTFILES_DIR/.claude/skills/"*/; do
skill_name=$(basename "$skill")
target="$CLAUDE_SKILLS_HOME/$skill_name"
is_nix_managed "$target" && continue
ln -sf "$skill" "$target"
done
# Claude commands
CLAUDE_COMMANDS_HOME="$HOME/.claude/commands"
# Keep commands as a real directory for per-command symlinks.
if [ -L "$CLAUDE_COMMANDS_HOME" ]; then
rm "$CLAUDE_COMMANDS_HOME"
fi
mkdir -p "$CLAUDE_COMMANDS_HOME"
for cmd in "$DOTFILES_DIR/.claude/commands/"*; do
cmd_name=$(basename "$cmd")
target="$CLAUDE_COMMANDS_HOME/$cmd_name"
is_nix_managed "$target" && continue
ln -sf "$cmd" "$target"
done
# Install mise (polyglot version manager)
echo "==> Installing mise..."
if [ ! -f "$HOME/.local/bin/mise" ]; then
curl -fsSL https://mise.run -o /tmp/mise-install.sh
sh /tmp/mise-install.sh
rm /tmp/mise-install.sh
else
echo " mise already installed"
fi
# Setup gh credential helper if gh is available
if command -v gh &> /dev/null; then
echo "==> Configuring gh credential helper..."
gh auth setup-git 2>/dev/null || echo " (run 'gh auth login' first if not authenticated)"
fi
echo ""
echo "==> Done! Restart your shell or run: source ~/.bashrc"
echo ""
echo "Next steps:"
echo " 1. Run 'gh auth login' to authenticate with GitHub"
echo " 2. Run 'gh ssh-key add ~/.ssh/id_ed25519.pub -t devbox-signing --type signing' to enable commit signing"
echo " 3. Run 'gh auth setup-git' to configure git credential helper"
echo " 4. Run 'mise use python@3.x' to install Python (or other runtimes)"
echo " 5. Open nvim to let lazy.nvim install plugins"
echo ""
if [ -f "$HOME/.ssh/id_ed25519.pub" ]; then
echo "Your SSH public key (for GitHub):"
cat "$HOME/.ssh/id_ed25519.pub"
fi