From 4fa39cc191d2a6283ec5dd8455159896115376ea Mon Sep 17 00:00:00 2001 From: typebrook Date: Fri, 31 Jan 2020 15:29:12 +0800 Subject: update --- scripts/gist | 384 +++++++++++++++++++++++++++++------------------------------ 1 file 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 configuredClient="" _config_cases() { - if [[ $1 == 'token' ]]; then - [[ ${#2} -eq 40 ]] && echo $1=$2 \ - || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty - elif [[ $1 == 'auto_sync' ]]; then - [[ $2 == 'false' ]] && echo $1=$2 \ - || echo $1=true - elif [[ $1 == 'folder' ]]; then - [[ -n "$2" ]] && echo $1=$2 \ - || echo $1=~/gist - elif [[ $1 == 'user' ]]; then - echo $1=$2 - fi + if [[ $1 == 'token' ]]; then + [[ ${#2} -eq 40 ]] && echo $1=$2 \ + || echo -e Invalid token format, it is not 40 chars '\n' > /dev/tty + elif [[ $1 == 'auto_sync' ]]; then + [[ $2 == 'false' ]] && echo $1=$2 \ + || echo $1=true + elif [[ $1 == 'folder' ]]; then + [[ -n "$2" ]] && echo $1=$2 \ + || echo $1=~/gist + elif [[ $1 == 'user' ]]; then + echo $1=$2 + fi } _configure() { - [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 - target=$(_config_cases "$@") + [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 + target=$(_config_cases "$@") - umask 0077 && touch $CONFIG - [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $CONFIG && echo $target >> $CONFIG - cat $CONFIG + umask 0077 && touch $CONFIG + [[ "$target" =~ [^=]$ ]] && sed -i "/^$1=/ d" $CONFIG && echo $target >> $CONFIG + cat $CONFIG } _ask_username() { - while [[ ! $user =~ ^[[:alnum:]]+$ ]]; do - [[ -n $user ]] && echo "Not a valid username" - read -p "Github username: " user < /dev/tty - done - _configure user $user + while [[ ! $user =~ ^[[:alnum:]]+$ ]]; do + [[ -n $user ]] && echo "Not a valid username" + read -p "Github username: " user < /dev/tty + done + _configure user $user } _ask_token() { - echo -n "Create a new token from web browser? [Y/n] " - read answer < /dev/tty - if [[ ! $answer =~ ^(N|n|No|NO|no)$ ]]; then - python -mwebbrowser https://github.com/settings/tokens/new\?scopes\=gist; - fi + echo -n "Create a new token from web browser? [Y/n] " + read answer < /dev/tty + if [[ ! $answer =~ ^(N|n|No|NO|no)$ ]]; then + python -mwebbrowser https://github.com/settings/tokens/new\?scopes\=gist; + fi - while [[ ! $token =~ ^[[:alnum:]]{40}$ ]]; do - [[ -n $token ]] && echo "Not a valid token" - trap 'echo; return 1' INT - read -p "Paste your token here (Ctrl-C to skip): " token < /dev/tty - done - _configure token $token + while [[ ! $token =~ ^[[:alnum:]]{40}$ ]]; do + [[ -n $token ]] && echo "Not a valid token" + trap 'echo; return 1' INT + read -p "Paste your token here (Ctrl-C to skip): " token < /dev/tty + done + _configure token $token } _apply_config() { - source $CONFIG 2> /dev/null || true - if [[ ! -e $CONFIG ]] || [[ -z $user ]]; then - echo 'Hi fellow! To access your gists, I need your Github username' - echo "Also a personal token with scope which allows "gist"!'" - echo - _ask_username - _ask_token - elif [[ -z $token ]] && [[ $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then - if ! (_ask_token); then - echo 'To create/edit/delete a gist, a token is needed' - return 1 - fi + source $CONFIG 2> /dev/null || true + if [[ ! -e $CONFIG ]] || [[ -z $user ]]; then + echo 'Hi fellow! To access your gists, I need your Github username' + echo "Also a personal token with scope which allows "gist"!'" + echo + _ask_username + _ask_token + elif [[ -z $token ]] && [[ $1 =~ ^(n|new|e|edit|D|delete)$ ]]; then + if ! (_ask_token); then + echo 'To create/edit/delete a gist, a token is needed' + return 1 fi + fi - source $CONFIG + source $CONFIG } _apply_config "$@" || exit 1 @@ -172,25 +172,25 @@ httpGet() # TODO a way to show files # TODO show git status outdated _show_list() { - if [[ ! -e "$1" ]]; then - echo 'No local file found for last update, please run command:' - echo " gist update $([[ $1 == $STARRED ]] && echo 'star')" - return 0 - fi - cat $1 \ - | while read index link blob_code file_num extra description; do - local repo=$folder/$(echo $link | sed 's#.*/##') - local occupy=0 - - # if repo is not yet cloned, show green message "Not cloned yet" - [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16 - # if there are some changes in git index or working directory, show blue message "working" - [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9 - # if there is a commit not yet push, show red message "ahead" - [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 - - echo -e $index $link $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) - done + if [[ ! -e "$1" ]]; then + echo 'No local file found for last update, please run command:' + echo " gist update $([[ $1 == $STARRED ]] && echo 'star')" + return 0 + fi + cat $1 \ + | while read index link blob_code file_num extra description; do + local repo=$folder/$(echo $link | sed 's#.*/##') + local occupy=0 + + # if repo is not yet cloned, show green message "Not cloned yet" + [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16 + # if there are some changes in git index or working directory, show blue message "working" + [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9 + # if there is a commit not yet push, show red message "ahead" + [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 + + echo -e $index $link $file_num $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) + done } # parse JSON from STDIN with string of commands @@ -215,106 +215,105 @@ for gist in raw: # TODO check if a user create a very first gist _parse_response() { - AccessJsonElement "$(_handle_gists)" \ - | tac | sed 's/, /,/g' | nl -s' ' \ - | while read index link file_url_array public file_num comment_num description; do - local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-') - [[ $public == 'False' ]] && mark=p - [[ -n $1 ]] && index=$1 - echo $mark$index $link $blob_code $file_num $comment_num $description | tr -d '"' - done + AccessJsonElement "$(_handle_gists)" \ + | tac | sed 's/, /,/g' | nl -s' ' \ + | while read index link file_url_array public file_num comment_num description; do + local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-') + [[ $public == 'False' ]] && mark=p + [[ -n $1 ]] && index=$1 + echo $mark$index $link $blob_code $file_num $comment_num $description | tr -d '"' + done } # get the list of gists _update() { - echo "fetching $user's gists from $GITHUB_API..." - echo - local list_file=$INDEX - local route="users/$user/gists" - local mark="" - [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" && mark="s" - - curl -H "$auth_header" $GITHUB_API/$route \ - | _parse_response | sed -E "s/^ */$mark/" > $list_file \ - && _show_list $list_file \ - || echo Fail to update gists - - if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi + echo "fetching $user's gists from $GITHUB_API..." + echo + local list_file=$INDEX + local route="users/$user/gists" + local mark="" + [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" && mark="s" + + curl -H "$auth_header" $GITHUB_API/$route \ + | _parse_response | sed -E "s/^ */$mark/" > $list_file \ + && _show_list $list_file \ + || echo Fail to update gists + + if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi } _sync_repos() { - local list_file=$INDEX - [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" - - # clone repos which are not in the local - comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ - <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \ - | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{} - - # pull if remote repo has different blob objects - cat $INDEX | cut -d' ' -f2,3 \ - | while read url blob_code_remote; do - local repo=$folder/$(echo $url | sed 's#.*/##') - local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-') - cd $repo \ - && [[ $blob_code_local != $blob_code_remote ]] \ - && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \ - && git pull - done - echo Everything is fine! + local list_file=$INDEX + [[ "$1" =~ ^(star|s)$ ]] && list_file=$STARRED && route="gists/starred" + + # clone repos which are not in the local + comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ + <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \ + | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{} + + # pull if remote repo has different blob objects + cat $INDEX | cut -d' ' -f2,3 \ + | while read url blob_code_remote; do + local repo=$folder/$(echo $url | sed 's#.*/##') + local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-') + cd $repo \ + && [[ $blob_code_local != $blob_code_remote ]] \ + && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \ + && git pull + done + echo Everything is fine! } # get gist id from index files _gist_id() { - GIST_ID=$( (grep -hs '' $INDEX $STARRED || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##') - if [[ -z "$GIST_ID" ]]; then - echo -e "Not a valid index: \e[31m$1\e[0m" - echo Use the index in the first column instead: - echo - _show_list "$INDEX" - return 1 - fi + GIST_ID=$( (grep -hs '' $INDEX $STARRED || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##') + if [[ -z "$GIST_ID" ]]; then + echo -e "Not a valid index: \e[31m$1\e[0m" + echo Use the index in the first column instead: + echo + _show_list "$INDEX" + return 1 + fi } # TODO a better way without source +# FIXME source cause eixt _goto_gist() { - _gist_id $1 - - if [[ ! -d $folder/$GIST_ID ]]; then - echo 'Cloning gist as repo...' - git clone git@github.com:$GIST_ID.git $folder/$GIST_ID - if [[ "$?" -ne 0 ]]; then - echo 'Repo is cloned' - return 0 - else - echo 'Failed to clone the gist' - return 1 - fi + _gist_id $1 + + if [[ ! -d $folder/$GIST_ID ]]; then + echo 'Cloning gist as repo...' + git clone git@github.com:$GIST_ID.git $folder/$GIST_ID + if [[ "$?" -ne 0 ]]; then + echo 'Repo is cloned' + else + echo 'Failed to clone the gist' fi + fi - echo This gist is at $folder/$GIST_ID - echo -e "You can run the following command to jump to this directory: \n" - echo -e " \e[32m. gist $1\e[0m\n" - echo -n 'files: ' && cd $folder/$GIST_ID && ls - tig --all 2> /dev/null || true + echo This gist is at $folder/$GIST_ID + echo -e "You can run the following command to jump to this directory: \n" + echo -e " \e[32m. gist $1\e[0m\n" + echo -n 'files: ' && cd $folder/$GIST_ID && ls + tig --all 2> /dev/null || true } _delete_gist() { - for i in "$@"; do - _gist_id "$i" - curl -X DELETE -s -H "$auth_header" $GITHUB_API/gists/$GIST_ID \ - && echo "$i" deleted \ - && sed -i -E "/^$i / d" $INDEX - done + for i in "$@"; do + _gist_id "$i" + curl -X DELETE -s -H "$auth_header" $GITHUB_API/gists/$GIST_ID \ + && echo "$i" deleted \ + && sed -i -E "/^$i / d" $INDEX + done } # remove repos which are not in user gists anymore _clean_repos() { - comm -23 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ - <(cat $INDEX $STARRED 2> /dev/null | cut -d' ' -f2 | sed 's#.*/##' | sort) \ - | while read dir; do - mv $folder/$dir /tmp && echo move $folder/$dir to /tmp - done + comm -23 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ + <(cat $INDEX $STARRED 2> /dev/null | cut -d' ' -f2 | sed 's#.*/##' | sort) \ + | while read dir; do + mv $folder/$dir /tmp && echo move $folder/$dir to /tmp + done } _handle_gist() { @@ -345,77 +344,78 @@ for comment in raw: # TODO format with simple text _show_detail() { - _gist_id $1 - httpGet $GITHUB_API/gists/$GIST_ID \ - | AccessJsonElement "$(_handle_gist)" + _gist_id $1 + httpGet $GITHUB_API/gists/$GIST_ID \ + | AccessJsonElement "$(_handle_gist)" - httpGet $GITHUB_API/gists/$GIST_ID/comments \ - | AccessJsonElement "$(_handle_comment)" + httpGet $GITHUB_API/gists/$GIST_ID/comments \ + | AccessJsonElement "$(_handle_comment)" } _set_gist() { - public=true - while [[ -n "$@" ]]; do case $1 in - -d | --desc) - description="$2" - shift; shift;; - -f | --file) - filename="$2" - shift; shift;; - -p) - public=false - shift;; - *) - files="$1 $files" - shift;; - esac - done - ls $files > /dev/null || return 1 + public=true + while [[ -n "$@" ]]; do case $1 in + -d | --desc) + description="$2" + shift; shift;; + -f | --file) + filename="$2" + shift; shift;; + -p) + public=false + shift;; + *) + files="$1 $files" + shift;; + esac + done + ls $files > /dev/null || return 1 } _new_file() { - [[ -t 0 ]] && echo "Type a gist. to cancel, when done" > /dev/tty - tmp_file=$(mktemp) - cat > $tmp_file - echo -e '\n' > /dev/tty - [[ -z "$1" ]] && read -p 'Type file name: ' filename < /dev/tty - mv $tmp_file /tmp/$filename - echo /tmp/$filename + [[ -t 0 ]] && echo "Type a gist. to cancel, when done" > /dev/tty + tmp_file=$(mktemp) + cat > $tmp_file + echo -e '\n' > /dev/tty + [[ -z "$1" ]] && read -p 'Type file name: ' filename < /dev/tty + mv $tmp_file /tmp/$filename + echo /tmp/$filename } # create a new gist with files # FIXME catch status code from curl if it fails _create_gist() { - _set_gist "$@" || return 1 - [[ -z "$files" ]] && files=$(_new_file $filename) - [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty - - for file in $files; do - echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"}," - done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \ - | echo "{ \"public\": $public, \"files\": $(cat -), \"description\": \"$description\"}" \ - | curl -s -H "$auth_header" --data @- $GITHUB_API/gists \ - | sed '1 s/^/[/; $ s/$/]/' \ - | _parse_response $(( $(sed '/^s/ d' $INDEX | wc -l) +1 )) >> $INDEX \ - && echo -e '\nGist created' \ - || echo 'Fail to create gist' - - _show_list $INDEX | tail -1 + _set_gist "$@" || return 1 + [[ -z "$files" ]] && files=$(_new_file $filename) + [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty + + echo 'Creating a new gist' + for file in $files; do + echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"}," + done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \ + | echo "{ \"public\": $public, \"files\": $(cat -), \"description\": \"$description\"}" \ + | curl -s -H "$auth_header" --data @- $GITHUB_API/gists \ + | sed '1 s/^/[/; $ s/$/]/' \ + | _parse_response $(( $(sed '/^s/ d' $INDEX | wc -l) +1 )) >> $INDEX \ + && echo -e '\nGist created' \ + || echo 'Fail to create gist' + + _show_list $INDEX | tail -1 } # update description of a gist _edit_gist() { - _gist_id $1 + _gist_id $1 - echo -n 'Type new description: ' - read DESC < /dev/tty - echo "{ \"description\": \"$DESC\" }" \ - | curl -X PATCH -H "$auth_header" --data @- $GITHUB_API/gists/$GIST_ID > /dev/null \ - && _update + echo -n 'Type new description: ' + read DESC < /dev/tty + echo "{ \"description\": \"$DESC\" }" \ + | curl -X PATCH -H "$auth_header" --data @- $GITHUB_API/gists/$GIST_ID > /dev/null \ + && _update } usage() { - sed -E -n ' /^$/ q; 8,$ s/^#//p' $0 + sed -E -n ' /^$/ q; 8,$ s/^#//p' $0 } getConfiguredClient -- cgit v1.2.3-70-g09d2