brainy/docs/tools/claude-commit/dotfiles/setup-claude-commit.sh

237 lines
7.2 KiB
Bash
Raw Normal View History

#!/bin/bash
# Setup script for Claude Commit on any machine
# This script installs the claude-commit tool globally
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}==================================${NC}"
echo -e "${BLUE} Claude Commit Setup Script${NC}"
echo -e "${BLUE}==================================${NC}"
echo ""
# Create ~/.local/bin if it doesn't exist
echo -e "${YELLOW}Creating ~/.local/bin directory...${NC}"
mkdir -p ~/.local/bin
# Create the claude-commit script
echo -e "${YELLOW}Installing claude-commit script...${NC}"
cat > ~/.local/bin/claude-commit << 'EOF'
#!/bin/bash
# Claude Commit Message Generator - Global Version
# Automatically generates Conventional Commit messages using git diff
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Check if we're in a git repository
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo -e "${RED}Not in a git repository${NC}"
exit 1
fi
# Check if there are changes to commit
if [[ -z $(git status -s) ]]; then
echo -e "${RED}No changes to commit${NC}"
exit 1
fi
# Get the diff of staged changes (or all changes if nothing staged)
if [[ -n $(git diff --cached --name-only) ]]; then
DIFF=$(git diff --cached)
FILES=$(git diff --cached --name-only)
echo -e "${GREEN}Analyzing staged changes...${NC}"
else
DIFF=$(git diff)
FILES=$(git diff --name-only)
echo -e "${YELLOW}No staged changes. Analyzing all modified files...${NC}"
echo -e "${YELLOW}Run 'git add' first to stage specific changes${NC}"
fi
# Get project name from git remote or directory name
PROJECT_NAME=$(basename "$(git rev-parse --show-toplevel)")
REMOTE_URL=$(git config --get remote.origin.url 2>/dev/null)
if [[ -n "$REMOTE_URL" ]]; then
PROJECT_NAME=$(basename -s .git "$REMOTE_URL")
fi
# Create a prompt for Claude
PROMPT="Based on the following git diff from the '$PROJECT_NAME' project, generate a Conventional Commit message.
REQUIREMENTS:
1. Use Conventional Commit format: <type>(<scope>): <description>
2. Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
3. Keep first line under 72 characters
4. Use imperative mood (e.g., 'add' not 'added')
5. Include a detailed body explaining the purpose and impact
6. Note any breaking changes with 'BREAKING CHANGE:' prefix
7. Reference any issue numbers if apparent from the code
FILES CHANGED:
$FILES
GIT DIFF (showing first 500 lines):
$(echo "$DIFF" | head -n 500)
Generate ONLY the commit message, no explanations or markdown formatting."
# Call Claude API (using claude CLI)
echo -e "${GREEN}Generating commit message with Claude...${NC}"
# Save the prompt to a temporary file to avoid shell escaping issues
TEMP_PROMPT=$(mktemp)
echo "$PROMPT" > "$TEMP_PROMPT"
# Generate the commit message
COMMIT_MSG=$(claude code --no-markdown < "$TEMP_PROMPT" 2>/dev/null)
# Clean up temp file
rm "$TEMP_PROMPT"
# Check if message was generated
if [[ -z "$COMMIT_MSG" ]]; then
echo -e "${RED}Failed to generate commit message${NC}"
echo "Falling back to standard git commit..."
git commit
exit 1
fi
# Display the generated message
echo -e "${GREEN}Generated commit message:${NC}"
echo "----------------------------------------"
echo "$COMMIT_MSG"
echo "----------------------------------------"
# Ask for confirmation
echo -e "${YELLOW}Do you want to:${NC}"
echo " 1) Use this message"
echo " 2) Edit this message"
echo " 3) Cancel"
read -p "Choice [1-3]: " choice
case $choice in
1)
# Stage all changes if nothing is staged
if [[ -z $(git diff --cached --name-only) ]]; then
git add -A
fi
# Commit with the generated message
git commit -m "$COMMIT_MSG"
echo -e "${GREEN}✓ Committed successfully${NC}"
;;
2)
# Save message to temp file and open in editor
TEMP_MSG=$(mktemp)
echo "$COMMIT_MSG" > "$TEMP_MSG"
${EDITOR:-vim} "$TEMP_MSG"
# Stage all changes if nothing is staged
if [[ -z $(git diff --cached --name-only) ]]; then
git add -A
fi
# Commit with edited message
git commit -F "$TEMP_MSG"
rm "$TEMP_MSG"
echo -e "${GREEN}✓ Committed with edited message${NC}"
;;
3)
echo -e "${YELLOW}Commit cancelled${NC}"
exit 0
;;
*)
echo -e "${RED}Invalid choice. Commit cancelled${NC}"
exit 1
;;
esac
EOF
# Make the script executable
chmod +x ~/.local/bin/claude-commit
echo -e "${GREEN}✓ claude-commit script installed${NC}"
# Set up git aliases
echo -e "${YELLOW}Setting up git aliases...${NC}"
git config --global alias.cc '!~/.local/bin/claude-commit'
git config --global alias.smart-commit '!~/.local/bin/claude-commit'
echo -e "${GREEN}✓ Git aliases configured${NC}"
# Add ~/.local/bin to PATH if not already there
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
echo -e "${YELLOW}Adding ~/.local/bin to PATH...${NC}"
# Detect shell and update appropriate config file
if [[ -n "$ZSH_VERSION" ]]; then
SHELL_CONFIG="$HOME/.zshrc"
elif [[ -n "$BASH_VERSION" ]]; then
SHELL_CONFIG="$HOME/.bashrc"
else
SHELL_CONFIG="$HOME/.profile"
fi
echo '' >> "$SHELL_CONFIG"
echo '# Added by claude-commit setup' >> "$SHELL_CONFIG"
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$SHELL_CONFIG"
echo -e "${GREEN}✓ Added to $SHELL_CONFIG${NC}"
echo -e "${YELLOW}Please run: source $SHELL_CONFIG${NC}"
else
echo -e "${GREEN}✓ ~/.local/bin already in PATH${NC}"
fi
# Test the installation
echo ""
echo -e "${BLUE}Testing installation...${NC}"
if command -v claude-commit >/dev/null 2>&1 || [ -x ~/.local/bin/claude-commit ]; then
echo -e "${GREEN}✓ claude-commit is installed and executable${NC}"
else
echo -e "${YELLOW}⚠ claude-commit installed but not in PATH yet${NC}"
echo -e "${YELLOW} Please restart your terminal or run: source ~/.bashrc${NC}"
fi
if git config --global --get alias.cc >/dev/null 2>&1; then
echo -e "${GREEN}✓ git cc alias is configured${NC}"
else
echo -e "${RED}✗ git cc alias configuration failed${NC}"
fi
echo ""
echo -e "${GREEN}==================================${NC}"
echo -e "${GREEN} Installation Complete!${NC}"
echo -e "${GREEN}==================================${NC}"
echo ""
echo -e "${BLUE}Usage:${NC}"
echo -e " ${YELLOW}git cc${NC} - Generate and commit with Claude"
echo -e " ${YELLOW}git smart-commit${NC} - Alternative alias"
echo ""
echo -e "${BLUE}This works in any git repository!${NC}"
echo ""
# Create a sync script for dotfiles
echo -e "${YELLOW}Creating sync script...${NC}"
cat > ~/.local/bin/sync-claude-commit << 'SYNC_EOF'
#!/bin/bash
# Sync claude-commit from a remote source
SCRIPT_URL="https://raw.githubusercontent.com/yourusername/dotfiles/main/bin/claude-commit"
echo "Syncing claude-commit..."
curl -sSL "$SCRIPT_URL" > ~/.local/bin/claude-commit
chmod +x ~/.local/bin/claude-commit
echo "✓ claude-commit updated"
SYNC_EOF
chmod +x ~/.local/bin/sync-claude-commit
echo -e "${GREEN}✓ Sync script created at ~/.local/bin/sync-claude-commit${NC}"
echo -e "${YELLOW} (Update the URL in the script to your dotfiles repo)${NC}"