Skip to content

Instantly share code, notes, and snippets.

@arledesma
Last active February 9, 2022 21:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arledesma/7e28e2ffee380fa329f3ab13ee8e9ccf to your computer and use it in GitHub Desktop.
Save arledesma/7e28e2ffee380fa329f3ab13ee8e9ccf to your computer and use it in GitHub Desktop.
Clone all repositories from an organization.
#!/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