/
github_fetchfile
executable file
·101 lines (86 loc) · 3.14 KB
/
github_fetchfile
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
#!/usr/bin/env bash
###############################################################################
## File: github_fetchfile
## Purpose: Shell Script to curl-download large files from github
## Notes:
## - Will use your Github CLI Token from the macOS Keychain
## - Has to hit the repo twice, once to get the SHA needed, and once to
## actually download your file. See instead github_fetchfile_small if < 1MB
## - Depends on node for JSON parsing.
###############################################################################
set -e
while getopts ":t:o:r:b:p:O:s:" opt; do
case $opt in
t) TOKEN="$OPTARG"
;;
s) SCRIPT_NAME="$OPTARG"
;;
o) REPO_OWNER="$OPTARG"
;;
r) REPO="$OPTARG"
;;
b) BRANCH="$OPTARG"
;;
p) ASSET_PATH="$OPTARG"
;;
O) OUTPUT_PATH="$OPTARG"
;;
\?) INVALID=1; echo "Invalid Option: -$OPTARG" >&2
;;
esac
done
INVALID=${INVALID:-0}
# Set Defaults
REPO_OWNER=${REPO_OWNER:-"$GITHUB_USER"}
BRANCH=${BRANCH:-"main"}
# Used to get a unique access code for this script
SCRIPT_NAME=${SCRIPT_NAME:-"$(basename "$0")"}
# Test required params
if [[ INVALID -eq 0 ]] && [[ "$REPO_OWNER" == "" ]]; then
echo "Repository owner must be passed in, or ENV[\$GITHUB_USER] must be set!" >&2
INVALID=1
fi
TOKEN=$("$(dirname "${BASH_SOURCE[0]}" )/github_token" -r -s "$SCRIPT_NAME")
if [[ INVALID -eq 0 ]] && [[ "$TOKEN" == "" ]]; then
echo "Couldn't load Github Personal Access Token, aborting… " >&2
exit 1
fi
if [[ INVALID -eq 0 ]] && [[ "$ASSET_PATH" == "" ]]; then
echo "-p ASSET_PATH missing." >&2
INVALID=1
fi
if [[ INVALID -eq 0 ]] && [[ "$OUTPUT_PATH" == "" ]]; then
echo "-O OUTPUT_PATH missing." >&2
INVALID=1
fi
if [ $INVALID -eq 1 ]; then
echo "Usage: $0 [-t TOKEN] [-s SCRIPT_NAME] [-o REPO_OWNER] -r REPO [-b BRANCH] -p ASSET_PATH -O OUTPUT_PATH" >&2
echo " -t Github Personal Access Token with sufficient permissions. Will look at keychain if omitted." >&2
echo " -s Identifier for the Keychain item used to lookup a token for this script." >&2
echo " -b Choose what branch to fetch from. If omitted, the default branch name is 'main'." >&2
exit 1
fi
type node >/dev/null 2>&1 || { echo >&2 "This tool requires node for JSON parsing/inspection. Aborting."; exit 1; }
# Technique from: https://medium.com/@caludio/how-to-download-large-files-from-github-4863a2dbba3b
# 1. Fetch the dir of the target
echo "https://api.github.com/repos/$REPO_OWNER/$REPO/contents/$(basename "$ASSET_PATH")?ref=$BRANCH"
JSON_RESPONSE=$(curl -H "Authorization: token $TOKEN" -L "https://api.github.com/repos/$REPO_OWNER/$REPO/contents/$(dirname "$ASSET_PATH")?ref=$BRANCH")
# echo "$JSON_RESPONSE"
# 2. Parse the JSON of the dir and find the file we were looking for
BASE=$(basename "$ASSET_PATH")
# echo "Base $BASE"
SCRIPT=$(cat <<- HEREDOC
var r=JSON.parse('${JSON_RESPONSE}');
r.forEach(function(v) {
if(v.name=='${BASE}'){
console.log(v.sha);
}
});
HEREDOC
)
THE_SHA=$(echo "$SCRIPT" | tr -d '\n' | tr -d '\t' | node)
# echo "$SHA"
# 3. Fetch the large file
curl -s -H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3.raw+json" \
-o "$OUTPUT_PATH" -L "https://api.github.com/repos/$REPO_OWNER/$REPO/git/blobs/$THE_SHA"