aboutsummaryrefslogtreecommitdiff
path: root/reposync.sh
blob: b938dee3848ec43a57eda94a5be8bd7a28e84e85 (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
#!/bin/bash

# reposync.sh
# Syncs a folder to GitHub

ARGV=($@)
ARGC=${#ARGV[@]}

API_BASE="https://api.github.com"

# ['name']='ssh_url' # name with .git suffix
declare -A GH_REPOS

function curl_wrapper() {
	RAW_CURL=$(curl -s -w "%{http_code}" $@; exit $?)
	RET=$?
	[ $RET -ne 0 ] && >&2 echo curl failed with $RET && exit 1

	HTTP_CODE=$(tail -n 1 <<< "$RAW_CURL")
	[ $HTTP_CODE -ge 300 ] && >&2 echo HTTP error $HTTP_CODE && exit 1

	head -n -1 <<< "$RAW_CURL"
}

# create new repository for $USERNAME
# 1: name
function github_create_repo() {
	[ -z "$TOKEN" ] && >&2 echo TOKEN not set. No write access. && exit 1
	JSON_RETURN=$(curl_wrapper -X POST -H "Content-Type: application/json" -u $USERNAME:$TOKEN \
		-d "{\"name\":\"$1\"}" "$API_BASE/user/repos"; exit $? )
	[ $? -ne 0 ] && exit 1

	GH_REPOS[$1.git]=$(jq -r ".clone_url" <<< $JSON_RETURN | sed -n -e "s/^\(https:\/\/\)\(.*\)$/\1$USERNAME:$TOKEN@\2/p" )
}

function github_update_repo_list() {
	GH_REPOS=()

	local CURL_USER=""
	[ ! -z "$TOKEN" ] && CURL_USER="-u $USERNAME:$TOKEN"

	# replace with /user/repos to also get private
	JSON_REPOS=$(curl_wrapper $CURL_USER "$API_BASE/users/$USERNAME/repos"; exit $?)
	[ $? -ne 0 ] && exit 1

	GH_REPOS_COUNT=$(jq ". | length" <<< "$JSON_REPOS")
	
	for (( i=0; i<$GH_REPOS_COUNT; i++ )); do
		name="$(jq ".[$i].name" <<< "$JSON_REPOS" | tr -d '"' ).git"
		GH_REPOS[$name]=$(jq -r ".[$i].clone_url" <<< "$JSON_REPOS" | sed -n -e "s/^\(https:\/\/\)\(.*\)$/\1$USERNAME:$TOKEN@\2/p" )
	done
}

[ -f "$HOME/settings.sh" ] && source $HOME/settings.sh

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
	##sudo -u git mkdir "$REPO_DIR/$repo"
	sudo -u git 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

	git -C "$REPO_DIR/$repo" push "${GH_REPOS[$repo]}"
done

for repo in "${TO_PUSH[@]}"; do
	git -C "$REPO_DIR/$repo" push "${GH_REPOS[$repo]}"
done

echo
echo Done.