-
Notifications
You must be signed in to change notification settings - Fork 3
/
gist.sh
executable file
·263 lines (208 loc) · 4.91 KB
/
gist.sh
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#!/bin/sh
# gmarik & rocketraman
log ()
{
echo -e "$@" >&2
}
err_exit ()
{
log "Error: $1"
exit 1
}
require ()
{
which $1 > /dev/null || err_exit "$0 requires '$1'"
}
help ()
{
log 'Usage:
SYNOPSIS
Post gist:
gist.sh [-e <extension>] [-p] [-c] [-a] [-d]
gist.sh [-p] [-d] [-a] -f file
Retrieve gist:
gist.sh [-f <file> | -c] [-d] <gist-id>
Clone gist:
gist.sh [-l] [-p] [-d] <gist-id>
DESCRIPTION
With -f, gist.sh reads/writes files.
With -c, gist.sh reads/writes to the clipboard (xclip is required).
With -l, gist.sh clones the gist to a local git repository.
Otherwise, gist.sh reads/writes standard input/output.
If your git config contains github.user and github.token (see
https://github.com/account), they will be used to assign yourself as owner
of posted gists. Use the -a or --anon parameter to post anonymously.
OPTIONS
-f, --file
Read/write a gist from/to the specified file. Github guesses the gist
language from the filename, therefore -e is ignored.
-c, --clip
Read/write a gist from/to the clipboard.
-l, --clone
Clone a gist.
-e, --ext
When reading standard input or clipboard, specify an extension. Github
sets the gist language based on the extension e.g. "java", "rb", "py".
Ignored if -f is specified.
-p, --private
Make a gist private. When cloning, use the private clone URL to clone
the gist. Requires the gist to be non-anonymous.
-a, --anon
Post a gist anonymously, even if Github authentication data is
available in the global git config.
-d, --debug
Debug mode. Nothing is actually read or written to Github.
'
}
gist_get ()
{
URL="https://raw.github.com/gist/$1"
log "* reading Gist from $URL"
CMD="curl -s $URL"
if [ "$_DEBUG" = "1" ]; then
echo $CMD
exit 0
fi
if [ "$_FILENAME" != "" ]; then
if [ -f "$_FILENAME" ]; then
log "* Filename $_FILENAME already exists, aborting."
exit 1
fi
$CMD > $_FILENAME
log "* Gist written to file $_FILENAME"
elif [ "$_CLIP" = "1" ]; then
$CMD | xclip -i -selection clipboard
log "* Gist written to clipboard"
else
log "\n"
echo "$($CMD)"
fi
}
gist_clone ()
{
if [ "$_PRIVATE" = "1" ]; then
URL="git@gist.github.com:$1.git"
else
URL="git://gist.github.com/$1.git"
fi
log "* cloning Gist from $URL"
CMD="git clone $URL gist-$1"
if [ "$_DEBUG" = "1" ]; then
echo $CMD
exit 0
fi
$CMD
}
gist_post ()
{
if [ "$_FILENAME" != "" ]; then
log "* reading Gist from $_FILENAME"
REQUEST_FILE="$_FILENAME"
FILENAME=$(basename "$_FILENAME")
if [ "$_FILEEXT" != "" ]; then
log "* warning: -e specified with -f, ignoring -e"
fi
FILEEXT=""
elif [ "$_CLIP" = "1" ]; then
log "* reading Gist from clipboard"
REQUEST_FILE=/tmp/gist.sh.req
xclip -o -selection clipboard > $REQUEST_FILE
FILENAME=""
FILEEXT=".$_FILEEXT"
else
log "* reading Gist from stdin"
REQUEST_FILE=/tmp/gist.sh.req
#cleanup
: > $REQUEST_FILE
# read file content
#TODO: improve
OLDIFS="$IFS"
IFS=""
while read line; do
echo "$line" >> $REQUEST_FILE
done
IFS="$OLDIFS"
FILENAME=""
FILEEXT=".$_FILEEXT"
fi
if [ ! -s $REQUEST_FILE ]; then
help && exit 0
fi
RESPONSE_FILE=/tmp/gist.sh.res
#cleanup
: > $RESPONSE_FILE
if [ "$_DEBUG" = "1" ]; then
DEBUG=echo
fi
if [ "$_PRIVATE" = "1" ]; then
PRIVATE="--data-urlencode public=false"
else
PRIVATE="--data-urlencode public=true"
fi
if [ "$_ANON" != "1" ]; then
require git
USER=$(git config --global github.user)
USERAVAIL=$?
TOKEN=$(git config --global github.token)
TOKENAVAIL=$?
if [ $USERAVAIL -eq 0 -a $TOKENAVAIL -eq 0 ]; then
AUTH="--data-urlencode login=$USER --data-urlencode token=$TOKEN"
fi
fi
$DEBUG curl https://gist.github.com/gists \
-i \
--silent \
$PRIVATE \
$AUTH \
--data-urlencode "file_name[gistfile1]=$FILENAME" \
--data-urlencode "file_ext[gistfile1]=$FILEEXT" \
--data-urlencode "file_contents[gistfile1]@$REQUEST_FILE" \
-o $RESPONSE_FILE
LOCATION=$(cat $RESPONSE_FILE|sed -ne '/Location/p'|cut -f2- -d:|tr -d ' ')
log "* Gist location:"
echo "$LOCATION"
}
require curl
while [ $# -gt 0 ]; do
case $1 in
-h|--help)
help
exit 0
;;
-d|--debug)
_DEBUG=1
;;
-e|--ext)
shift
_FILEEXT="$1"
;;
-f|--file)
shift
_FILENAME="$1"
;;
-c|--clip)
require xclip
_CLIP=1
;;
-p|--private)
_PRIVATE=1
;;
-a|--anon)
_ANON=1
;;
-l|--clone)
require git
_CLONE=1
;;
*[a-zA-Z0-9]) # gist ID
if [ "$_CLONE" = "1" ]; then
gist_clone $1
else
gist_get $1
fi
exit 0
;;
esac
shift
done
gist_post