aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xgist511
1 files changed, 293 insertions, 218 deletions
diff --git a/gist b/gist
index 40d723a..ee400fb 100755
--- a/gist
+++ b/gist
@@ -15,13 +15,9 @@
15# 15#
16# * list your gists with format: [number] [url] [file_num] [comment_num] [short description] 16# * list your gists with format: [number] [url] [file_num] [comment_num] [short description]
17# gist [star | s] 17# gist [star | s]
18#
19# * clone gist repos which are not in local
20# * pull master branch if a local repo is behind its remote
21# gist (sync | S)
22# 18#
23# * Go to local gist repo 19# * show the path of local gist repo and files
24# . gist <number_of_gist_in_list> 20# gist <index_of_gist>
25# 21#
26# * create a new gist with files 22# * create a new gist with files
27# gist (new | n) [-d | --desc "<gist-description>"] <files>... 23# gist (new | n) [-d | --desc "<gist-description>"] <files>...
@@ -30,13 +26,13 @@
30# gist (new | n) [-d | --desc "<gist-description>"] [-f | --file <file>] < <file-with-content> 26# gist (new | n) [-d | --desc "<gist-description>"] [-f | --file <file>] < <file-with-content>
31# 27#
32# * show the detail of a gist 28# * show the detail of a gist
33# gist (detail | d) <gist_index> 29# gist (detail | d) <index_of_gist>
34# 30#
35# * edit a gist description 31# * edit a gist description
36# gist (edit | e) <gist_index> 32# gist (edit | e) <index_of_gist>
37# 33#
38# * delete a gist 34# * delete a gist
39# gist (delete | D) <gist_index>... 35# gist (delete | D) <index_of_gist>...
40# 36#
41# * clean removed gists in local 37# * clean removed gists in local
42# gist (clean | C) 38# gist (clean | C)
@@ -46,109 +42,172 @@
46# It is your business to do git commit and git push 42# It is your business to do git commit and git push
47# 43#
48# * configuration 44# * configuration
49# gist (config | c) [token <value>] [user <value>] [folder <value>] [auto-sync false] 45# gist (config | c) [token|user|folder|auto-sync|EDITOR|action [value]]
50# 46#
51# * show this help message 47# * show this help message
52# gist (help | h) 48# gist (help | h)
53 49
54# TODO error handling, unit test
55# TODO parallel branch works with wget and other stuff 50# TODO parallel branch works with wget and other stuff
56# TODO completion 51# TODO new command "user" to fetch other user's gists
57# TODO grep mode for description, file content 52# TODO grep mode for description, file content
53# TODO push github.com (may need new token)
54# TODO description for current directory
55# TODO error handling, unit test
56# TODO test on mac and remote machine
57# TODO completion
58 58
59# Validate settings. 59# Shell configuration
60config=~/.config/gistrc
61set -eo pipefail
62[ "$TRACE" ] && set -x 60[ "$TRACE" ] && set -x
63 61
64## parse JSON from STDIN with string of commands 62GITHUB_API=https://api.github.com
65AccessJsonElement() { 63CONFIG=~/.config/gist.conf; mkdir -p ~/.config
66 PYTHONIOENCODING=utf-8 python -c "from __future__ import print_function; import sys, json; raw = json.load(sys.stdin); $1" 64configuredClient=""
67 return "$?" 65
66# handle configuration cases
67_configure() {
68 local target=""
69 [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0
70 if [[ $1 == 'token' ]]; then
71 [[ ${#2} -eq 40 ]] && target=$1=$2 \
72 || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty
73 elif [[ $1 == 'auto_sync' ]]; then
74 [[ $2 == 'false' ]] && target=$1=$2 \
75 || target=$1=true
76 elif [[ $1 == 'folder' ]]; then
77 [[ -n "$2" ]] && target=$1=$2 \
78 || target=$1=~/gist
79 elif [[ $1 == 'user' ]]; then
80 target=$1=$2
81 fi
82
83 umask 0077 && touch $CONFIG
84 [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $CONFIG && echo $target >> $CONFIG
85 cat $CONFIG
68} 86}
69 87
70_auth() { 88# prompt for username
71 echo 'Hi fellow! To access your gists, I need your Github username and a personal token with scope which allows "gist"!' 89_ask_username() {
90 while [[ ! $user =~ ^[[:alnum:]]+$ ]]; do
91 [[ -n $user ]] && echo "Not a valid username"
72 read -p "Github username: " user < /dev/tty 92 read -p "Github username: " user < /dev/tty
73 if [[ $user =~ ^[[:alnum:]]+$ ]]; then 93 done
74 mkdir -p ~/.config 94 _configure user $user
75 umask 0077 95}
76 echo user=$user > $config
77 else
78 echo "Not a valid username"
79 return 0
80 fi
81
82 echo -n "Create a new token from web browser? [Y/n] "
83 read answer < /dev/tty
84 if [[ ! $answer =~ ^(N|n|No|NO|no)$ ]]; then
85 python -mwebbrowser https://github.com/settings/tokens/new\?scopes\=gist;
86 fi
87 96
88 read -p "Paste your token here: " new_token < /dev/tty 97# prompt for toekn
89 [[ $new_token =~ ^[[:alnum:]]{40}$ ]] \ 98# TODO token check, ref: https://developer.github.com/v3/apps/oauth_applications/#check-a-token
90 && echo token=$new_token >> $config \ 99_ask_token() {
91 || echo "Not a valid token" 100 echo -n "Create a new token from web browser? [Y/n] "
101 read answer < /dev/tty
102 if [[ ! $answer =~ ^(N|n|No|NO|no)$ ]]; then
103 python -mwebbrowser https://github.com/settings/tokens/new\?scopes\=gist
104 fi
105
106 while [[ ! $token =~ ^[[:alnum:]]{40}$ ]]; do
107 [[ -n $token ]] && echo "Not a valid token"
108 trap 'echo; return 1' INT
109 read -p "Paste your token here (Ctrl-C to skip): " token < /dev/tty
110 done
111 _configure token $token
92} 112}
93 113
94case "$1" in 114_validate_config(){
95 config | c) ;; 115 source $CONFIG 2> /dev/null || true
96 *) 116 if [[ ! -e $CONFIG || -z $user ]]; then
97 while ! source $config 2> /dev/null || [[ -z "$token" ]] || [[ -z "$user" ]]; do 117 echo 'Hi fellow! To access your gists, I need your Github username'
98 _auth 118 echo "Also a personal token with scope which allows "gist"!'"
99 done;; 119 echo
100esac 120 _ask_username
121 _ask_token
122 elif [[ -z $token && $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then
123 if ! (_ask_token); then
124 echo 'To create/edit/delete a gist, a token is needed'
125 return 1
126 fi
127 elif [[ -z $token && $1 =~ ^(u|update)$ && $2 =~ ^(s|star) ]]; then
128 if ! (_ask_token); then
129 echo 'To get user starred gists, a token is needed'
130 return 1
131 fi
132 fi
133}
134
135# load configuration
136_apply_config() {
137 source $CONFIG && _validate_config
138
139 AUTH_HEADER="Authorization: token $token"
140 [[ -z "$action" ]] && action="${EDITOR:-vi} *"
141 [[ -z "$folder" ]] && folder=~/gist && mkdir -p $folder
142 INDEX=$folder/index
143}
101 144
102github_api=https://api.github.com 145_apply_config "$@" || exit 1
103auth_header="Authorization: token $token" 146
147## This function determines which http get tool the system has installed and returns an error if there isnt one
148getConfiguredClient() {
149 if command -v curl &>/dev/null; then
150 configuredClient="curl"
151 elif command -v wget &>/dev/null; then
152 configuredClient="wget"
153 elif command -v http &>/dev/null; then
154 configuredClient="httpie"
155 elif command -v fetch &>/dev/null; then
156 configuredClient="fetch"
157 else
158 echo "Error: This tool requires either curl, wget, httpie or fetch to be installed." >&2
159 return 1
160 fi
161}
104 162
105[[ -z "$folder" ]] && folder=~/gist 163## Allows to call the users configured client without if statements everywhere
106mkdir -p $folder 164httpGet() {
107index=$folder/index 165 local header=""
108starred=$folder/starred 166 case "$configuredClient" in
167 curl) [[ -n $token ]] && header="--header Authorization: token $token"; curl -A curl -s $header "$@" ;;
168 wget) [[ -n $token ]] && header="--header Authorization: token $token"; wget -qO- $header "$@" ;;
169 httpie) [[ -n $token ]] && header="Authorization:token $token"; http -b GET "$@" "$header";;
170 fetch) fetch -q "$@" ;;
171 esac
172}
109 173
110# Show the list of gist, but not updated time 174# Show the list of gist, but not updated time
111# TODO a way to show files 175# TODO a way to show files
112# TODO show git status outdated 176# TODO show git status outdated
113_show_list() { 177_show_list() {
114 if [[ ! -e "$1" ]]; then 178 if [[ ! -e $INDEX ]]; then
115 echo No local file found for last update 179 echo 'No local file found for last update, please run command:'
116 echo Please run command: 180 echo ' gist update'
117 echo " gist update" 181 return 0
118 exit 0 182 fi
119 fi 183 local filter=""
120 cat $1 \ 184 if [[ $1 == "s" ]]; then
121 | while read line_num link file_url_array file_num extra description; do 185 filter='/^[^s]/ d'
122 local repo=$folder/$(echo $link | sed 's#.*/##') 186 else
123 local occupy=0 187 filter='/^s/ d'
124 188 fi
125 # if repo is not yet cloned, show green message "Not cloned yet" 189 cat $INDEX \
126 [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=17 190 | while read index link blob_code file_num extra description; do
127 191 local repo=$folder/$(echo $link | sed 's#.*/##')
128 # if there are some changes in git index or working directory, show blue message "working" 192 local occupy=0
129 [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=10 193
130 # if there is a commit not yet push, show red message "ahead" 194 # if repo is not yet cloned, show green message "Not cloned yet"
131 [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=8 195 [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16
132 196 # if there are some changes in git index or working directory, show blue message "working"
133 echo -e $line_num $link $file_num $extra $(echo $description | cut -c -$(( 60 - $occupy )) ) 197 [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9
134 done 198 # if there is a commit not yet push, show red message "ahead"
199 [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7
200
201 echo -e $index $link $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) )
202 done \
203 | sed "$filter"
135} 204}
136 205
137# get the list of gists 206# parse JSON from STDIN with string of commands
138_update() { 207AccessJsonElement() {
139 echo "fetching from api.github.com..." 208 PYTHONIOENCODING=utf-8 \
140 echo 209 python -c "from __future__ import print_function; import sys, json; raw = json.load(sys.stdin); $1" 2> /dev/null
141 local list_file=$index 210 return "$?"
142 local route="users/$user/gists"
143 local mark=""
144 [[ "$1" =~ ^(star|s)$ ]] && list_file=$starred && route="gists/starred" && mark="s"
145
146 curl -s -H "$auth_header" $github_api/$route \
147 | _parse_response | nl -s' ' | sed -E "s/^ */$mark/" > $list_file \
148 && _show_list $list_file \
149 || echo Fail to update gists
150
151 if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi
152} 211}
153 212
154# equal to: jq '.[] | "\(.html_url) \([.files[] | .raw_url]) \(.files | keys | length) \(.comments) \(.description)"' 213# equal to: jq '.[] | "\(.html_url) \([.files[] | .raw_url]) \(.files | keys | length) \(.comments) \(.description)"'
@@ -157,6 +216,7 @@ _handle_gists() {
157for gist in raw: 216for gist in raw:
158 print(gist["html_url"], end=" ") 217 print(gist["html_url"], end=" ")
159 print([file["raw_url"] for file in gist["files"].values()], end=" ") 218 print([file["raw_url"] for file in gist["files"].values()], end=" ")
219 print(gist["public"], end=" ")
160 print(len(gist["files"]), end=" ") 220 print(len(gist["files"]), end=" ")
161 print(gist["comments"], end=" ") 221 print(gist["comments"], end=" ")
162 print(gist["description"]) 222 print(gist["description"])
@@ -164,83 +224,110 @@ for gist in raw:
164} 224}
165 225
166# TODO check if a user create a very first gist 226# TODO check if a user create a very first gist
227# parse response from gists require
167_parse_response() { 228_parse_response() {
168 AccessJsonElement "$(_handle_gists)" \ 229 AccessJsonElement "$(_handle_gists)" \
169 | tac | sed 's/, /,/g'\ 230 | tac | sed 's/, /,/g' | nl -s' ' \
170 | while read link file_url_array file_num comment_num description; do 231 | while read index link file_url_array public file_num comment_num description; do
171 local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-') 232 local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-')
172 echo $link $blob_code $file_num $comment_num $description | tr -d '"' 233 [[ $public == 'False' ]] && local mark=p
173 done 234 [[ -n $1 ]] && local index=$1
235 echo $mark$index $link $blob_code $file_num $comment_num $description | tr -d '"'
236 done
237}
238
239# get latest list of gists from Github API
240_update() {
241 echo "fetching $user's gists from $GITHUB_API..."
242 echo
243 local route="users/$user/gists"
244 local mark=""
245 local filter='/^[^s]/ d'
246 if [[ "$1" =~ ^(star|s)$ ]];then
247 route="gists/starred"
248 mark="s"
249 filter='/^[s]/ d'
250 fi
251
252 local response=$(httpGet $GITHUB_API/$route)
253 false && echo Failed to update gists && return 1
254 sed -i "$filter" $INDEX
255 echo $response | _parse_response >> $INDEX
256 _show_list $mark
257
258 if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi
174} 259}
175 260
261# update local git repos
176_sync_repos() { 262_sync_repos() {
177 local list_file=$index 263 # clone repos which are not in the local
178 [[ "$1" =~ ^(star|s)$ ]] && list_file=$starred && route="gists/starred" 264 comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \
179 265 <(cat $INDEX | cut -d' ' -f2 | sed 's#.*/##' | sort) \
180 # clone repos which are not in the local 266 | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{}
181 comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ 267
182 <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \ 268 # pull if remote repo has different blob objects
183 | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{} 269 cat $INDEX | cut -d' ' -f2,3 \
184 270 | while read url blob_code_remote; do
185 # pull if remote repo has different blob objects 271 local repo=$folder/$(echo $url | sed 's#.*/##')
186 cat $index | cut -d' ' -f2,3 \ 272 local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-')
187 | while read url blob_code_remote; do 273 cd $repo \
188 local repo=$folder/$(echo $url | sed 's#.*/##') 274 && [[ $blob_code_local != $blob_code_remote ]] \
189 local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-') 275 && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \
190 cd $repo \ 276 && git pull
191 && [[ $blob_code_local != $blob_code_remote ]] \ 277 done
192 &&[[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \ 278 echo Everything is fine!
193 && git pull
194 done
195 echo Everything is fine!
196} 279}
197 280
198# get gist id from index files 281# get gist id from index files
199_gist_id() { 282_gist_id() {
200 GIST_ID=$( (grep -hs '' $index $starred || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##') 283 GIST_ID=$( (grep -hs '' $INDEX || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##')
201 if [[ -z "$GIST_ID" ]]; then 284 if [[ -z "$GIST_ID" ]]; then
202 echo -e "Not a valid index: \e[31m$1\e[0m" 285 echo -e "Not a valid index: \e[31m$1\e[0m"
203 echo Use the index number in the first column instead: 286 echo Use the index in the first column instead:
204 echo 287 echo
205 _show_list "$index" 288 _show_list
206 exit 1 289 return 1
207 fi 290 fi
208} 291}
209 292
210_goto_gist() { 293_goto_gist() {
211 _gist_id $1 294 _gist_id $1 || return 1
212 295
213 if [[ ! -d $folder/$GIST_ID ]]; then 296 if [[ ! -d $folder/$GIST_ID ]]; then
214 echo 'Cloning gist as repo...' 297 echo 'Cloning gist as repo...'
215 git clone git@github.com:$GIST_ID.git $folder/$GIST_ID \ 298 git clone git@github.com:$GIST_ID.git $folder/$GIST_ID
216 && echo 'Repo is cloned' \ 299
217 || echo 'Failed to clone the gist' 300 if [[ $? -eq 0 ]]; then
301 echo 'Repo is cloned' > /dev/tty
302 else
303 echo 'Failed to clone the gist' > /dev/tty
304 return 1
218 fi 305 fi
306 fi
219 307
220 echo This gist is at $folder/$GIST_ID 308 (cd $folder/$GIST_ID && eval "$action")
221 echo -e "You can run the following command to jump to this directory: \n" 309 echo $folder/$GIST_ID
222 echo -e " \e[32m. gist $1\e[0m\n"
223 cd $folder/$GIST_ID && ls && tig --all 2> /dev/null
224} 310}
225 311
226_delete_gist() { 312_delete_gist() {
227 for i in "$@"; do 313 for i in "$@"; do
228 _gist_id "$i" 314 _gist_id "$i"
229 curl -X DELETE -s -H "$auth_header" $github_api/gists/$GIST_ID \ 315 curl -X DELETE -s -H "$AUTH_HEADER" $GITHUB_API/gists/$GIST_ID \
230 && echo "$i" deleted \ 316 && echo "$i" deleted \
231 && sed -i -E "/^$i / d" $index 317 && sed -i -E "/^$i / d" $INDEX
232 done 318 done
233} 319}
234 320
235# remove repos which are not in user gists anymore 321# remove repos which are not in user gists anymore
236_clean_repos() { 322_clean_repos() {
237 comm -23 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ 323 comm -23 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \
238 <(cat $index $starred 2> /dev/null | cut -d' ' -f2 | sed 's#.*/##' | sort) \ 324 <(cat $INDEX 2> /dev/null | cut -d' ' -f2 | sed 's#.*/##' | sort) \
239 | while read dir; do 325 | while read dir; do
240 mv $folder/$dir /tmp && echo move $folder/$dir to /tmp 326 mv $folder/$dir /tmp && echo move $folder/$dir to /tmp
241 done 327 done
242} 328}
243 329
330# parse JSON from gist detail
244_handle_gist() { 331_handle_gist() {
245 echo ' 332 echo '
246print("site:", raw["html_url"]) 333print("site:", raw["html_url"])
@@ -269,104 +356,92 @@ for comment in raw:
269 356
270# TODO format with simple text 357# TODO format with simple text
271_show_detail() { 358_show_detail() {
272 _gist_id $1 359 _gist_id $1
273 curl -s $github_api/gists/$GIST_ID \ 360 httpGet $GITHUB_API/gists/$GIST_ID \
274 | AccessJsonElement "$(_handle_gist)" 361 | AccessJsonElement "$(_handle_gist)"
275 362
276 curl -s $github_api/gists/$GIST_ID/comments \ 363 httpGet $GITHUB_API/gists/$GIST_ID/comments \
277 | AccessJsonElement "$(_handle_comment)" 364 | AccessJsonElement "$(_handle_comment)"
278} 365}
279 366
280# FIXME put file before parameters 367# set filename/description/permission for a new gist
281_set_gist() { 368_set_gist() {
282 while [[ "$1" =~ ^- && "$1" != "--" ]]; do case $1 in 369 public=true
283 -d | --desc) 370 while [[ -n "$@" ]]; do case $1 in
284 description="$2" 371 -d | --desc)
285 shift; shift;; 372 description="$2"
286 -f | --file) 373 shift; shift;;
287 filename="$2" 374 -f | --file)
288 shift; shift;; 375 filename="$2"
289 esac 376 shift; shift;;
290 done 377 -p)
291 if [[ "$1" == '--' ]]; then shift; fi 378 public=false
292 files="$@" 379 shift;;
293 ls $files > /dev/null || exit 1 380 *)
381 files="$1 $files"
382 shift;;
383 esac
384 done
385 ls $files > /dev/null || return 1
294} 386}
295 387
388# Let user type the content of gist before setting filename
296_new_file() { 389_new_file() {
297 [[ -t 0 ]] && echo "Type a gist. <Ctrl-C> to cancel, <Ctrl-D> when done" > /dev/tty 390 [[ -t 0 ]] && echo "Type a gist. <Ctrl-C> to cancel, <Ctrl-D> when done" > /dev/tty
298 tmp_file=$(mktemp) 391 local tmp_file=$(mktemp)
299 cat > $tmp_file 392 cat > $tmp_file
300 echo -e '\n' > /dev/tty 393 echo -e '\n' > /dev/tty
301 [[ -z "$1" ]] && read -p 'Type file name: ' filename < /dev/tty 394 [[ -z "$1" ]] && read -p 'Type file name: ' filename < /dev/tty
302 mv $tmp_file /tmp/$filename 395 mv $tmp_file /tmp/$filename
303 echo /tmp/$filename 396 echo /tmp/$filename
304} 397}
305 398
306# create a new gist with files 399# create a new gist with files
307# TODO support secret gist
308_create_gist() { 400_create_gist() {
309 _set_gist "$@" 401 _set_gist "$@" || return 1
310 [[ -z "$files" ]] && files=$(_new_file $filename) 402 [[ -z "$files" ]] && files=$(_new_file $filename)
311 [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty 403 [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty
312 404
313 for file in $files; do 405 local index=$(( $(sed '/^s/ d' $INDEX | wc -l) +1 ))
314 echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"}," 406 echo 'Creating a new gist...'
315 done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \ 407 for file in $files; do
316 | echo "{ \"public\": true, \"files\": $(cat -), \"description\": \"$description\"}" \ 408 echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"},"
317 | curl -s -H "$auth_header" --data @- $github_api/gists \ 409 done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \
318 | sed '1 s/^/[/; $ s/$/]/' \ 410 | echo "{ \"public\": $public, \"files\": $(cat -), \"description\": \"$description\"}" \
319 | _parse_response \ 411 | curl -s -H "$AUTH_HEADER" --data @- $GITHUB_API/gists \
320 | sed -E "s/^/$(( $(wc -l $index | cut -d' ' -f1) + 1 )) /" >> $index \ 412 | tee jojo \
321 && echo -e '\nGist created' \ 413 | sed '1 s/^/[/; $ s/$/]/' \
322 || echo 'Fail to create gist' 414 | _parse_response $index >> $INDEX
323 415
324 _show_list $index | tail -1 416 if [[ $? -eq 0 ]]; then
417 echo 'Gist is created'
418 _show_list | tail -1
419 else
420 echo 'Failed to create gist'
421 fi
325} 422}
326 423
327# update description of a gist 424# update description of a gist
328_edit_gist() { 425_edit_gist() {
329 _gist_id $1 426 _gist_id $1
330
331 echo -n 'Type new description: '
332 read DESC < /dev/tty
333 echo "{ \"description\": \"$DESC\" }" \
334 | curl -X PATCH -H "$auth_header" --data @- $github_api/gists/$GIST_ID > /dev/null \
335 && _update
336}
337
338_help_message() {
339 sed -E -n ' /^$/ q; 8,$ s/^#//p' $0
340}
341 427
342_cases() { 428 echo -n 'Type new description: '
343 if [[ $1 == 'token' ]]; then 429 read DESC < /dev/tty
344 [[ ${#2} -eq 40 ]] && echo $1=$2 \ 430 echo "{ \"description\": \"$DESC\" }" \
345 || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty 431 | curl -X PATCH -H "$AUTH_HEADER" --data @- $GITHUB_API/gists/$GIST_ID > /dev/null \
346 elif [[ $1 == 'auto_sync' ]]; then 432 && _update
347 [[ $2 == 'false' ]] && echo $1=$2 \
348 || echo $1=true
349 elif [[ $1 == 'folder' ]]; then
350 [[ -n "$2" ]] && echo $1=$2 \
351 || echo $1=~/gist
352 elif [[ $1 == 'user' ]]; then
353 echo $1=$2
354 fi
355} 433}
356 434
357_configure() { 435usage() {
358 [[ -z "$@" ]] && (vim $config) && exit 0 436 sed -E -n ' /^$/ q; 8,$ s/^#//p' $0
359 target=$(_cases "$@")
360
361 [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $config && echo $target >> $config
362 cat $config
363} 437}
364 438
439getConfiguredClient
365case "$1" in 440case "$1" in
366 "") 441 "")
367 _show_list $index ;; 442 _show_list ;;
368 star | s) 443 star | s)
369 _show_list $starred ;; 444 _show_list s ;;
370 update | u) 445 update | u)
371 _update "$2" ;; 446 _update "$2" ;;
372 new | n) 447 new | n)
@@ -388,7 +463,7 @@ case "$1" in
388 shift 463 shift
389 _configure "$@" ;; 464 _configure "$@" ;;
390 help | h) 465 help | h)
391 _help_message ;; 466 usage ;;
392 *) 467 *)
393 _goto_gist "$1" ;; 468 _goto_gist "$1" ;;
394esac 469esac