Help and docs
Sign in

grindlemire/dotfiles code browser

main 0375daa
162 lines · 5.4 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
#! /bin/zsh

Red="\033[0;31m"
Green='\033[0;32m'
Color_Off='\033[0m'

# Ensure ssh-agent is running for git operations
. ensure-ssh-agent > /dev/null 2>&1

create_pr=false
target_branch=""

# Parse arguments
if [ "$1" = "-push" ]; then
    create_pr=true
    shift
    target_branch="${1:-main}"
fi

# Get current branch name
current_branch=$(git branch 2>/dev/null | grep \* | awk -F '\\* ' '{$0=$2}1')
if [ -z "$current_branch" ]; then
    echo -e "${Red}Error: Not in a git repository${Color_Off}"
    exit 1
fi

# Fetch latest main branch
echo -e "${Green}Fetching latest main branch...${Color_Off}"
git fetch origin main --quiet 2>/dev/null || git fetch origin master --quiet 2>/dev/null

# Determine main branch name (main or master) - use for diff generation
main_branch="main"
if ! git rev-parse --verify origin/main >/dev/null 2>&1; then
    if git rev-parse --verify origin/master >/dev/null 2>&1; then
        main_branch="master"
    else
        echo -e "${Red}Error: Could not find main or master branch${Color_Off}"
        exit 1
    fi
fi

# If -push was specified but no target given, use the detected main branch
if [ "$create_pr" = true ] && [ -z "$target_branch" ]; then
    target_branch="$main_branch"
fi

# Get diff between current branch and main
echo -e "${Green}Generating PR title and description...${Color_Off}"
diff_output=$(git diff origin/${main_branch}..HEAD --diff-algorithm=minimal 2>/dev/null)

if [ -z "$diff_output" ]; then
    echo -e "${Red}Error: No differences found between ${current_branch} and ${main_branch}${Color_Off}"
    exit 1
fi

# Get commit log for context
commit_log=$(git log --oneline origin/${main_branch}..HEAD 2>/dev/null)

# Generate PR title and description using Claude
pr_content=$(echo -e "$commit_log\n\n---\n\n$diff_output" | claude -p "You are helping write a GitHub pull request. Based on the commit messages and code diff below, generate a title and description.

Title requirements:
- Short and descriptive (under 60 chars)
- Natural, conversational tone
- Describe what changed, not how
- No prefixes like 'feat:' or 'fix:' unless that's the actual convention used in the commits

Description requirements:
- Write like a developer explaining their work to a teammate
- Start with a brief 1-2 sentence summary of what this PR does
- List the key changes in bullet points
- Be specific about what actually changed
- NO corporate-speak, NO AI phrases like 'This PR introduces', 'enhances', 'leverages', 'streamlines'
- Keep it clear and direct
- Don't explain obvious things

Format your response exactly as:
TITLE: <your title here>

DESCRIPTION:
<your description here>

Now analyze these changes:" 2>/dev/null)
CLAUDE_EXIT=$?

if [ -z "$pr_content" ] || [ $CLAUDE_EXIT -ne 0 ]; then
    echo -e "${Red}Claude generation failed, using commit log${Color_Off}"
    # Extract first 2-3 words from the most recent commit message as title
    fallback_title=$(echo "$commit_log" | head -n 1 | sed 's/^[a-f0-9]* //' | awk '{print $1, $2}')
    pr_content="TITLE: ${fallback_title}\n\nDESCRIPTION:\n## Changes\n$(echo "$commit_log" | head -n 10 | sed 's/^/- /')"
fi

# Extract title and description
pr_title=$(echo "$pr_content" | grep -A 1 "^TITLE:" | tail -n 1 | sed 's/^[[:space:]]*//')
pr_description=$(echo "$pr_content" | sed -n '/^DESCRIPTION:/,$p' | sed '1d' | sed 's/^[[:space:]]*//')

# Fallback if extraction failed
if [ -z "$pr_title" ]; then
    # Use first 2 words from latest commit message
    pr_title=$(echo "$commit_log" | head -n 1 | sed 's/^[a-f0-9]* //' | awk '{print $1, $2}')
fi
if [ -z "$pr_description" ]; then
    pr_description="## Changes\n$(echo "$commit_log" | sed 's/^/- /')"
fi

# If -push was specified, create or update the PR
if [ "$create_pr" = true ]; then
    # Check if PR already exists for current branch
    echo -e "${Green}Checking for existing PR...${Color_Off}"
    existing_pr=$(gh pr list --head "$current_branch" --json number --jq '.[0].number' 2>/dev/null)

    if [ -n "$existing_pr" ]; then
        # Update existing PR
        echo -e "${Green}Updating existing PR #${existing_pr}...${Color_Off}"

        # Create temp file for description
        desc_file=$(mktemp)
        echo "$pr_description" > "$desc_file"

        gh pr edit "$existing_pr" --title "$pr_title" --body-file "$desc_file"
        edit_exit=$?
        rm -f "$desc_file"

        if [ $edit_exit -eq 0 ]; then
            echo -e "${Green}Successfully updated PR #${existing_pr}${Color_Off}"
            gh pr view "$existing_pr" --web
        else
            echo -e "${Red}Failed to update PR${Color_Off}"
            exit 1
        fi
    else
        # Create new PR
        echo -e "${Green}Creating new PR targeting ${target_branch}...${Color_Off}"

        # Push current branch to remote
        git push -u origin "$current_branch" 2>&1
        if [ $? -ne 0 ]; then
            echo -e "${Red}Failed to push branch${Color_Off}"
            exit 1
        fi

        # Create temp file for description
        desc_file=$(mktemp)
        echo "$pr_description" > "$desc_file"

        gh pr create --base "$target_branch" --title "$pr_title" --body-file "$desc_file" --web
        create_exit=$?
        rm -f "$desc_file"

        if [ $create_exit -ne 0 ]; then
            echo -e "${Red}Failed to create PR${Color_Off}"
            exit 1
        fi
    fi
else
    # Output in copyable format
    echo -e "\n${Green}=== PR Title ===${Color_Off}"
    echo "$pr_title"
    echo -e "\n${Green}=== PR Description ===${Color_Off}"
    echo "$pr_description"
    echo ""
fi