-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTaskfile.yml
More file actions
225 lines (202 loc) · 7.74 KB
/
Taskfile.yml
File metadata and controls
225 lines (202 loc) · 7.74 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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
version: '3'
vars:
# Resolved once per run. Points at the user gem bin so bundle/rubocop are
# always found without root and without needing rbenv initialised.
GEM_BIN:
sh: ruby -e 'puts Gem.user_dir + "/bin"'
tasks:
# Development setup
up:
desc: "Install development dependencies (dev tools + Ruby gems)"
cmds:
- |
# Install shell dev tools required for task test:unit and task style
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install bats-core shellcheck shfmt
elif [[ -f /etc/arch-release ]]; then
sudo pacman -S --needed --noconfirm bats shellcheck shfmt
else
sudo apt-get install -y bats shellcheck
# shfmt not in apt on older Ubuntu; install via go if available
if command -v go >/dev/null 2>&1; then
go install mvdan.cc/sh/v3/cmd/shfmt@latest
fi
fi
echo "✓ Dev tools installed"
- |
REQUIRED_BUNDLER="4.0.3"
BUNDLE_BIN="{{.GEM_BIN}}/bundle"
# Install the required bundler version to the user gem dir if missing
if ! "${BUNDLE_BIN}" --version 2>/dev/null | grep -q "${REQUIRED_BUNDLER}"; then
echo "Installing bundler ${REQUIRED_BUNDLER}..."
gem install bundler -v "${REQUIRED_BUNDLER}" --user-install
fi
# Set global bundle config so all projects install gems to the user gem dir
# and never require root. This persists in ~/.bundle/config.
"${BUNDLE_BIN}" config set --global path "$(ruby -e 'puts Gem.user_dir')"
"${BUNDLE_BIN}" config set --global bin "{{.GEM_BIN}}"
"${BUNDLE_BIN}" install
echo "Setup NPM"
npm install
- echo "✓ Development dependencies installed"
# Installation
install:
desc: "Run the installation script"
cmds:
- ./install.sh
# Stow dotfiles
stow:
desc: "Re-stow the home directory"
deps:
- generate:ghostty
cmds:
- stow home -d "./" -t $HOME --adopt
# Clean everything
clean:
desc: "Clean all generated files and state"
cmds:
- docker compose -f test/integration/docker-compose.yml down -v 2>/dev/null || true
- rm -f ./tmp/test-*.log
- echo "✓ Cleaned all generated files and state"
# Style (lint and fix)
style:
desc: "Run ShellCheck linting and auto-fix formatting"
cmds:
- shellcheck install.sh home/bin/lib/*.sh
- |
for f in home/bin/*; do
[[ -f "$f" ]] || continue
if head -1 "$f" | grep -q 'bash'; then
shellcheck "$f"
fi
done
- |
if command -v shfmt >/dev/null 2>&1; then
shfmt -i 2 -w install.sh
echo "✓ Scripts formatted"
fi
- echo "✓ All scripts passed ShellCheck"
- bundle exec rubocop -A src/install.rb
- echo "✓ All Ruby files passed RuboCop"
# Build
build:
desc: "Build Docker images for integration tests"
cmds:
- |
if ! docker compose version >/dev/null 2>&1; then
echo "Error: docker compose not available"
exit 1
fi
- echo "Building integration test images..."
- docker compose -f test/integration/docker-compose.yml build --parallel
- echo "✓ All integration test images built successfully"
build:clean:
desc: "Rebuild Docker images from scratch (no cache)"
cmds:
- |
if ! docker compose version >/dev/null 2>&1; then
echo "Error: docker compose not available"
exit 1
fi
- echo "Removing existing images..."
- docker compose -f test/integration/docker-compose.yml down --rmi all -v 2>/dev/null || true
- docker image rm -f shell-test:ubuntu-22 shell-test:ubuntu-24 shell-test:arch shell-test:debian 2>/dev/null || true
- echo "Rebuilding all images from scratch..."
- docker compose -f test/integration/docker-compose.yml build --no-cache --parallel
- echo "✓ All integration test images rebuilt successfully"
# Testing
test:
desc: "Run all tests (unit + integration + bin)"
deps:
- test:unit
- test:integration
- test:bin
test:unit:
desc: "Run unit tests (Ruby installer + pi extensions)"
cmds:
- |
echo "Running Ruby installer unit tests..."
ruby test/unit/test_installer.rb
echo "✓ Ruby installer tests passed"
- |
BUN="${HOME}/.bun/bin/bun"
if ! "$BUN" --version >/dev/null 2>&1; then
echo "Warning: bun not found at ${BUN}, skipping pi extension tests"
exit 0
fi
EXT_DIR="home/.pi/agent/extensions/custom-tools"
if [ ! -d "${EXT_DIR}/node_modules" ]; then
echo "Installing pi extension test dependencies..."
(cd "${EXT_DIR}" && "$BUN" install)
fi
(cd "${EXT_DIR}" && "$BUN" test test/)
test:bin:
desc: "Run home/bin/ tool tests (BATS + Ruby)"
cmds:
- bats home/bin/test/bats/*.bats
- bundle exec ruby -e "Dir.glob('home/bin/test/**/*.rb').sort.each { |f| require_relative f }"
test:opencode:
desc: "Run OpenCode plugin tests with Bun"
cmds:
- |
BUN="${HOME}/.bun/bin/bun"
if ! "$BUN" --version >/dev/null 2>&1; then
echo "Error: bun not found at ${BUN}"
exit 1
fi
- ${HOME}/.bun/bin/bun test ${HOME}/.config/opencode/plugins/test/*.test.ts
test:integration:
desc: "Run integration tests with Docker (requires 'task build' first). Use CLI_ARGS to specify platforms: task test:integration -- ubuntu-22 debian"
cmds:
- |
if ! docker compose version >/dev/null 2>&1; then
echo "Error: docker compose not available"
exit 1
fi
- |
# Check if images exist
if ! docker image inspect shell-test:ubuntu-22 >/dev/null 2>&1; then
echo "Error: Integration test images not built. Run 'task build' first."
exit 1
fi
- test/integration/run-install-test.sh {{.CLI_ARGS}}
# Generate configs
generate:
desc: "Generate .zshrc, .gitconfig, opencode.jsonc, and ghostty config"
deps:
- generate:zsh
- generate:gitconfig
- generate:opencode
- generate:ghostty
generate:zsh:
desc: "Re-generate .zshrc and completions"
cmds:
- $HOME/src/github.com/kalindudc/shell/src/generate_zshrc.rb
generate:gitconfig:
desc: "Re-generate .gitconfig"
cmds:
- |
if [[ -z "${GIT_EMAIL:-}" ]]; then
export GIT_EMAIL=$(git config --global user.email 2>/dev/null || echo "")
fi
if [[ -z "${GIT_NAME:-}" ]]; then
export GIT_NAME=$(git config --global user.name 2>/dev/null || echo "")
fi
if [[ -z "${GIT_SIGNING_KEY:-}" ]]; then
export GIT_SIGNING_KEY=$(git config --global user.signingkey 2>/dev/null || echo "")
fi
- $HOME/src/github.com/kalindudc/shell/src/generate_tempate.rb -i $HOME/src/github.com/kalindudc/shell/src/templates/.gitconfig.erb -o $HOME/src/github.com/kalindudc/shell/home/.gitconfig
generate:opencode:
desc: "Merge opencode.jsonc template into ~/.config/opencode/opencode.jsonc (preserves user customizations)"
cmds:
- |
# OPENCODE_PROFILE defaults to "personal" in the script.
# Set it in your shell env or .env to "work" for the work machine profile.
# GROQ_API_KEY is optional; when set, enables Groq critic models (personal only).
# OLLAMA_MODELS is optional; space-separated list, e.g. "qwen3:8b llama4:scout".
# Set OLLAMA_MODELS="" to omit the ollama provider block.
$HOME/src/github.com/kalindudc/shell/src/generate_opencode_config.rb
generate:ghostty:
desc: "Generate OS-specific ghostty font-size override config"
cmds:
- $HOME/src/github.com/kalindudc/shell/src/generate_ghostty_config.rb