Skip to content

Commit a85224d

Browse files
authored
Update fetch_github_repos_names.sh
1 parent a15d9bf commit a85224d

File tree

1 file changed

+55
-39
lines changed

1 file changed

+55
-39
lines changed

src/fetch_github_repos_names.sh

+55-39
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,108 @@
11
#!/bin/bash
2+
set -euo pipefail
23

34
# Script Name: fetch_github_repos_names.sh
45
# Description: Fetches and lists all repositories of a GitHub user.
5-
# It lists both public and private repositories if a personal access token is provided.
6-
# Usage: fetch_github_repos.sh [github_username] [github_token]
7-
# github_username - Optional. The GitHub username for which to fetch repositories.
8-
# github_token - Optional. A GitHub personal access token for accessing private repositories.
9-
# Example: ./fetch_github_repos_names.sh johnsmith [token]
6+
# Lists both public and private repositories if a personal access token is provided.
7+
# Usage: ./fetch_github_repos_names.sh [github_username] [github_token]
8+
# Example: ./fetch_github_repos_names.sh johnsmith YOUR_GITHUB_TOKEN
9+
10+
# Display usage message and exit
11+
usage() {
12+
echo "Usage: $0 [github_username] [github_token]"
13+
echo " github_username - Optional. GitHub username to fetch repositories for."
14+
echo " github_token - Optional. Personal access token to access private repositories."
15+
exit 1
16+
}
1017

1118
echo "GitHub Repository Fetcher"
1219

13-
# Function to check if jq is installed
20+
# Check if jq is installed
1421
check_jq_installed() {
1522
if ! command -v jq &>/dev/null; then
1623
echo "Error: jq is not installed. Please install jq to run this script."
1724
exit 1
1825
fi
1926
}
2027

21-
# Function to get authenticated user's login
28+
# Get authenticated user's login using provided token
2229
get_authenticated_user() {
23-
local token=$1
24-
local auth_header=""
25-
local user_login=""
30+
local token="$1"
31+
local auth_header="Authorization: token $token"
32+
local user_login
33+
user_login=$(curl -s -H "$auth_header" https://api.github.com/user | jq -r '.login')
34+
echo "$user_login"
35+
}
2636

27-
if [ -n "$token" ]; then
28-
auth_header="Authorization: token $token"
29-
user_login=$(curl -s -H "$auth_header" https://api.github.com/user | jq -r '.login')
37+
# Global variable for authorization header (set in main)
38+
auth_header=""
39+
40+
# Fetch a page with a single curl call to get both headers and body
41+
# The function echoes the body and sets the global variable 'next_url' if more pages exist.
42+
fetch_page() {
43+
local url="$1"
44+
# Fetch headers and body together
45+
local response
46+
response=$(curl -s -D - "$url" -H "$auth_header")
47+
# Separate headers (everything until the first blank line)
48+
local header
49+
header=$(printf "%s" "$response" | sed -n '1,/^$/p')
50+
# Separate body (everything after the first blank line)
51+
local body
52+
body=$(printf "%s" "$response" | sed -n '/^$/,$p' | sed '1d')
53+
# Extract next page URL from the Link header, if available
54+
if [[ "$header" =~ \<([^>]+)\>\;\ *rel=\"next\" ]]; then
55+
next_url="${BASH_REMATCH[1]}"
56+
else
57+
next_url=""
3058
fi
31-
32-
echo "$user_login"
59+
echo "$body"
3360
}
3461

3562
# Main function
3663
main() {
3764
check_jq_installed
3865

3966
if [ "$#" -gt 2 ]; then
40-
echo "Usage: $0 [github_username] [github_token]"
41-
exit 1
67+
usage
4268
fi
4369

44-
local USERNAME=${1:-}
45-
local GITHUB_TOKEN=${2:-}
70+
local USERNAME="${1:-}"
71+
local GITHUB_TOKEN="${2:-}"
4672
local AUTHENTICATED_USER=""
4773

4874
if [ -n "$GITHUB_TOKEN" ]; then
75+
auth_header="Authorization: token $GITHUB_TOKEN"
4976
AUTHENTICATED_USER=$(get_authenticated_user "$GITHUB_TOKEN")
5077
if [ -z "$AUTHENTICATED_USER" ] || [ "$AUTHENTICATED_USER" = "null" ]; then
5178
echo "Error: Invalid or expired GitHub token."
5279
exit 1
5380
fi
81+
else
82+
auth_header=""
5483
fi
5584

56-
# Determine which endpoint to use
5785
local URL=""
86+
# Determine API endpoint to use
5887
if [ -n "$GITHUB_TOKEN" ] && { [ -z "$USERNAME" ] || [ "$USERNAME" = "$AUTHENTICATED_USER" ]; }; then
59-
# Fetch all repos (public and private) of authenticated user
6088
URL="https://api.github.com/user/repos?per_page=100"
6189
echo "Fetching repositories for authenticated user '$AUTHENTICATED_USER'..."
6290
elif [ -n "$USERNAME" ]; then
63-
# Fetch public repos of specified user
6491
URL="https://api.github.com/users/$USERNAME/repos?per_page=100"
6592
echo "Fetching public repositories for user '$USERNAME'..."
6693
else
6794
echo "Error: Username required if no token is provided."
68-
exit 1
95+
usage
6996
fi
7097

7198
echo "--------------------------------"
7299

73-
local auth_header=""
74-
if [ -n "$GITHUB_TOKEN" ]; then
75-
auth_header="Authorization: token $GITHUB_TOKEN"
76-
fi
77-
78-
# Fetch repos with pagination
100+
# Fetch repositories with pagination
79101
while [ -n "$URL" ]; do
80-
response=$(curl -s -H "$auth_header" "$URL")
81-
echo "$response" | jq -r '.[] | .name'
82-
83-
# Get the 'next' URL from the 'Link' header
84-
link_header=$(curl -s -I -H "$auth_header" "$URL" | grep -i '^Link: ' | tr -d '\r\n')
85-
if [[ $link_header =~ \<([^>]+)\>\;[[:space:]]rel=\"next\" ]]; then
86-
URL="${BASH_REMATCH[1]}"
87-
else
88-
URL=""
89-
fi
102+
local page_body
103+
page_body=$(fetch_page "$URL")
104+
echo "$page_body" | jq -r '.[] | .name'
105+
URL="$next_url"
90106
done
91107

92108
echo "--------------------------------"

0 commit comments

Comments
 (0)