-
Notifications
You must be signed in to change notification settings - Fork 0
/
bb
203 lines (177 loc) · 7.01 KB
/
bb
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
#!/bin/bash
###############################################################################
# bb: A Simple Bitbucket CLI Tool
#
# Description:
# bb is a command-line interface tool designed to interact with Bitbucket
# repositories. It allows users to manage pull requests, comments, and more
# directly from the terminal, streamlining the development workflow.
#
# Author:
# Oleksandr Manzyuk <alexander.manzyuk@gooroo.dev>
#
# License:
# MIT License. See the LICENSE file in the project root for full license information:
# https://github.com/gooroo-dev/bitbucket-cli/blob/main/LICENSE
#
# Repository:
# https://github.com/gooroo-dev/bitbucket-cli
#
# Version:
# 1.0.0
#
###############################################################################
# Ensure required environment variables are set
if [[ -z "$BITBUCKET_USERNAME" || -z "$BITBUCKET_APP_PASSWORD" ]]; then
echo "Error: BITBUCKET_USERNAME and BITBUCKET_APP_PASSWORD environment variables must be set."
exit 1
fi
# Check if inside a Git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "Error: This command must be run inside a Git repository."
exit 1
fi
# Function to display usage
usage() {
echo "Usage: bb pr <command> [arguments]"
echo ""
echo "Commands:"
echo " list List all pull requests in the repository."
echo " info <pull_request_id> Get information about a specific pull request."
echo " diff <pull_request_id> Get the diff of a pull request."
echo " comment <pull_request_id> <file_path> <line> <comment> Add a comment to a specific line."
echo " comments <pull_request_id> List all comments on a pull request."
exit 1
}
# Function to make authenticated requests
make_request() {
local url="$1"
local method="$2"
local data="$3"
# echo "curl -s -u $BITBUCKET_USERNAME:$BITBUCKET_APP_PASSWORD -X $method -H 'Content-Type: application/json' -d \"$data\" $url" >&2
curl -s -u "$BITBUCKET_USERNAME:$BITBUCKET_APP_PASSWORD" \
-X "$method" \
-H "Content-Type: application/json" \
-d "$data" \
"$url"
}
# Function to parse Git remote URL and extract workspace and repository
get_workspace_repo() {
local remote_url
remote_url=$(git config --get remote.origin.url)
if [[ -z "$remote_url" ]]; then
echo "Error: No remote origin found in this Git repository."
exit 1
fi
# Handle SSH URL: git@bitbucket.org:workspace/repo.git
if [[ "$remote_url" =~ git@bitbucket\.org:(.+)/(.+)\.git ]]; then
WORKSPACE="${BASH_REMATCH[1]}"
REPO="${BASH_REMATCH[2]}"
# Handle HTTPS URL: https://bitbucket.org/workspace/repo.git
elif [[ "$remote_url" =~ https://bitbucket\.org/([^/]+)/([^/]+)(\.git)? ]]; then
WORKSPACE="${BASH_REMATCH[1]}"
REPO="${BASH_REMATCH[2]}"
else
echo "Error: Unsupported remote URL format. Please ensure the remote origin points to Bitbucket."
exit 1
fi
}
# Get workspace and repository from Git remote
get_workspace_repo
# Construct base API URL
API_BASE_URL="https://api.bitbucket.org/2.0/repositories/${WORKSPACE}/${REPO}"
# Ensure at least two arguments are provided
if [ $# -lt 2 ]; then
usage
fi
# Parse main command
COMMAND=$1
SUBCOMMAND=$2
case $COMMAND in
pr)
case $SUBCOMMAND in
list)
if [ $# -ne 2 ]; then
echo "Usage: bb pr list"
exit 1
fi
# Bitbucket API: GET /2.0/repositories/{workspace}/{repo}/pullrequests
API_URL="${API_BASE_URL}/pullrequests?state=OPEN"
RESPONSE=$(make_request "$API_URL" "GET")
echo "$RESPONSE" | jq
;;
info)
if [ $# -ne 3 ]; then
echo "Usage: bb pr info <pull_request_id>"
exit 1
fi
PR_ID=$3
# Bitbucket API: GET /2.0/repositories/{workspace}/{repo}/pullrequests/{pull_request_id}
API_URL="${API_BASE_URL}/pullrequests/${PR_ID}"
RESPONSE=$(make_request "$API_URL" "GET")
echo "$RESPONSE" | jq
;;
diff)
if [ $# -ne 3 ]; then
echo "Usage: bb [-v] pr diff <pull_request_id>" >&2
exit 1
fi
PR_ID=$3
# Fetch PR info to get the diff URL
PR_INFO_URL="${API_BASE_URL}/pullrequests/${PR_ID}"
PR_INFO_RESPONSE=$(make_request "$PR_INFO_URL" "GET")
# Extract the diff URL using jq
DIFF_URL=$(echo "$PR_INFO_RESPONSE" | jq -r '.links.diff.href')
# Check if DIFF_URL is not null or empty
if [[ -z "$DIFF_URL" || "$DIFF_URL" == "null" ]]; then
echo "Error: Diff URL not found for pull request ID: $PR_ID" >&2
exit 1
fi
# Fetch the diff using the extracted URL
# The diff URL might require specific headers; set Accept to text/plain
DIFF_RESPONSE=$(make_request "$DIFF_URL" "GET" "" "Accept: text/plain")
# Check if DIFF_RESPONSE is not empty
if [[ -z "$DIFF_RESPONSE" ]]; then
echo "No diff available for pull request ID: $PR_ID" >&2
exit 1
fi
echo "$DIFF_RESPONSE"
;;
comment)
if [ $# -ne 6 ]; then
echo "Usage: bb pr comment <pull_request_id> <file_path> <line> <comment>"
exit 1
fi
PR_ID=$3
FILE_PATH=$4
LINE=$5
COMMENT=$6
# Bitbucket API: POST /2.0/repositories/{workspace}/{repo}/pullrequests/{pull_request_id}/comments
COMMENTS_URL="${API_BASE_URL}/pullrequests/${PR_ID}/comments"
DATA=$(jq -n --arg path "$FILE_PATH" --argjson line "$LINE" --arg text "$COMMENT" \
'{content: {raw: $text}, inline: {path: $path, to: $line, from: $line}}')
RESPONSE=$(make_request "$COMMENTS_URL" "POST" "$DATA")
echo "$RESPONSE" | jq
;;
comments)
if [ $# -ne 3 ]; then
echo "Usage: bb pr comments <pull_request_id>"
exit 1
fi
PR_ID=$3
# Bitbucket API: GET /2.0/repositories/{workspace}/{repo}/pullrequests/{pull_request_id}/comments
COMMENTS_URL="${API_BASE_URL}/pullrequests/${PR_ID}/comments"
RESPONSE=$(make_request "$COMMENTS_URL" "GET")
echo "$RESPONSE" | jq
;;
*)
echo "Unknown subcommand for pr: $SUBCOMMAND"
usage
;;
esac
;;
*)
echo "Unknown command: $COMMAND"
usage
;;
esac