#!/bin/bash # Color codes using tput for better terminal compatibility RED=$(tput setaf 1) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3) BLUE=$(tput setaf 4) RESET=$(tput sgr0) # Usage instructions usage() { echo "${BLUE}Usage:${RESET} $0" echo "Lists all public repositories owned by the authenticated user and their organizations." echo "\nMake sure GITHUB_TOKEN is set in your environment (with 'public_repo' or 'repo' scope)." echo "You can set GITHUB_TOKEN in your ~/.zshrc (for Zsh users), ~/.bashrc (for Bash users), or in a .env file in this directory." echo "\nOptions:" echo " -h, --help Show this help message and exit." } # Check for help flag if [[ "$1" == "-h" || "$1" == "--help" ]]; then usage exit 0 fi # Check for required tools for tool in jq curl; do if ! command -v $tool &>/dev/null; then echo "${RED}❌ Error: Required tool '$tool' is not installed. Please install it and try again.${RESET}" exit 1 fi done # Load environment variables if [[ -f .env ]]; then export $(grep -v '^#' .env | xargs) fi if [[ -z "$GITHUB_TOKEN" ]]; then echo "${RED}❌ Error: GITHUB_TOKEN is not set.\nSet it in your environment (e.g., export GITHUB_TOKEN=... in ~/.zshrc or ~/.bashrc) or in a .env file.${RESET}" exit 1 fi # Function to check for API errors check_api_error() { local response="$1" local error_message=$(echo "$response" | jq -r 'if type == "object" and has("message") then .message else empty end') if [[ -n "$error_message" ]]; then echo "${RED}❌ GitHub API Error: $error_message${RESET}" return 1 fi local is_array=$(echo "$response" | jq -r 'if type == "array" then "true" else "false" end') if [[ "$is_array" != "true" ]]; then echo "${RED}❌ GitHub API Error: Unexpected response format${RESET}" return 1 fi return 0 } # Validate GitHub token before proceeding VALIDATE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user) TOKEN_ERROR=$(echo "$VALIDATE" | jq -r '.message // empty') if [[ -n "$TOKEN_ERROR" ]]; then echo "${RED}❌ Invalid or unauthorized GITHUB_TOKEN: $TOKEN_ERROR${RESET}" echo "${YELLOW}👉 Please check your token value and permissions at https://github.com/settings/tokens${RESET}" echo "${BLUE}💡 Make sure to set your GITHUB_TOKEN in your ~/.zshrc (for Zsh), ~/.bashrc (for Bash), or a .env file in this directory.${RESET}" exit 1 fi # Fetch user public repos echo "${BLUE}🔍 Fetching all public repositories owned by user...${RESET}" RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/user/repos?per_page=100&type=public") if check_api_error "$RESPONSE"; then USER_PUBLIC_REPOS=$(echo "$RESPONSE" | jq -r '.[].full_name') if [[ -z "$USER_PUBLIC_REPOS" ]]; then echo "${YELLOW}🚫 No public repositories found for user.${RESET}" else printf "${GREEN}=> 📂 Public Repositories%s${RESET}\n" " (User-Owned)" > /dev/tty echo "$USER_PUBLIC_REPOS" echo "--------------------------------------------" fi else echo "${RED}❌ Failed to fetch user repositories.${RESET}" fi # Fetch organizations echo "${BLUE}🔍 Fetching organizations...${RESET}" RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/user/orgs") if check_api_error "$RESPONSE"; then ORG_LIST=$(echo "$RESPONSE" | jq -r '.[].login') if [[ -z "$ORG_LIST" ]]; then echo "${YELLOW}🚫 No organizations found for user.${RESET}" exit 0 fi else echo "${RED}❌ Failed to fetch organizations.${RESET}" exit 1 fi # Fetch org public repos echo "${BLUE}🔍 Fetching all public repositories under organizations...${RESET}" for ORG in $ORG_LIST; do RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/orgs/$ORG/repos?per_page=100&type=public") if check_api_error "$RESPONSE"; then ORG_PUBLIC_REPOS=$(echo "$RESPONSE" | jq -r '.[].full_name') if [[ -z "$ORG_PUBLIC_REPOS" ]]; then echo "${YELLOW}🚫 No public repositories found in organization: $ORG${RESET}" else printf "${GREEN}=> 📂 Public Repositories%s${RESET}\n" " ($ORG)" > /dev/tty echo "$ORG_PUBLIC_REPOS" fi else echo "${RED}❌ Failed to fetch repositories for organization: $ORG${RESET}" fi echo "--------------------------------------------" done