|
#!/bin/bash |
|
|
|
usage() { |
|
echo "Usage: $0 -u <bitbucket_username> -p <bitbucket_app_password> -w <workspace_id> -b <branch1[,branch2,...]> [-d <destination_directory>]" |
|
exit 1 |
|
} |
|
|
|
DESTINATION_DIR="repositories" |
|
|
|
while getopts ":u:p:w:b:d:" opt; do |
|
case $opt in |
|
u) |
|
BITBUCKET_USERNAME="$OPTARG" |
|
;; |
|
p) |
|
BITBUCKET_APP_PASSWORD="$OPTARG" |
|
;; |
|
w) |
|
WORKSPACE_ID="$OPTARG" |
|
;; |
|
b) |
|
IFS=',' read -ra BRANCHES <<< "$OPTARG" |
|
;; |
|
d) |
|
DESTINATION_DIR="$OPTARG" |
|
;; |
|
\?) |
|
echo "Invalid option: -$OPTARG" >&2 |
|
usage |
|
;; |
|
:) |
|
echo "Option -$OPTARG requires an argument." >&2 |
|
usage |
|
;; |
|
esac |
|
done |
|
|
|
if [ -z "$BITBUCKET_USERNAME" ] || [ -z "$BITBUCKET_APP_PASSWORD" ] || [ -z "$WORKSPACE_ID" ] || [ ${#BRANCHES[@]} -eq 0 ]; then |
|
usage |
|
fi |
|
|
|
# Initialize the API URL and repositories variable |
|
API_URL="https://api.bitbucket.org/2.0/repositories/$WORKSPACE_ID?pagelen=100" |
|
REPOSITORIES="" |
|
PAGE_NUMBER=1 |
|
|
|
# Iterate through the paginated API response |
|
while [ -n "$API_URL" ]; do |
|
echo "Fetching repositories from page $PAGE_NUMBER..." |
|
# Get the current page of repositories |
|
PAGE_RESPONSE=$(curl -s -u "$BITBUCKET_USERNAME:$BITBUCKET_APP_PASSWORD" "$API_URL") |
|
|
|
# Extract the repositories and append them to the list |
|
REPOSITORIES+=$(echo "$PAGE_RESPONSE" | jq -r '.values[] | "\(.project.key) \(.name) \(.links.clone[] | select(.name == "ssh") | .href)"')$'\n' |
|
|
|
# Check for a "next" value in the response, indicating another page of results |
|
API_URL=$(echo "$PAGE_RESPONSE" | jq -r 'if .next then .next else "" end') |
|
|
|
# Increment the page number |
|
PAGE_NUMBER=$((PAGE_NUMBER + 1)) |
|
done |
|
|
|
REPO_COUNT=$(echo "$REPOSITORIES" | grep -c -v '^$') |
|
|
|
# Check if no repositories are found |
|
if [ $REPO_COUNT -eq 0 ]; then |
|
echo "No repositories found in the specified workspace." |
|
exit 0 |
|
fi |
|
|
|
echo "Total repositories: $REPO_COUNT" |
|
echo "Repositories:" |
|
echo "$REPOSITORIES" |
|
|
|
# Create the destination directory if it doesn't exist |
|
mkdir -p "$DESTINATION_DIR" |
|
|
|
# Iterate through the repositories and clone or pull them |
|
while read -r PROJECT_KEY REPO_NAME REPO_URL; do |
|
if [ -n "$REPO_URL" ]; then |
|
# Convert project key to lowercase |
|
PROJECT_KEY_LOWER=$(echo "$PROJECT_KEY" | tr '[:upper:]' '[:lower:]') |
|
|
|
REPO_PATH="$DESTINATION_DIR/$PROJECT_KEY_LOWER/$REPO_NAME" |
|
|
|
if [ -d "$REPO_PATH" ]; then |
|
echo "Pulling the latest changes for $REPO_NAME" |
|
cd "$REPO_PATH" || exit |
|
git fetch |
|
git pull || { echo "Failed to pull $REPO_NAME. Continuing with the next repository."; continue; } |
|
else |
|
echo "Cloning $REPO_NAME to $REPO_PATH" |
|
mkdir -p "$DESTINATION_DIR/$PROJECT_KEY_LOWER" && cd "$DESTINATION_DIR/$PROJECT_KEY_LOWER" || exit |
|
git clone "$REPO_URL" "$REPO_NAME" || { echo "Failed to clone $REPO_NAME. Continuing with the next repository."; continue; } |
|
cd "$REPO_NAME" || exit |
|
fi |
|
|
|
# Check out the branches passed as arguments |
|
for branch in "${BRANCHES[@]}"; do |
|
if git show-ref --quiet "refs/remotes/origin/$branch"; then |
|
echo "Checking out branch $branch" |
|
git checkout "$branch" |
|
git pull || { echo "Failed to pull $branch in $REPO_NAME. Continuing with the next branch."; continue; } |
|
fi |
|
done |
|
|
|
cd ../../.. |
|
|
|
# Decrease the repository count and print the number of remaining repositories |
|
REPO_COUNT=$((REPO_COUNT - 1)) |
|
echo "Repositories remaining: $REPO_COUNT" |
|
fi |
|
done <<< "$REPOSITORIES" |