summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xscripts/gist384
1 files changed, 192 insertions, 192 deletions
diff --git a/scripts/gist b/scripts/gist
index 182425c..892cdac 100755
--- a/scripts/gist
+++ b/scripts/gist
@@ -67,68 +67,68 @@ CONFIG=~/.config/gist.conf; mkdir -p ~/.config
67configuredClient="" 67configuredClient=""
68 68
69_config_cases() { 69_config_cases() {
70 if [[ $1 == 'token' ]]; then 70 if [[ $1 == 'token' ]]; then
71 [[ ${#2} -eq 40 ]] && echo $1=$2 \ 71 [[ ${#2} -eq 40 ]] && echo $1=$2 \
72 || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty 72 || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty
73 elif [[ $1 == 'auto_sync' ]]; then 73 elif [[ $1 == 'auto_sync' ]]; then
74 [[ $2 == 'false' ]] && echo $1=$2 \ 74 [[ $2 == 'false' ]] && echo $1=$2 \
75 || echo $1=true 75 || echo $1=true
76 elif [[ $1 == 'folder' ]]; then 76 elif [[ $1 == 'folder' ]]; then
77 [[ -n "$2" ]] && echo $1=$2 \ 77 [[ -n "$2" ]] && echo $1=$2 \
78 || echo $1=~/gist 78 || echo $1=~/gist
79 elif [[ $1 == 'user' ]]; then 79 elif [[ $1 == 'user' ]]; then
80 echo $1=$2 80 echo $1=$2
81 fi 81 fi
82} 82}
83 83
84_configure() { 84_configure() {
85 [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 85 [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0
86 target=$(_config_cases "$@") 86 target=$(_config_cases "$@")
87 87
88 umask 0077 && touch $CONFIG 88 umask 0077 && touch $CONFIG
89 [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $CONFIG && echo $target >> $CONFIG 89 [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $CONFIG && echo $target >> $CONFIG
90 cat $CONFIG 90 cat $CONFIG
91} 91}
92 92
93_ask_username() { 93_ask_username() {
94 while [[ ! $user =~ ^[[:alnum:]]+$ ]]; do 94 while [[ ! $user =~ ^[[:alnum:]]+$ ]]; do
95 [[ -n $user ]] && echo "Not a valid username" 95 [[ -n $user ]] && echo "Not a valid username"
96 read -p "Github username: " user < /dev/tty 96 read -p "Github username: " user < /dev/tty
97 done 97 done
98 _configure user $user 98 _configure user $user
99} 99}
100 100
101_ask_token() { 101_ask_token() {
102 echo -n "Create a new token from web browser? [Y/n] " 102 echo -n "Create a new token from web browser? [Y/n] "
103 read answer < /dev/tty 103 read answer < /dev/tty
104 if [[ ! $answer =~ ^(N|n|No|NO|no)$ ]]; then 104 if [[ ! $answer =~ ^(N|n|No|NO|no)$ ]]; then
105 python -mwebbrowser https://github.com/settings/tokens/new\?scopes\=gist; 105 python -mwebbrowser https://github.com/settings/tokens/new\?scopes\=gist;
106 fi 106 fi
107 107
108 while [[ ! $token =~ ^[[:alnum:]]{40}$ ]]; do 108 while [[ ! $token =~ ^[[:alnum:]]{40}$ ]]; do
109 [[ -n $token ]] && echo "Not a valid token" 109 [[ -n $token ]] && echo "Not a valid token"
110 trap 'echo; return 1' INT 110 trap 'echo; return 1' INT
111 read -p "Paste your token here (Ctrl-C to skip): " token < /dev/tty 111 read -p "Paste your token here (Ctrl-C to skip): " token < /dev/tty
112 done 112 done
113 _configure token $token 113 _configure token $token
114} 114}
115 115
116_apply_config() { 116_apply_config() {
117 source $CONFIG 2> /dev/null || true 117 source $CONFIG 2> /dev/null || true
118 if [[ ! -e $CONFIG ]] || [[ -z $user ]]; then 118 if [[ ! -e $CONFIG ]] || [[ -z $user ]]; then
119 echo 'Hi fellow! To access your gists, I need your Github username' 119 echo 'Hi fellow! To access your gists, I need your Github username'
120 echo "Also a personal token with scope which allows "gist"!'" 120 echo "Also a personal token with scope which allows "gist"!'"
121 echo 121 echo
122 _ask_username 122 _ask_username
123 _ask_token 123 _ask_token
124 elif [[ -z $token ]] && [[ $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then 124 elif [[ -z $token ]] && [[ $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then
125 if ! (_ask_token); then 125 if ! (_ask_token); then
126 echo 'To create/edit/delete a gist, a token is needed' 126 echo 'To create/edit/delete a gist, a token is needed'
127 return 1 127 return 1
128 fi
129 fi 128 fi
129 fi
130 130
131 source $CONFIG 131 source $CONFIG
132} 132}
133 133
134_apply_config "$@" || exit 1 134_apply_config "$@" || exit 1
@@ -172,25 +172,25 @@ httpGet()
172# TODO a way to show files 172# TODO a way to show files
173# TODO show git status outdated 173# TODO show git status outdated
174_show_list() { 174_show_list() {
175 if [[ ! -e "$1" ]]; then 175 if [[ ! -e "$1" ]]; then
176 echo 'No local file found for last update, please run command:' 176 echo 'No local file found for last update, please run command:'
177 echo " gist update $([[ $1 == $STARRED ]] && echo 'star')" 177 echo " gist update $([[ $1 == $STARRED ]] && echo 'star')"
178 return 0 178 return 0
179 fi 179 fi
180 cat $1 \ 180 cat $1 \
181 | while read index link blob_code file_num extra description; do 181 | while read index link blob_code file_num extra description; do
182 local repo=$folder/$(echo $link | sed 's#.*/##') 182 local repo=$folder/$(echo $link | sed 's#.*/##')
183 local occupy=0 183 local occupy=0
184 184
185 # if repo is not yet cloned, show green message "Not cloned yet" 185 # if repo is not yet cloned, show green message "Not cloned yet"
186 [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16 186 [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16
187 # if there are some changes in git index or working directory, show blue message "working" 187 # if there are some changes in git index or working directory, show blue message "working"
188 [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9 188 [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9
189 # if there is a commit not yet push, show red message "ahead" 189 # if there is a commit not yet push, show red message "ahead"
190 [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 190 [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7
191 191
192 echo -e $index $link $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) 192 echo -e $index $link $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) )
193 done 193 done
194} 194}
195 195
196# parse JSON from STDIN with string of commands 196# parse JSON from STDIN with string of commands
@@ -215,106 +215,105 @@ for gist in raw:
215 215
216# TODO check if a user create a very first gist 216# TODO check if a user create a very first gist
217_parse_response() { 217_parse_response() {
218 AccessJsonElement "$(_handle_gists)" \ 218 AccessJsonElement "$(_handle_gists)" \
219 | tac | sed 's/, /,/g' | nl -s' ' \ 219 | tac | sed 's/, /,/g' | nl -s' ' \
220 | while read index link file_url_array public file_num comment_num description; do 220 | while read index link file_url_array public file_num comment_num description; do
221 local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-') 221 local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-')
222 [[ $public == 'False' ]] && mark=p 222 [[ $public == 'False' ]] && mark=p
223 [[ -n $1 ]] && index=$1 223 [[ -n $1 ]] && index=$1
224 echo $mark$index $link $blob_code $file_num $comment_num $description | tr -d '"' 224 echo $mark$index $link $blob_code $file_num $comment_num $description | tr -d '"'
225 done 225 done
226} 226}
227 227
228# get the list of gists 228# get the list of gists
229_update() { 229_update() {
230 echo "fetching $user's gists from $GITHUB_API..." 230 echo "fetching $user's gists from $GITHUB_API..."
231 echo 231 echo
232 local list_file=$INDEX 232 local list_file=$INDEX
233 local route="users/$user/gists" 233 local route="users/$user/gists"
234 local mark="" 234 local mark=""
235 [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" && mark="s" 235 [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" && mark="s"
236 236
237 curl -H "$auth_header" $GITHUB_API/$route \ 237 curl -H "$auth_header" $GITHUB_API/$route \
238 | _parse_response | sed -E "s/^ */$mark/" > $list_file \ 238 | _parse_response | sed -E "s/^ */$mark/" > $list_file \
239 && _show_list $list_file \ 239 && _show_list $list_file \
240 || echo Fail to update gists 240 || echo Fail to update gists
241 241
242 if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi 242 if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi
243} 243}
244 244
245_sync_repos() { 245_sync_repos() {
246 local list_file=$INDEX 246 local list_file=$INDEX
247 [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" 247 [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred"
248 248
249 # clone repos which are not in the local 249 # clone repos which are not in the local
250 comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ 250 comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \
251 <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \ 251 <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \
252 | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{} 252 | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{}
253 253
254 # pull if remote repo has different blob objects 254 # pull if remote repo has different blob objects
255 cat $INDEX | cut -d' ' -f2,3 \ 255 cat $INDEX | cut -d' ' -f2,3 \
256 | while read url blob_code_remote; do 256 | while read url blob_code_remote; do
257 local repo=$folder/$(echo $url | sed 's#.*/##') 257 local repo=$folder/$(echo $url | sed 's#.*/##')
258 local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-') 258 local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-')
259 cd $repo \ 259 cd $repo \
260 && [[ $blob_code_local != $blob_code_remote ]] \ 260 && [[ $blob_code_local != $blob_code_remote ]] \
261 && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \ 261 && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \
262 && git pull 262 && git pull
263 done 263 done
264 echo Everything is fine! 264 echo Everything is fine!
265} 265}
266 266
267# get gist id from index files 267# get gist id from index files
268_gist_id() { 268_gist_id() {
269 GIST_ID=$( (grep -hs '' $INDEX $STARRED || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##') 269 GIST_ID=$( (grep -hs '' $INDEX $STARRED || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##')
270 if [[ -z "$GIST_ID" ]]; then 270 if [[ -z "$GIST_ID" ]]; then
271 echo -e "Not a valid index: \e[31m$1\e[0m" 271 echo -e "Not a valid index: \e[31m$1\e[0m"
272 echo Use the index in the first column instead: 272 echo Use the index in the first column instead:
273 echo 273 echo
274 _show_list "$INDEX" 274 _show_list "$INDEX"
275 return 1 275 return 1
276 fi 276 fi
277} 277}
278 278
279# TODO a better way without source 279# TODO a better way without source
280# FIXME source cause eixt
280_goto_gist() { 281_goto_gist() {
281 _gist_id $1 282 _gist_id $1
282 283
283 if [[ ! -d $folder/$GIST_ID ]]; then 284 if [[ ! -d $folder/$GIST_ID ]]; then
284 echo 'Cloning gist as repo...' 285 echo 'Cloning gist as repo...'
285 git clone git@github.com:$GIST_ID.git $folder/$GIST_ID 286 git clone git@github.com:$GIST_ID.git $folder/$GIST_ID
286 if [[ "$?" -ne 0 ]]; then 287 if [[ "$?" -ne 0 ]]; then
287 echo 'Repo is cloned' 288 echo 'Repo is cloned'
288 return 0 289 else
289 else 290 echo 'Failed to clone the gist'
290 echo 'Failed to clone the gist'
291 return 1
292 fi
293 fi 291 fi
292 fi
294 293
295 echo This gist is at $folder/$GIST_ID 294 echo This gist is at $folder/$GIST_ID
296 echo -e "You can run the following command to jump to this directory: \n" 295 echo -e "You can run the following command to jump to this directory: \n"
297 echo -e " \e[32m. gist $1\e[0m\n" 296 echo -e " \e[32m. gist $1\e[0m\n"
298 echo -n 'files: ' && cd $folder/$GIST_ID && ls 297 echo -n 'files: ' && cd $folder/$GIST_ID && ls
299 tig --all 2> /dev/null || true 298 tig --all 2> /dev/null || true
300} 299}
301 300
302_delete_gist() { 301_delete_gist() {
303 for i in "$@"; do 302 for i in "$@"; do
304 _gist_id "$i" 303 _gist_id "$i"
305 curl -X DELETE -s -H "$auth_header" $GITHUB_API/gists/$GIST_ID \ 304 curl -X DELETE -s -H "$auth_header" $GITHUB_API/gists/$GIST_ID \
306 && echo "$i" deleted \ 305 && echo "$i" deleted \
307 && sed -i -E "/^$i / d" $INDEX 306 && sed -i -E "/^$i / d" $INDEX
308 done 307 done
309} 308}
310 309
311# remove repos which are not in user gists anymore 310# remove repos which are not in user gists anymore
312_clean_repos() { 311_clean_repos() {
313 comm -23 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ 312 comm -23 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \
314 <(cat $INDEX $STARRED 2> /dev/null | cut -d' ' -f2 | sed 's#.*/##' | sort) \ 313 <(cat $INDEX $STARRED 2> /dev/null | cut -d' ' -f2 | sed 's#.*/##' | sort) \
315 | while read dir; do 314 | while read dir; do
316 mv $folder/$dir /tmp && echo move $folder/$dir to /tmp 315 mv $folder/$dir /tmp && echo move $folder/$dir to /tmp
317 done 316 done
318} 317}
319 318
320_handle_gist() { 319_handle_gist() {
@@ -345,77 +344,78 @@ for comment in raw:
345 344
346# TODO format with simple text 345# TODO format with simple text
347_show_detail() { 346_show_detail() {
348 _gist_id $1 347 _gist_id $1
349 httpGet $GITHUB_API/gists/$GIST_ID \ 348 httpGet $GITHUB_API/gists/$GIST_ID \
350 | AccessJsonElement "$(_handle_gist)" 349 | AccessJsonElement "$(_handle_gist)"
351 350
352 httpGet $GITHUB_API/gists/$GIST_ID/comments \ 351 httpGet $GITHUB_API/gists/$GIST_ID/comments \
353 | AccessJsonElement "$(_handle_comment)" 352 | AccessJsonElement "$(_handle_comment)"
354} 353}
355 354
356_set_gist() { 355_set_gist() {
357 public=true 356 public=true
358 while [[ -n "$@" ]]; do case $1 in 357 while [[ -n "$@" ]]; do case $1 in
359 -d | --desc) 358 -d | --desc)
360 description="$2" 359 description="$2"
361 shift; shift;; 360 shift; shift;;
362 -f | --file) 361 -f | --file)
363 filename="$2" 362 filename="$2"
364 shift; shift;; 363 shift; shift;;
365 -p) 364 -p)
366 public=false 365 public=false
367 shift;; 366 shift;;
368 *) 367 *)
369 files="$1 $files" 368 files="$1 $files"
370 shift;; 369 shift;;
371 esac 370 esac
372 done 371 done
373 ls $files > /dev/null || return 1 372 ls $files > /dev/null || return 1
374} 373}
375 374
376_new_file() { 375_new_file() {
377 [[ -t 0 ]] && echo "Type a gist. <Ctrl-C> to cancel, <Ctrl-D> when done" > /dev/tty 376 [[ -t 0 ]] && echo "Type a gist. <Ctrl-C> to cancel, <Ctrl-D> when done" > /dev/tty
378 tmp_file=$(mktemp) 377 tmp_file=$(mktemp)
379 cat > $tmp_file 378 cat > $tmp_file
380 echo -e '\n' > /dev/tty 379 echo -e '\n' > /dev/tty
381 [[ -z "$1" ]] && read -p 'Type file name: ' filename < /dev/tty 380 [[ -z "$1" ]] && read -p 'Type file name: ' filename < /dev/tty
382 mv $tmp_file /tmp/$filename 381 mv $tmp_file /tmp/$filename
383 echo /tmp/$filename 382 echo /tmp/$filename
384} 383}
385 384
386# create a new gist with files 385# create a new gist with files
387# FIXME catch status code from curl if it fails 386# FIXME catch status code from curl if it fails
388_create_gist() { 387_create_gist() {
389 _set_gist "$@" || return 1 388 _set_gist "$@" || return 1
390 [[ -z "$files" ]] && files=$(_new_file $filename) 389 [[ -z "$files" ]] && files=$(_new_file $filename)
391 [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty 390 [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty
392 391
393 for file in $files; do 392 echo 'Creating a new gist'
394 echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"}," 393 for file in $files; do
395 done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \ 394 echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"},"
396 | echo "{ \"public\": $public, \"files\": $(cat -), \"description\": \"$description\"}" \ 395 done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \
397 | curl -s -H "$auth_header" --data @- $GITHUB_API/gists \ 396 | echo "{ \"public\": $public, \"files\": $(cat -), \"description\": \"$description\"}" \
398 | sed '1 s/^/[/; $ s/$/]/' \ 397 | curl -s -H "$auth_header" --data @- $GITHUB_API/gists \
399 | _parse_response $(( $(sed '/^s/ d' $INDEX | wc -l) +1 )) >> $INDEX \ 398 | sed '1 s/^/[/; $ s/$/]/' \
400 && echo -e '\nGist created' \ 399 | _parse_response $(( $(sed '/^s/ d' $INDEX | wc -l) +1 )) >> $INDEX \
401 || echo 'Fail to create gist' 400 && echo -e '\nGist created' \
402 401 || echo 'Fail to create gist'
403 _show_list $INDEX | tail -1 402
403 _show_list $INDEX | tail -1
404} 404}
405 405
406# update description of a gist 406# update description of a gist
407_edit_gist() { 407_edit_gist() {
408 _gist_id $1 408 _gist_id $1
409 409
410 echo -n 'Type new description: ' 410 echo -n 'Type new description: '
411 read DESC < /dev/tty 411 read DESC < /dev/tty
412 echo "{ \"description\": \"$DESC\" }" \ 412 echo "{ \"description\": \"$DESC\" }" \
413 | curl -X PATCH -H "$auth_header" --data @- $GITHUB_API/gists/$GIST_ID > /dev/null \ 413 | curl -X PATCH -H "$auth_header" --data @- $GITHUB_API/gists/$GIST_ID > /dev/null \
414 && _update 414 && _update
415} 415}
416 416
417usage() { 417usage() {
418 sed -E -n ' /^$/ q; 8,$ s/^#//p' $0 418 sed -E -n ' /^$/ q; 8,$ s/^#//p' $0
419} 419}
420 420
421getConfiguredClient 421getConfiguredClient