Last active
May 14, 2017 11:57
-
-
Save xenithorb/bd0be10e105ef160826e1c0902bae3f1 to your computer and use it in GitHub Desktop.
A helper script for python-github-backup that also handles backing up github gists
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 | |
# | |
# github-backup.sh: A helper script for python-github-backup that also | |
# handles backing up github gists | |
# | |
# Author: Mike Goodwin | |
# Date: 20170429 | |
# | |
# Usage Example: | |
# | |
# This would download all repos and gists and install a virtual | |
# env for python-github-backup | |
# | |
# ./github-backup.sh -o <outdir> -t <token> -rgis | |
# | |
# | |
# For a new token, see: https://github.com/settings/tokens/new | |
GH_TOKEN="${GH_TOKEN}" # Set token here or export GH_TOKEN or -t <token> | |
API="https://api.github.com" | |
VENV_DIR="${HOME}/virtualenvs/github-backup" | |
DEPS=( | |
"github-backup" | |
"python" | |
"virtualenv" | |
"pyvenv" | |
"curl" | |
) | |
json_parse() { | |
env python <( | |
cat <<-EOF | |
import json | |
import sys | |
a = json.loads(sys.stdin.read()) | |
if type(a) is not list: | |
a = [a] | |
print('%s' % '\n'.join([s['${1}'] for s in a])) | |
EOF | |
) | |
} | |
curl_gh_api() { | |
curl -sH "Authorization: token ${GH_TOKEN}" "${API}/${1}" | |
} | |
github_back() { | |
[[ "${1}" == "org" ]] && | |
local o="-O --repositories" d="$2" u="$3" | |
[[ "${1}" == "user" ]] && | |
local o='--all' d="$2" u="$3" | |
(( PREFER_SSH )) && local PREFER_SSH='--prefer-ssh' | |
github-backup -iFP ${o} ${PREFER_SSH} -t "${GH_TOKEN}" -o "${d}" "${u}" | |
} | |
while getopts ":sirt:go:" opt; do | |
found_opts=1 | |
case "${opt}" in | |
o) OUTDIR="${OPTARG%/}" ;; | |
s) PREFER_SSH=1 ;; | |
t) GH_TOKEN="${OPTARG}" ;; | |
g) DO_GISTS=1 ;; | |
i) DO_VENVINSTALL=1 ;; | |
r) DO_REPOS=1 ;; | |
\?) echo "Invalid option: -${OPTARG}" >&2; exit 1 ;; | |
:) echo "Error, argument required: -${OPTARG}" >&2; exit 1 ;; | |
esac | |
done | |
if [[ ! "$OUTDIR" ]] && ((found_opts)); then | |
echo "Error: -o <outdir> is REQUIRED"; exit 1 | |
fi | |
if [[ ! "$GH_TOKEN" ]] && ((found_opts)); then | |
echo "Error: -t <token> is missing" | |
fi | |
((!found_opts)) && { echo "Missing some options"; exit 1; } | |
PY_VER=$( env python --version 2>&1 | awk 'BEGIN{FS="[ .]"} {print $2}' ) | |
[[ "$PY_VER" == "2" ]] && DEPS=( "${DEPS[@]/pyvenv}" ); VENV_CMD=virtualenv | |
[[ "$PY_VER" == "3" ]] && DEPS=( "${DEPS[@]/virtualenv}" ); VENV_CMD=pyvenv | |
if ! command -v github-backup &>/dev/null; then | |
if ((DO_VENVINSTALL)); then | |
VENV_ACTIVATE="${VENV_DIR}/bin/activate" | |
[[ ! -d "${VENV_DIR%/*}" ]] && mkdir -p "${VENV_DIR%/*}" | |
if [[ ! -f "${VENV_ACTIVATE}" ]]; then | |
$VENV_CMD "$VENV_DIR" | |
fi | |
if [[ ! -x "${VENV_DIR}/bin/github-backup" ]]; then | |
# shellcheck source=/dev/null | |
source "${VENV_ACTIVATE}" | |
pip install --upgrade github-backup | |
fi | |
fi | |
if [[ -x "${VENV_DIR}/bin/github-backup" ]]; then | |
# shellcheck source=/dev/null | |
source "${VENV_ACTIVATE}" | |
fi | |
fi | |
# Find deps | |
for cmd in "${DEPS[@]}"; do | |
if [[ "$cmd" ]]; then | |
if ! command -v "${cmd}" >/dev/null 2>&1; then | |
if [[ "$cmd" == "github-backup" ]]; then | |
echo "Missing: $cmd, perhaps try -i ?" | |
else | |
echo "Missing: $cmd, please install to continue." | |
fi | |
exit 1 | |
fi | |
fi | |
done | |
GH_USER_JSON=$( curl_gh_api user ) | |
GH_MSG_TEST=$( json_parse message <<< "$GH_USER_JSON" 2>/dev/null ) | |
[[ "${GH_MSG_TEST}" ]] && { echo "${GH_MSG_TEST}"; exit 1; } | |
GH_USER=$( json_parse login <<< "$GH_USER_JSON" ) | |
if ((DO_REPOS)); then | |
readarray -t ORGS < <( curl_gh_api user/orgs | json_parse login ) | |
USER_DIR="${OUTDIR}/users/${GH_USER}" | |
ORGS_DIR="${OUTDIR}/orgs" | |
[[ ! -d "${USER_DIR}" ]] && mkdir -p "${USER_DIR}" #./users/xenith | |
github_back user "${USER_DIR}" "${GH_USER}" | |
for org in "${ORGS[@]}"; do | |
[[ ! -d "${org}" ]] && mkdir -p "${ORGS_DIR}/${org}" | |
github_back org "${ORGS_DIR}/${org}" "${org}" | |
done | |
fi | |
if ((DO_GISTS)); then | |
GISTS_JSON=$( curl_gh_api gists ) | |
readarray -t GISTS_REPO_URL < <( json_parse git_pull_url <<< "${GISTS_JSON}" ) | |
readarray -t GISTS_DESC < <( json_parse description <<< "${GISTS_JSON}" ) | |
readarray -t GISTS_ID < <( json_parse id <<< "${GISTS_JSON}" ) | |
GIST_DIR="${OUTDIR}/users/${GH_USER}/gists" | |
[[ ! -d "${GIST_DIR}" ]] && mkdir -p "$GIST_DIR" | |
pushd "$GIST_DIR" &>/dev/null | |
for i in "${!GISTS_REPO_URL[@]}"; do | |
if [[ ! -d "${GISTS_ID[i]}" ]]; then | |
((PREFER_SSH)) && GISTS_REPO_URL[$i]=$( sed -r 's|^https://|git@|; s|/(.*)|:\1|' <<< "${GISTS_REPO_URL[i]}" ) | |
mkdir "${GISTS_ID[i]}" | |
git clone "${GISTS_REPO_URL[i]}" "${GISTS_ID[i]}/repo" | |
else | |
pushd "${GISTS_ID[i]}/repo" &>/dev/null | |
echo -n "$PWD: " | |
git pull --rebase --autostash | |
popd &>/dev/null | |
fi | |
echo "${GISTS_ID[i]}: ${GISTS_DESC[i]}" > "${GISTS_ID[i]}/description" | |
done | |
popd &>/dev/null | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage Example:
Yields the following file structure: