Last active
February 9, 2022 21:40
-
-
Save arledesma/7e28e2ffee380fa329f3ab13ee8e9ccf to your computer and use it in GitHub Desktop.
Clone all repositories from an organization.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -e | |
# DRY_RUN=1 | |
readonly DEFAULT_ORG="mindstream-it"; | |
readonly DEFAULT_GITHUB_BASE="${HOME}/src/github.com"; | |
readonly DEFAULT_GITHUB_API_BASE="https://api.github.com/orgs"; | |
readonly GITHUB_TOKEN_ERROR_MESSAGE="Variable must be set to the value of a PAT. See https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token for creating a PAT."; | |
function __log { | |
local -r log_level="${1:-quiet}"; | |
if [ "${LOG_LEVEL:-quiet}" = "quiet" ]; | |
then | |
return 0; | |
fi | |
if [ "${LOG_LEVEL}" = "$log_level" ]; | |
then | |
case $log_level in | |
verbose | debug) | |
echo "$2"; | |
;; | |
*) | |
echo "$log_level: $2"; | |
;; | |
esac | |
fi | |
} | |
function __log_verbose { | |
__log "verbose" "$*"; | |
} | |
function __log_debug { | |
__log "debug" "$*"; | |
} | |
function __git { | |
if [ -n "${DRY_RUN:-""}" ]; | |
then | |
echo >&2 "DRY RUN: git $*"; | |
return | |
fi | |
"$(command -v git)" "$@" | |
} | |
function ensure_org_dir { | |
local -r github_base="${1:-$DEFAULT_GITHUB_BASE}"; | |
local -r org="$2"; | |
mkdir -p "$github_base"; | |
pushd "$github_base" &>/dev/null; | |
mkdir -p "$org"; | |
popd &>/dev/null; | |
} | |
function mirror_org_repos { | |
local -r github_base="${1:-$DEFAULT_GITHUB_BASE}"; | |
local -r org="$2"; | |
local -r token="$3"; | |
# local -r repos_json="$(curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${token}" "${DEFAULT_GITHUB_API_BASE}/${org}/repos?per_page=200")" | |
local repos_json; | |
if [ -n "$(command -v gh)" ]; then | |
repos_json="$(gh repo list quantum-sec --no-archived --limit 300 --json name,sshUrl,defaultBranchRef --jq '[.[] | {ssh_url: .sshUrl, default_branch: .defaultBranchRef.name}]')"; | |
elif [ -n "$(command -v curl)" ]; then | |
repos_json="$(curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${token}" "${DEFAULT_GITHUB_API_BASE}/${org}/repos?per_page=200")"; | |
else | |
echo >&2 "Install gh or curl to continue"; | |
exit 1; | |
fi | |
local repo_dir remote default_branch; | |
jq -r '.[] | "\(.ssh_url) \(.default_branch)"' <<< "${repos_json}" | \ | |
while read -rs remote default_branch; | |
do | |
repo_dir="$(basename -s.git "$remote")"; | |
__log_verbose '{ "repo_dir": "'"$repo_dir"'", "remote": "'"$remote"'", "default_branch": "'"$default_branch"'" }'; | |
pushd "$github_base/$org" &>/dev/null; | |
if [ -d "${repo_dir}" ]; | |
then | |
pushd "${repo_dir}" &>/dev/null; | |
if ! __git ls-remote --exit-code --heads origin "$(git symbolic-ref --quiet HEAD)" >/dev/null; | |
then | |
__git switch "$default_branch"; | |
# git switch master || git switch main | |
fi | |
__git fetch --prune-tags; | |
__git pull --all --tags --autostash; | |
popd &>/dev/null; | |
else | |
__git clone "$remote"; | |
fi | |
popd &>/dev/null; | |
done | |
} | |
function main { | |
local -r org="${1:-$DEFAULT_ORG}"; | |
ensure_org_dir "${GITHUB_BASE_DIRECTORY}" "$org"; | |
mirror_org_repos "${GITHUB_BASE_DIRECTORY}" "$org" "${GITHUB_TOKEN:?$GITHUB_TOKEN_ERROR_MESSAGE}"; | |
} | |
main "$@"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment