Skip to content

Commit ca1afa1

Browse files
foharaclaude
andcommitted
Add install script for global CLI installation
Adds scripts/install.sh with commands to install, reinstall, uninstall, and check status of the Lash CLI binary. Documents usage in README. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent c0d654a commit ca1afa1

2 files changed

Lines changed: 238 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,38 @@ cargo fmt --check
6969
cargo clippy --workspace -- -D warnings
7070
```
7171

72+
## Installation
73+
74+
Install Lash globally using the install script:
75+
76+
```bash
77+
# Install Lash to ~/.cargo/bin/lash
78+
./scripts/install.sh
79+
80+
# Force reinstall (useful for local development/testing)
81+
./scripts/install.sh reinstall
82+
83+
# Check installation status
84+
./scripts/install.sh status
85+
86+
# Uninstall
87+
./scripts/install.sh uninstall
88+
```
89+
90+
The script builds an optimized release binary and installs it to `~/.cargo/bin/lash`. Ensure `~/.cargo/bin` is in your PATH:
91+
92+
```bash
93+
export PATH="$HOME/.cargo/bin:$PATH"
94+
```
95+
96+
Alternatively, install directly with Cargo:
97+
98+
```bash
99+
cargo install --path crates/lash-cli # Install
100+
cargo install --path crates/lash-cli --force # Reinstall
101+
cargo uninstall lash-cli # Uninstall
102+
```
103+
72104
## Try the Playground
73105

74106
Want to explore Lash's features without setting up your own project? Try the playground!

‎scripts/install.sh‎

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#!/bin/bash
2+
# Lash CLI Installer
3+
# Builds and installs the Lash CLI globally via Cargo
4+
5+
set -e
6+
7+
# Colors for output
8+
RED='\033[0;31m'
9+
GREEN='\033[0;32m'
10+
YELLOW='\033[0;33m'
11+
BLUE='\033[0;34m'
12+
CYAN='\033[0;36m'
13+
BOLD='\033[1m'
14+
DIM='\033[2m'
15+
NC='\033[0m' # No Color
16+
17+
# Paths
18+
CARGO_BIN="$HOME/.cargo/bin"
19+
LASH_BINARY="$CARGO_BIN/lash"
20+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
22+
23+
# Print the Lash banner
24+
print_banner() {
25+
echo ""
26+
echo -e "${CYAN}${BOLD}┓ ┓${NC}"
27+
echo -e "${CYAN}${BOLD}┃ ┏┓┏┣┓${NC}"
28+
echo -e "${CYAN}${BOLD}┗┛┗┻┛┛┗${NC}"
29+
echo -e "${DIM}Minimalist task tracker for devs and agents${NC}"
30+
echo ""
31+
}
32+
33+
# Print usage
34+
usage() {
35+
echo -e "${BOLD}Usage:${NC} $0 [COMMAND]"
36+
echo ""
37+
echo -e "${BOLD}Commands:${NC}"
38+
echo -e " ${GREEN}install${NC} Build and install Lash globally ${DIM}(default)${NC}"
39+
echo -e " ${YELLOW}reinstall${NC} Force reinstall even if version unchanged"
40+
echo -e " ${RED}uninstall${NC} Remove Lash from system"
41+
echo -e " ${BLUE}status${NC} Check current installation status"
42+
echo -e " ${CYAN}help${NC} Show this help message"
43+
echo ""
44+
echo -e "${BOLD}Locations:${NC}"
45+
echo -e " ${DIM}Binary:${NC} $LASH_BINARY"
46+
echo -e " ${DIM}Source:${NC} $PROJECT_ROOT/crates/lash-cli"
47+
echo ""
48+
}
49+
50+
# Check if ~/.cargo/bin is in PATH
51+
check_path() {
52+
if [[ ":$PATH:" != *":$CARGO_BIN:"* ]]; then
53+
echo -e "${YELLOW}⚠️ Warning:${NC} $CARGO_BIN is not in your PATH"
54+
echo ""
55+
echo -e "${DIM}Add this to your shell config (~/.bashrc, ~/.zshrc, etc.):${NC}"
56+
echo -e " ${CYAN}export PATH=\"\$HOME/.cargo/bin:\$PATH\"${NC}"
57+
echo ""
58+
return 1
59+
fi
60+
return 0
61+
}
62+
63+
# Install Lash
64+
do_install() {
65+
local force_flag=""
66+
if [ "$1" = "--force" ]; then
67+
force_flag="--force"
68+
echo -e "${YELLOW}🔄 Reinstalling Lash...${NC}"
69+
else
70+
echo -e "${GREEN}📦 Installing Lash...${NC}"
71+
fi
72+
echo ""
73+
74+
# Change to project root
75+
cd "$PROJECT_ROOT"
76+
77+
echo -e "${DIM}Building release binary from crates/lash-cli...${NC}"
78+
echo -e "${DIM}This compiles with optimizations (LTO enabled) - may take a minute.${NC}"
79+
echo ""
80+
81+
# Run cargo install
82+
cargo install --path crates/lash-cli $force_flag
83+
84+
echo ""
85+
86+
# Verify installation
87+
if [ -x "$LASH_BINARY" ]; then
88+
echo -e "${GREEN}✅ Installation successful!${NC}"
89+
echo ""
90+
91+
# Check PATH
92+
if check_path; then
93+
echo -e "${DIM}Verifying installation...${NC}"
94+
echo ""
95+
"$LASH_BINARY" --version
96+
echo ""
97+
echo -e "${GREEN}🎉 Lash is ready to use!${NC}"
98+
echo -e "${DIM}Try: lash --help${NC}"
99+
else
100+
echo ""
101+
echo -e "${DIM}After updating your PATH, verify with:${NC}"
102+
echo -e " ${CYAN}lash --version${NC}"
103+
fi
104+
else
105+
echo -e "${RED}❌ Installation failed - binary not found${NC}"
106+
exit 1
107+
fi
108+
}
109+
110+
# Uninstall Lash
111+
do_uninstall() {
112+
echo -e "${RED}🗑️ Uninstalling Lash...${NC}"
113+
echo ""
114+
115+
if [ -x "$LASH_BINARY" ]; then
116+
echo -e "${DIM}Removing binary from $CARGO_BIN...${NC}"
117+
cargo uninstall lash-cli 2>/dev/null || rm -f "$LASH_BINARY"
118+
echo ""
119+
echo -e "${GREEN}✅ Lash has been uninstalled${NC}"
120+
121+
# Verify removal
122+
if command -v lash &> /dev/null; then
123+
echo -e "${YELLOW}⚠️ Note: 'lash' still found in PATH (maybe a different installation?)${NC}"
124+
echo -e "${DIM}Location: $(which lash)${NC}"
125+
else
126+
echo -e "${DIM}Verified: 'which lash' returns nothing${NC}"
127+
fi
128+
else
129+
echo -e "${YELLOW}⚠️ Lash is not installed at $LASH_BINARY${NC}"
130+
131+
# Check if it's installed elsewhere
132+
if command -v lash &> /dev/null; then
133+
echo -e "${DIM}Found lash elsewhere: $(which lash)${NC}"
134+
fi
135+
fi
136+
}
137+
138+
# Check installation status
139+
do_status() {
140+
echo -e "${BLUE}🔍 Checking Lash installation status...${NC}"
141+
echo ""
142+
143+
# Check binary
144+
echo -e "${BOLD}Binary:${NC}"
145+
if [ -x "$LASH_BINARY" ]; then
146+
echo -e " ${GREEN}✓${NC} Found at $LASH_BINARY"
147+
local version=$("$LASH_BINARY" --version 2>/dev/null || echo "unknown")
148+
echo -e " ${DIM}Version: $version${NC}"
149+
else
150+
echo -e " ${RED}✗${NC} Not found at $LASH_BINARY"
151+
fi
152+
echo ""
153+
154+
# Check PATH
155+
echo -e "${BOLD}PATH:${NC}"
156+
if check_path 2>/dev/null; then
157+
echo -e " ${GREEN}✓${NC} $CARGO_BIN is in PATH"
158+
else
159+
echo -e " ${YELLOW}✗${NC} $CARGO_BIN is not in PATH"
160+
fi
161+
echo ""
162+
163+
# Check which lash
164+
echo -e "${BOLD}which lash:${NC}"
165+
if command -v lash &> /dev/null; then
166+
echo -e " ${GREEN}✓${NC} $(which lash)"
167+
else
168+
echo -e " ${RED}✗${NC} Not found in PATH"
169+
fi
170+
echo ""
171+
172+
# Check source
173+
echo -e "${BOLD}Source:${NC}"
174+
if [ -f "$PROJECT_ROOT/crates/lash-cli/Cargo.toml" ]; then
175+
echo -e " ${GREEN}✓${NC} Found at $PROJECT_ROOT/crates/lash-cli"
176+
else
177+
echo -e " ${RED}✗${NC} Source not found (are you in the lash repo?)"
178+
fi
179+
}
180+
181+
# Main
182+
print_banner
183+
184+
case "${1:-install}" in
185+
install)
186+
do_install
187+
;;
188+
reinstall|force|--force)
189+
do_install --force
190+
;;
191+
uninstall|remove)
192+
do_uninstall
193+
;;
194+
status|check)
195+
do_status
196+
;;
197+
help|--help|-h)
198+
usage
199+
;;
200+
*)
201+
echo -e "${RED}❌ Unknown command: $1${NC}"
202+
echo ""
203+
usage
204+
exit 1
205+
;;
206+
esac

0 commit comments

Comments
 (0)