diff options
-rwxr-xr-x | gist | 76 |
1 files changed, 58 insertions, 18 deletions
@@ -6,7 +6,7 @@ | |||
6 | # | 6 | # |
7 | # | 7 | # |
8 | # This script host your gists as local cloned git repo | 8 | # This script host your gists as local cloned git repo |
9 | # It works under GNU with jq and curl, both are easy to get in most cases | 9 | # It works under GNU curl, which is easy to get in most cases |
10 | # | 10 | # |
11 | # Use the following commands to manage your gists: | 11 | # Use the following commands to manage your gists: |
12 | # | 12 | # |
@@ -46,13 +46,12 @@ | |||
46 | # It is your business to do git commit and git push | 46 | # It is your business to do git commit and git push |
47 | # | 47 | # |
48 | # * configuration | 48 | # * configuration |
49 | # gist (config | c) [token <value>] [user <value>] [folder <value>] | 49 | # gist (config | c) [token <value>] [user <value>] [folder <value>] [auto-sync false] |
50 | # | 50 | # |
51 | # * show this help message | 51 | # * show this help message |
52 | # gist (help | h) | 52 | # gist (help | h) |
53 | 53 | ||
54 | # TODO error handling, unit test | 54 | # TODO error handling, unit test |
55 | # TODO parallel branch works with json parsing on python | ||
56 | # TODO parallel branch works with wget and other stuff | 55 | # TODO parallel branch works with wget and other stuff |
57 | # TODO completion | 56 | # TODO completion |
58 | # TODO grep mode for description, file content | 57 | # TODO grep mode for description, file content |
@@ -62,6 +61,12 @@ config=~/.config/gistrc | |||
62 | set -eo pipefail | 61 | set -eo pipefail |
63 | [ "$TRACE" ] && set -x | 62 | [ "$TRACE" ] && set -x |
64 | 63 | ||
64 | ## parse JSON from STDIN with string of commands | ||
65 | AccessJsonElement() { | ||
66 | PYTHONIOENCODING=utf-8 python -c "from __future__ import print_function; import sys, json; raw = json.load(sys.stdin); $1" | ||
67 | return "$?" | ||
68 | } | ||
69 | |||
65 | _auth() { | 70 | _auth() { |
66 | echo 'Hi fellow! To access your gists, I need your Github username and a personal token with scope which allows "gist"!' | 71 | echo 'Hi fellow! To access your gists, I need your Github username and a personal token with scope which allows "gist"!' |
67 | read -p "Github username: " user < /dev/tty | 72 | read -p "Github username: " user < /dev/tty |
@@ -146,12 +151,24 @@ _update() { | |||
146 | if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi | 151 | if [[ $auto_sync != "false" ]]; then (_sync_repos $1 > /dev/null 2>&1 &); fi |
147 | } | 152 | } |
148 | 153 | ||
154 | # equal to: jq '.[] | "\(.html_url) \([.files[] | .raw_url]) \(.files | keys | length) \(.comments) \(.description)"' | ||
155 | _handle_gists() { | ||
156 | echo ' | ||
157 | for gist in raw: | ||
158 | print(gist["html_url"], end=" ") | ||
159 | print([file["raw_url"] for file in gist["files"].values()], end=" ") | ||
160 | print(len(gist["files"]), end=" ") | ||
161 | print(gist["comments"], end=" ") | ||
162 | print(gist["description"]) | ||
163 | ' | ||
164 | } | ||
165 | |||
149 | # TODO check if a user create a very first gist | 166 | # TODO check if a user create a very first gist |
150 | _parse_response() { | 167 | _parse_response() { |
151 | jq '.[] | "\(.html_url) \([.files[] | .raw_url]) \(.files | keys | length) \(.comments) \(.description)"' \ | 168 | AccessJsonElement "$(_handle_gists)" \ |
152 | | tac \ | 169 | | tac | sed 's/, /,/g'\ |
153 | | while read link file_url_array file_num comment_num description; do | 170 | | while read link file_url_array file_num comment_num description; do |
154 | local blob_code=$(echo $file_url_array | jq -r '.[]' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-') | 171 | local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -sd '-') |
155 | echo $link $blob_code $file_num $comment_num $description | tr -d '"' | 172 | echo $link $blob_code $file_num $comment_num $description | tr -d '"' |
156 | done | 173 | done |
157 | } | 174 | } |
@@ -163,7 +180,7 @@ _sync_repos() { | |||
163 | # clone repos which are not in the local | 180 | # clone repos which are not in the local |
164 | comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ | 181 | comm -13 <(find $folder -maxdepth 1 -type d | sed '1d; s#.*/##' | sort) \ |
165 | <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \ | 182 | <(cat $list_file | cut -d' ' -f2 | sed 's#.*/##' | sort) \ |
166 | | xargs -I{} git clone git@github.com:{}.git $folder/{} | 183 | | xargs -I{} --max-procs 8 git clone git@github.com:{}.git $folder/{} |
167 | 184 | ||
168 | # pull if remote repo has different blob objects | 185 | # pull if remote repo has different blob objects |
169 | cat $index | cut -d' ' -f2,3 \ | 186 | cat $index | cut -d' ' -f2,3 \ |
@@ -178,8 +195,9 @@ _sync_repos() { | |||
178 | echo Everything is fine! | 195 | echo Everything is fine! |
179 | } | 196 | } |
180 | 197 | ||
198 | # get gist id from index files | ||
181 | _gist_id() { | 199 | _gist_id() { |
182 | GIST_ID=$(cat $index $starred 2> /dev/null | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##') | 200 | GIST_ID=$( (grep -hs '' $index $starred || true) | sed -n "/^$1 / p" | cut -d' ' -f2 | sed -E 's#.*/##') |
183 | if [[ -z "$GIST_ID" ]]; then | 201 | if [[ -z "$GIST_ID" ]]; then |
184 | echo -e "Not a valid index: \e[31m$1\e[0m" | 202 | echo -e "Not a valid index: \e[31m$1\e[0m" |
185 | echo Use the index number in the first column instead: | 203 | echo Use the index number in the first column instead: |
@@ -223,16 +241,43 @@ _clean_repos() { | |||
223 | done | 241 | done |
224 | } | 242 | } |
225 | 243 | ||
244 | _handle_gist() { | ||
245 | echo ' | ||
246 | print("site:", raw["html_url"]) | ||
247 | print("description:", raw["description"]) | ||
248 | print("public:", raw["public"]) | ||
249 | print("API:", raw["url"]) | ||
250 | print("created_at:", raw["created_at"]) | ||
251 | print("updated_at:", raw["updated_at"]) | ||
252 | print("files:") | ||
253 | for file in raw["files"].keys(): | ||
254 | print(" ", file) | ||
255 | ' | ||
256 | } | ||
257 | |||
258 | # equal to jq '.[] | {user: .user.login, created_at: .created_at, updated_at: .updated_at, body: .body}' | ||
259 | _handle_comment() { | ||
260 | echo ' | ||
261 | for comment in raw: | ||
262 | print() | ||
263 | print("|", "user:", comment["user"]["login"]) | ||
264 | print("|", "created_at:", comment["created_at"]) | ||
265 | print("|", "updated_at:", comment["updated_at"]) | ||
266 | print("|", comment["body"]) | ||
267 | ' | ||
268 | } | ||
269 | |||
226 | # TODO format with simple text | 270 | # TODO format with simple text |
227 | _show_detail() { | 271 | _show_detail() { |
228 | _gist_id $1 | 272 | _gist_id $1 |
229 | curl -s $github_api/gists/$GIST_ID \ | 273 | curl -s $github_api/gists/$GIST_ID \ |
230 | | jq '{site: .html_url, description: .description, public: .public, API: .url, created_at: .created_at, updated_at: .updated_at, files: (.files | keys)}' | 274 | | AccessJsonElement "$(_handle_gist)" |
231 | 275 | ||
232 | curl -s $github_api/gists/$GIST_ID/comments \ | 276 | curl -s $github_api/gists/$GIST_ID/comments \ |
233 | | jq '.[] | {user: .user.login, created_at: .created_at, updated_at: .updated_at, body: .body}' | 277 | | AccessJsonElement "$(_handle_comment)" |
234 | } | 278 | } |
235 | 279 | ||
280 | # FIXME put file before parameters | ||
236 | _set_gist() { | 281 | _set_gist() { |
237 | while [[ "$1" =~ ^- && "$1" != "--" ]]; do case $1 in | 282 | while [[ "$1" =~ ^- && "$1" != "--" ]]; do case $1 in |
238 | -d | --desc) | 283 | -d | --desc) |
@@ -266,14 +311,9 @@ _create_gist() { | |||
266 | [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty | 311 | [[ -z "$description" ]] && read -p 'Type description: ' description < /dev/tty |
267 | 312 | ||
268 | for file in $files; do | 313 | for file in $files; do |
269 | FILE=$(basename $file) | 314 | echo "\"$(basename $file)\": {\"content\": \"$(sed '$ !s/$/\\n/' $file)\"}," |
270 | jq --arg FILE "$FILE" '. as $content | { ($FILE): {content: $content} }' -Rs $file | 315 | done | tr -d '\n' | sed 's/^/{/; s/,$/}/' \ |
271 | done \ | 316 | | echo "{ \"public\": true, \"files\": $(cat -), \"description\": \"$description\"}" \ |
272 | | jq --slurp --arg DESC "$description" '{ | ||
273 | public: true, | ||
274 | files: add, | ||
275 | description: ($DESC) | ||
276 | }' \ | ||
277 | | curl -s -H "$auth_header" --data @- $github_api/gists \ | 317 | | curl -s -H "$auth_header" --data @- $github_api/gists \ |
278 | | sed '1 s/^/[/; $ s/$/]/' \ | 318 | | sed '1 s/^/[/; $ s/$/]/' \ |
279 | | _parse_response \ | 319 | | _parse_response \ |