blob: f33374f149c0cc25936f118ab109b6fdf961e053 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#!/bin/bash
# reposync.sh
# Syncs a folder to GitHub
# required setup:
# - different user for script (no specific name needed) and git access (git)
#
# Usage:
# reposync.sh <CONFIG FILE>
#
# Config file:
# Sourcable bash script setting the variables:
# USERNAME GitHub Username
# TOKEN Password or Token
# REPO_DIR Directory on the filesystem
# PRIVATE Treat repositories as private (true/false)
ARGV=($@)
ARGC=${#ARGV[@]}
API_BASE="https://api.github.com"
# ['name']='ssh_url' # name with .git suffix
declare -A GH_REPOS
function url_inject_credentials() {
sed -n -e "s/^\(https:\/\/\)\(.*\)$/\1$USERNAME:$TOKEN@\2/p"
}
function curl_wrapper() {
local CURL_RETURN
CURL_RETURN=$( curl -s -w "%{http_code}" $@ ; exit $? )
local RET=$?
[ $RET -ne 0 ] && >&2 echo cURL code $RET && return 1
head -n -1 <<< "$CURL_RETURN"
local HTTP_CODE=$(tail -n 1 <<< "$CURL_RETURN")
[ $HTTP_CODE -ge 300 ] && >&2 echo HTTP Code $HTTP_CODE && return 1
return 0
}
# create new repository for $USERNAME
# 1: name
function github_create_repo() {
[ -z "$TOKEN" ] && >&2 echo TOKEN not set. No write access. && exit 1
local JSON_RETURN
JSON_RETURN=$(curl_wrapper -X POST -H "Content-Type: application/json" -u $USERNAME:$TOKEN \
-d "{\"name\":\"$1\",\"private\":$PRIVATE}" "$API_BASE/user/repos"; exit $? )
[ $? -ne 0 ] && exit 1
echo "$JSON_RETURN"
GH_REPOS[$1.git]=$(jq -r ".clone_url" <<< "$JSON_RETURN" | url_inject_credentials )
}
function github_update_repo_list() {
GH_REPOS=()
local CURL_USER=""
[ ! -z "$TOKEN" ] && CURL_USER="-u $USERNAME:$TOKEN"
local VISIBILITY=""
[ "$PRIVATE" = "true" ] && VISIBILITY="private" || VISIBILITY="public"
local JSON_REPOS
JSON_REPOS=$(curl_wrapper -u $USERNAME:$TOKEN \
"$API_BASE/user/repos?visibility=$VISIBILITY"; exit $?)
[ $? -ne 0 ] && jq ".message" <<< "$JSON_REPOS" && exit 1
GH_REPOS_COUNT=$(jq ". | length" <<< "$JSON_REPOS")
for (( i=0; i<$GH_REPOS_COUNT; i++ )); do
name="$(jq -r ".[$i].name" <<< "$JSON_REPOS" ).git"
GH_REPOS[$name]=$(jq -r ".[$i].clone_url" <<< "$JSON_REPOS" | url_inject_credentials )
done
}
[ ! -f "$1" ] && echo Config file not found && exit 1
source "$1"
[ -z "$USERNAME" -o -z "$TOKEN" ] && echo GitHub credentials config error. && exit 1
[ ! -d "$REPO_DIR" ] && echo Repo directory does not exist. && exit 1
[ "$PRIVATE" != "true" ] && PRIVATE=false
github_update_repo_list
LOCAL_REPOS=( $(for repo in $(ls -d $REPO_DIR/*.git/ 2> /dev/null); do basename $repo; done ) )
TO_CLONE=( $(comm -23 <(printf "%s\n" "${!GH_REPOS[@]}" | sort) \
<(printf "%s\n" "${LOCAL_REPOS[@]}" | sort) ) )
TO_CREATE=( $(comm -13 <(printf "%s\n" "${!GH_REPOS[@]}" | sort) \
<(printf "%s\n" "${LOCAL_REPOS[@]}" | sort) ) )
TO_PUSH=( $(comm -12 <(printf "%s\n" "${!GH_REPOS[@]}" | sort) \
<(printf "%s\n" "${LOCAL_REPOS[@]}" | sort) ) )
echo TO CLONE
printf "%s\n" "${TO_CLONE[@]}"
echo
echo TO CREATE
printf "%s\n" "${TO_CREATE[@]}"
echo
echo TO PUSH
printf "%s\n" "${TO_PUSH[@]}"
echo
for repo in "${TO_CLONE[@]}"; do
git clone --bare \
"${GH_REPOS[$repo]}" "$REPO_DIR/$repo"
done
for repo in "${TO_CREATE[@]}"; do
github_create_repo ${repo%.git}
[ -z "${GH_REPOS[$repo]}" ] && echo No clone_URL? && continue
TO_PUSH+=($repo)
done
for repo in "${TO_PUSH[@]}"; do
git -C "$REPO_DIR/$repo" push --all "${GH_REPOS[$repo]}"
git -C "$REPO_DIR/$repo" push --tags "${GH_REPOS[$repo]}"
done
echo
echo Done.
|