diff options
-rwxr-xr-x | gist | 57 |
1 files changed, 40 insertions, 17 deletions
@@ -5,33 +5,36 @@ | |||
5 | # https://gist.github.com/typebrook/b0d2e7e67aa50298fdf8111ae7466b56 | 5 | # https://gist.github.com/typebrook/b0d2e7e67aa50298fdf8111ae7466b56 |
6 | # | 6 | # |
7 | # gist | 7 | # gist |
8 | # Description: Host your gists as local cloned git repo | 8 | # Description: Manage your gists with git and Github API v3 |
9 | # Usage: gist [command] [<args>] | 9 | # Usage: gist [command] [<args>] |
10 | # | 10 | # |
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> [--no-action] 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>] [-p] <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>] [-p] [-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 |
18 | # edit, e <index_of_gist> edit a gist description | 18 | # edit, e <index_of_gist> edit a gist's description |
19 | # delete, D <index_of_gist>... delete a gist | 19 | # delete, D <index_of_gist>... delete a gist |
20 | # clean, C clean removed gists in local | 20 | # clean, C clean removed gists in local |
21 | # config, c [token | user | folder | auto_sync | EDITOR | action [value] ] do configuration | 21 | # config, c [token | user | folder | auto_sync | EDITOR | action [value] ] do configuration |
22 | # user, U <user> get gists from a given Github user | 22 | # user, U <user> get gists from a given Github user |
23 | # grep, g <pattern> grep gists by a given pattern | 23 | # grep, g <pattern> grep gists by a given pattern |
24 | # github, G <index_of_gist> Import this gist as a new Github repo | ||
24 | # push, p <pattern> push changes by git | 25 | # push, p <pattern> push changes by git |
25 | # help, h show this help message | 26 | # help, h show this help message |
26 | # | 27 | # |
27 | # Example: | 28 | # Example: |
28 | # gist (Show your gists) | 29 | # gist (Show your gists) |
30 | # gist update (update the list of gists from github.com) | ||
29 | # gist 3 (show the repo path of your 3rd gist, and do custom actions) | 31 | # gist 3 (show the repo path of your 3rd gist, and do custom actions) |
32 | # gist 3 --no-action (show the repo path of your 3rd gist, and do not perform actions) | ||
33 | # gist new foo --desc bar (create a new gist with file and description) | ||
30 | # | 34 | # |
31 | # Since now a gist is a local cloned repo | 35 | # Since now a gist is a local cloned repo |
32 | # It is your business to do git commit and git push | 36 | # It is your business to do git commit and git push |
33 | 37 | ||
34 | # TODO import to github repo (may need a new token) | ||
35 | # TODO test on bats, mac and remote machine | 38 | # TODO test on bats, mac and remote machine |
36 | # TODO completion | 39 | # TODO completion |
37 | 40 | ||
@@ -49,15 +52,17 @@ _configure() { | |||
49 | [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 | 52 | [[ -z "$@" ]] && (${EDITOR:-vi} $CONFIG) && return 0 |
50 | 53 | ||
51 | local target="" | 54 | local target="" |
52 | if [[ $1 == 'user' ]]; then | 55 | if [[ $1 =~ ^(user|token|folder|auto_sync|EDITOR|action)$ ]]; then |
53 | [[ -z $2 ]] && echo "Must specify username" >&2 && return 1 | 56 | if [[ $1 == 'user' ]]; then |
54 | elif [[ $1 == 'token' ]]; then | 57 | [[ -z $2 ]] && echo "Must specify username" >&2 && return 1 |
55 | [[ ${#2} -ne 40 ]] && echo 'Invalid token format, it is not 40 chars' >&2 \ | 58 | elif [[ $1 == 'token' ]]; then |
56 | && return 1 | 59 | [[ ${#2} -ne 40 ]] && echo 'Invalid token format, it is not 40 chars' >&2 \ |
57 | elif [[ $1 == 'auto_sync' ]]; then | 60 | && return 1 |
58 | [[ ! $2 =~ ^(true|false)$ ]] && return 1 | 61 | elif [[ $1 == 'auto_sync' ]]; then |
62 | [[ ! $2 =~ ^(true|false)$ ]] && return 1 | ||
63 | fi | ||
64 | target=$1=$2 | ||
59 | fi | 65 | fi |
60 | target=$1=$2 | ||
61 | 66 | ||
62 | umask 0077 && touch $CONFIG | 67 | umask 0077 && touch $CONFIG |
63 | sed -i "/^$1=/ d" $CONFIG && [[ "$target" =~ [^=]$ ]] && echo $target >> $CONFIG | 68 | sed -i "/^$1=/ d" $CONFIG && [[ "$target" =~ [^=]$ ]] && echo $target >> $CONFIG |
@@ -120,8 +125,6 @@ _apply_config() { | |||
120 | INDEX=$folder/index; [[ -e $INDEX ]] || touch $INDEX | 125 | INDEX=$folder/index; [[ -e $INDEX ]] || touch $INDEX |
121 | } | 126 | } |
122 | 127 | ||
123 | _apply_config "$@" || exit 1 | ||
124 | |||
125 | # This function determines which http get tool the system has installed and returns an error if there isnt one | 128 | # This function determines which http get tool the system has installed and returns an error if there isnt one |
126 | getConfiguredClient() { | 129 | getConfiguredClient() { |
127 | if command -v curl &>/dev/null; then | 130 | if command -v curl &>/dev/null; then |
@@ -176,6 +179,8 @@ _show_list() { | |||
176 | [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16 | 179 | [[ ! -d $repo ]] && extra="\e[32m[Not cloned yet]\e[0m" && occupy=16 |
177 | # if there are some changes in git index or working directory, show blue message "working" | 180 | # if there are some changes in git index or working directory, show blue message "working" |
178 | [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9 | 181 | [[ -n $(cd $repo && git status --short) ]] 2>/dev/null && extra="\e[36m[working]\e[0m" && occupy=9 |
182 | # if there files are different, show red message "outdated" | ||
183 | [[ $(_blob_code $repo) != $blob_code ]] 2>/dev/null && extra="\e[31m[outdated]\e[0m" && occupy=10 | ||
179 | # if there is a commit not yet push, show red message "ahead" | 184 | # if there is a commit not yet push, show red message "ahead" |
180 | [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 | 185 | [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 |
181 | 186 | ||
@@ -187,7 +192,15 @@ _show_list() { | |||
187 | 192 | ||
188 | # TODO support filenames, file contents | 193 | # TODO support filenames, file contents |
189 | _grep_content() { | 194 | _grep_content() { |
190 | _show_list other | grep -i $1 | 195 | _show_list | grep -i $1 |
196 | } | ||
197 | |||
198 | # TODO support filenames, file contents | ||
199 | _import_to_github() { | ||
200 | _gist_id $1 | ||
201 | echo put the folowing URL into webpage: | ||
202 | echo -n git@github.com:$GIST_ID.git | ||
203 | python -mwebbrowser https://github.com/new/import | ||
191 | } | 204 | } |
192 | 205 | ||
193 | _push_to_remote() { | 206 | _push_to_remote() { |
@@ -230,6 +243,7 @@ _parse_response() { | |||
230 | done | 243 | done |
231 | } | 244 | } |
232 | 245 | ||
246 | # TODO pagnation for more than 30 gists | ||
233 | # TODO add files and date of a gist | 247 | # TODO add files and date of a gist |
234 | # get latest list of gists from Github API | 248 | # get latest list of gists from Github API |
235 | _update() { | 249 | _update() { |
@@ -264,6 +278,11 @@ _query_user() { | |||
264 | done | 278 | done |
265 | } | 279 | } |
266 | 280 | ||
281 | _blob_code() { | ||
282 | cd $1 \ | ||
283 | && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-' | ||
284 | } | ||
285 | |||
267 | # update local git repos | 286 | # update local git repos |
268 | _sync_repos() { | 287 | _sync_repos() { |
269 | # clone repos which are not in the local | 288 | # clone repos which are not in the local |
@@ -275,7 +294,7 @@ _sync_repos() { | |||
275 | cat $INDEX | cut -d' ' -f2,3 \ | 294 | cat $INDEX | cut -d' ' -f2,3 \ |
276 | | while read url blob_code_remote; do | 295 | | while read url blob_code_remote; do |
277 | local repo=$folder/$(echo $url | sed 's#.*/##') | 296 | local repo=$folder/$(echo $url | sed 's#.*/##') |
278 | local blob_code_local=$(cd $repo && git ls-tree master | cut -d' ' -f3 | cut -c-7 | sort | paste -sd '-') | 297 | local blob_code_local=$(_blob_code $repo) |
279 | cd $repo \ | 298 | cd $repo \ |
280 | && [[ $blob_code_local != $blob_code_remote ]] \ | 299 | && [[ $blob_code_local != $blob_code_remote ]] \ |
281 | && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \ | 300 | && [[ $(git rev-parse origin/master) == $(git rev-parse master) ]] \ |
@@ -463,6 +482,7 @@ usage() { | |||
463 | sed -E -n ' /^$/ q; 7,$ s/^# //p' $0 | 482 | sed -E -n ' /^$/ q; 7,$ s/^# //p' $0 |
464 | } | 483 | } |
465 | 484 | ||
485 | _apply_config "$@" || exit 1 | ||
466 | getConfiguredClient | 486 | getConfiguredClient |
467 | if [[ $init ]]; then _update; exit 0; fi | 487 | if [[ $init ]]; then _update; exit 0; fi |
468 | case "$1" in | 488 | case "$1" in |
@@ -496,6 +516,9 @@ case "$1" in | |||
496 | grep | g) | 516 | grep | g) |
497 | shift | 517 | shift |
498 | _grep_content "$@" ;; | 518 | _grep_content "$@" ;; |
519 | github | G) | ||
520 | shift | ||
521 | _import_to_github "$1" ;; | ||
499 | push | p) | 522 | push | p) |
500 | shift | 523 | shift |
501 | _push_to_remote "$1" ;; | 524 | _push_to_remote "$1" ;; |