diff options
| -rwxr-xr-x | gist | 65 |
1 files changed, 33 insertions, 32 deletions
| @@ -11,7 +11,7 @@ | |||
| 11 | # [star | s] list your gists with format below, star for your starred gists: | 11 | # [star | s] list your gists with format below, star for your starred gists: |
| 12 | # [index_of_gist] [url] [file_num] [comment_num] [short description] | 12 | # [index_of_gist] [url] [file_num] [comment_num] [short description] |
| 13 | # update, u [star | s] update the local list of your gists, star for your starred gists | 13 | # update, u [star | s] update the local list of your gists, star for your starred gists |
| 14 | # <index_of_gist> show the path of local gist repo and do custom actions | 14 | # <index_of_gist> [--no-action] show the path of local gist repo and do custom actions |
| 15 | # new, n [-d | --desc <description>] <files>... create a new gist with files | 15 | # new, n [-d | --desc <description>] <files>... create a new gist with files |
| 16 | # new, n [-d | --desc <description>] [-f | --file <file_name>] create a new gist from STDIN | 16 | # new, n [-d | --desc <description>] [-f | --file <file_name>] create a new gist from STDIN |
| 17 | # detail, d <index_of_gist> show the detail of a gist | 17 | # detail, d <index_of_gist> show the detail of a gist |
| @@ -31,15 +31,14 @@ | |||
| 31 | 31 | ||
| 32 | # TODO grep mode for description, file content | 32 | # TODO grep mode for description, file content |
| 33 | # TODO push github.com (may need new token) | 33 | # TODO push github.com (may need new token) |
| 34 | # TODO description for current directory | ||
| 35 | # TODO unit test | 34 | # TODO unit test |
| 36 | # TODO test on mac and remote machine | 35 | # TODO test on bats, mac and remote machine |
| 37 | # TODO completion | 36 | # TODO completion |
| 38 | 37 | ||
| 39 | # Shell configuration | 38 | # Shell configuration |
| 40 | set -o pipefail | 39 | set -o pipefail |
| 41 | [ "$TRACE" ] && set -x | 40 | [ "$TRACE" ] && set -x |
| 42 | trap 'rm -f "$http_data" "tmp_file"' EXIT | 41 | trap 'rm -f "$http_data" "$tmp_file"' EXIT |
| 43 | 42 | ||
| 44 | GITHUB_API=https://api.github.com | 43 | GITHUB_API=https://api.github.com |
| 45 | CONFIG=~/.config/gist.conf; mkdir -p ~/.config | 44 | CONFIG=~/.config/gist.conf; mkdir -p ~/.config |
| @@ -47,23 +46,21 @@ configuredClient="" | |||
| 47 | 46 | ||
| 48 | # handle configuration cases | 47 | # handle configuration cases |
| 49 | _configure() { | 48 | _configure() { |
| 50 | local target="" | ||
| 51 | [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 | 49 | [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 |
| 52 | if [[ $1 == 'token' ]]; then | 50 | |
| 53 | [[ ${#2} -eq 40 ]] && target=$1=$2 \ | 51 | local target="" |
| 54 | || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty | 52 | if [[ $1 == 'user' ]]; then |
| 53 | [[ -z $2 ]] && echo "Must specify username" >&2 && return 1 | ||
| 54 | elif [[ $1 == 'token' ]]; then | ||
| 55 | [[ ${#2} -ne 40 ]] && echo 'Invalid token format, it is not 40 chars' >&2 \ | ||
| 56 | && return 1 | ||
| 55 | elif [[ $1 == 'auto_sync' ]]; then | 57 | elif [[ $1 == 'auto_sync' ]]; then |
| 56 | [[ $2 == 'false' ]] && target=$1=$2 \ | 58 | [[ ! $2 =~ ^(true|false)$ ]] && return 1 |
| 57 | || target=$1=true | ||
| 58 | elif [[ $1 == 'folder' ]]; then | ||
| 59 | [[ -n "$2" ]] && target=$1=$2 \ | ||
| 60 | || target=$1=~/gist | ||
| 61 | elif [[ $1 == 'user' ]]; then | ||
| 62 | target=$1=$2 | ||
| 63 | fi | 59 | fi |
| 60 | target=$1=$2 | ||
| 64 | 61 | ||
| 65 | umask 0077 && touch $CONFIG | 62 | umask 0077 && touch $CONFIG |
| 66 | [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $CONFIG && echo $target >> $CONFIG | 63 | sed -i "/^$1=/ d" $CONFIG && [[ "$target" =~ [^=]$ ]] && echo $target >> $CONFIG |
| 67 | cat $CONFIG | 64 | cat $CONFIG |
| 68 | } | 65 | } |
| 69 | 66 | ||
| @@ -93,14 +90,14 @@ _ask_token() { | |||
| 93 | _configure token $token | 90 | _configure token $token |
| 94 | } | 91 | } |
| 95 | 92 | ||
| 93 | # check configuration is fine with user setting | ||
| 96 | _validate_config(){ | 94 | _validate_config(){ |
| 97 | source $CONFIG 2> /dev/null || true | 95 | source $CONFIG 2> /dev/null || true |
| 98 | if [[ ! -e $CONFIG || -z $user ]]; then | 96 | if [[ ! -e $CONFIG || -z $user ]]; then |
| 99 | echo 'Hi fellow! To access your gists, I need your Github username' | 97 | echo 'Hi fellow! To access your gists, I need your Github username' |
| 100 | echo "Also a personal token with scope which allows "gist"!'" | 98 | echo "Also a personal token with scope which allows "gist"!'" |
| 101 | echo | 99 | echo |
| 102 | _ask_username | 100 | _ask_username && _ask_token && init=true |
| 103 | _ask_token | ||
| 104 | elif [[ -z $token && $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then | 101 | elif [[ -z $token && $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then |
| 105 | if ! (_ask_token); then | 102 | if ! (_ask_token); then |
| 106 | echo 'To create/edit/delete a gist, a token is needed' | 103 | echo 'To create/edit/delete a gist, a token is needed' |
| @@ -161,19 +158,17 @@ http_method() { | |||
| 161 | } | 158 | } |
| 162 | 159 | ||
| 163 | # Show the list of gist, but not updated time | 160 | # Show the list of gist, but not updated time |
| 164 | # TODO a way to show files | ||
| 165 | # TODO show git status outdated | ||
| 166 | _show_list() { | 161 | _show_list() { |
| 167 | if [[ ! -e $INDEX ]]; then | 162 | if [[ ! -e $INDEX ]]; then |
| 168 | echo 'No local file found for last update, please run command:' | 163 | echo 'No local file found for last update, please run command:' |
| 169 | echo ' gist update' | 164 | echo ' gist update' |
| 170 | return 0 | 165 | return 0 |
| 171 | fi | 166 | fi |
| 172 | local filter='/^s/ d; /^$/ d' | 167 | local filter='/^ *s/ d; /^$/ d' |
| 173 | [[ $1 == "s" ]] && filter='/^[^s]/ d; /^$/ d' | 168 | [[ $1 == "s" ]] && filter='/^ *[^ s]/ d; /^$/ d' |
| 174 | 169 | ||
| 175 | while read index link blob_code file_num extra author description; do | 170 | while read index link blob_code file_num extra author description; do |
| 176 | [[ $1 == "s" ]] && local author=$author | 171 | [[ $1 == "s" ]] && local name=$author |
| 177 | local repo=$folder/$(echo $link | sed 's#.*/##') | 172 | local repo=$folder/$(echo $link | sed 's#.*/##') |
| 178 | local occupy=0 | 173 | local occupy=0 |
| 179 | 174 | ||
| @@ -184,10 +179,10 @@ _show_list() { | |||
| 184 | # if there is a commit not yet push, show red message "ahead" | 179 | # if there is a commit not yet push, show red message "ahead" |
| 185 | [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 | 180 | [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 |
| 186 | 181 | ||
| 187 | echo -e $index $link $author $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) | 182 | echo -e "$(printf "% 3s" $index)" $link $name $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) |
| 188 | done < $INDEX \ | 183 | done < $INDEX \ |
| 189 | | sed "$filter" | 184 | | sed "$filter" |
| 190 | echo -e '\nrun "gist help" for more details' | 185 | echo -e '\nrun "gist help" for more details' > /dev/tty |
| 191 | } | 186 | } |
| 192 | 187 | ||
| 193 | # parse JSON from STDIN with string of commands | 188 | # parse JSON from STDIN with string of commands |
| @@ -225,7 +220,7 @@ _parse_response() { | |||
| 225 | done | 220 | done |
| 226 | } | 221 | } |
| 227 | 222 | ||
| 228 | # TODO add author, files and date of a gist | 223 | # TODO add files and date of a gist |
| 229 | # get latest list of gists from Github API | 224 | # get latest list of gists from Github API |
| 230 | _update() { | 225 | _update() { |
| 231 | echo "fetching $user's gists from $GITHUB_API..." | 226 | echo "fetching $user's gists from $GITHUB_API..." |
| @@ -306,7 +301,7 @@ _goto_gist() { | |||
| 306 | fi | 301 | fi |
| 307 | fi | 302 | fi |
| 308 | 303 | ||
| 309 | (cd $folder/$GIST_ID && eval "$action") | 304 | [[ $2 != '--no-action' ]] && cd $folder/$GIST_ID && eval "$action" |
| 310 | echo $folder/$GIST_ID | 305 | echo $folder/$GIST_ID |
| 311 | } | 306 | } |
| 312 | 307 | ||
| @@ -425,7 +420,10 @@ _create_gist() { | |||
| 425 | | AccessJsonElement "$(_gist_body)" > $http_data \ | 420 | | AccessJsonElement "$(_gist_body)" > $http_data \ |
| 426 | && http_method POST $GITHUB_API/gists \ | 421 | && http_method POST $GITHUB_API/gists \ |
| 427 | | sed '1 s/^/[/; $ s/$/]/' \ | 422 | | sed '1 s/^/[/; $ s/$/]/' \ |
| 428 | | _parse_response $(( $(sed '/^s/ d' $INDEX | wc -l) +1 )) >> $INDEX | 423 | | _parse_response $(( $(sed '/^s/ d' $INDEX | wc -l) +1 )) \ |
| 424 | | tee -a $INDEX \ | ||
| 425 | | cut -d' ' -f2 | sed -E 's#.*/##' \ | ||
| 426 | | (xargs -I{} git clone git@github.com:{}.git $folder/{} &> /dev/null &) | ||
| 429 | 427 | ||
| 430 | if [[ $? -eq 0 ]]; then | 428 | if [[ $? -eq 0 ]]; then |
| 431 | echo 'Gist is created' | 429 | echo 'Gist is created' |
| @@ -441,16 +439,19 @@ _edit_gist() { | |||
| 441 | 439 | ||
| 442 | echo -n 'Type new description: ' | 440 | echo -n 'Type new description: ' |
| 443 | read DESC < /dev/tty | 441 | read DESC < /dev/tty |
| 444 | echo "{ \"description\": \"$DESC\" }" \ | 442 | |
| 445 | | http_method PATCH $GITHUB_API/gists/$GIST_ID > /dev/null \ | 443 | http_data=$(mktemp) |
| 444 | echo "{ \"description\": \"$DESC\" }" > $http_data | ||
| 445 | http_method PATCH $http_data $GITHUB_API/gists/$GIST_ID > /dev/null \ | ||
| 446 | && _update | 446 | && _update |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | usage() { | 449 | usage() { |
| 450 | sed -E -n ' /^$/ q; 7,$ s/^#//p' $0 | 450 | sed -E -n ' /^$/ q; 7,$ s/^# //p' $0 |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | getConfiguredClient | 453 | getConfiguredClient |
| 454 | if [[ $init ]]; then _update; exit 0; fi | ||
| 454 | case "$1" in | 455 | case "$1" in |
| 455 | "") | 456 | "") |
| 456 | _show_list ;; | 457 | _show_list ;; |
| @@ -482,5 +483,5 @@ case "$1" in | |||
| 482 | help | h) | 483 | help | h) |
| 483 | usage ;; | 484 | usage ;; |
| 484 | *) | 485 | *) |
| 485 | _goto_gist "$1" ;; | 486 | _goto_gist "$@" ;; |
| 486 | esac | 487 | esac |