├── .gitignore ├── Gist.alfredextension ├── Gist.alfredworkflow ├── Makefile ├── README.md ├── functions.sh ├── gist.sh ├── icon.png ├── info.plist ├── screenshots ├── 1.png ├── 2.png └── setup.png └── tests ├── helper.sh ├── test_cli.sh ├── test_configure.sh └── test_settings.sh /.gitignore: -------------------------------------------------------------------------------- 1 | config 2 | -------------------------------------------------------------------------------- /Gist.alfredextension: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phallstrom/AlfredGist/5a264d156038d97d9139dca57c8308208e983627/Gist.alfredextension -------------------------------------------------------------------------------- /Gist.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phallstrom/AlfredGist/5a264d156038d97d9139dca57c8308208e983627/Gist.alfredworkflow -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EXTENSION = Gist.alfredworkflow 2 | BUNDLEID = pjkh.gist 3 | VERSION = 2.0.10 4 | SOURCE_FILES = functions.sh gist.sh icon.png info.plist 5 | PKG_FILES = $(SOURCE_FILES) 6 | 7 | WORKFLOW_DIR = $(HOME)/Dropbox/AlfredApp/Alfred.alfredpreferences/workflows 8 | INSTALL_DIR = `grep -l -- ">$(BUNDLEID)<" "$(WORKFLOW_DIR)"/*/info.plist | sed 's/\/info.plist//'` 9 | 10 | all: $(EXTENSION) 11 | 12 | $(EXTENSION): $(SOURCE_FILES) VERSION 13 | zip -rT $(EXTENSION) $(PKG_FILES) 14 | 15 | VERSION: 16 | touch info.plist 17 | 18 | clean: 19 | rm -rf $(EXTENSION) 20 | 21 | test: 22 | @roundup tests/test_* 23 | 24 | local-install: 25 | [[ -d "$(INSTALL_DIR)" ]] && cp -r $(PKG_FILES) "$(INSTALL_DIR)/" 26 | 27 | update-info-plist: 28 | [[ -d "$(INSTALL_DIR)" ]] && cp -r "$(INSTALL_DIR)/info.plist" . 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alfred Workflow - Gist 2 | 3 | A workflow for [Alfred](http://www.alfredapp.com/) to create [Gists](https://gist.github.com/) from your clipboard contents or selected files. 4 | 5 | ![Example 1](https://raw.github.com/phallstrom/AlfredGist/master/screenshots/1.png) 6 | ![Example 2](https://raw.github.com/phallstrom/AlfredGist/master/screenshots/2.png) 7 | 8 | ## Requirements 9 | 10 | - Alfred Version 2. 11 | - The Alfred [Powerpack](http://www.alfredapp.com/powerpack/). 12 | - A [GitHub](http://github.com) account. 13 | - [Gist.alfredworkflow](Gist.alfredworkflow?raw=true). 14 | 15 | ## Setup 16 | 17 | This workflow requires API access to gist.github.com. This requires a personal access token. 18 | Follow these steps to create and configure this token into the workflow. 19 | 20 | 1. Go to [Personal access tokens](https://github.com/settings/tokens) in your account settings. 21 | 1. Click [Generate New Token](https://github.com/settings/tokens/new). 22 | 1. Enter in a reasonable token description such as 'Alfred Gist Workflow'. 23 | 1. Ensure that the only selected scope is 'gist'. 24 | 1. Click 'Generate Token'. 25 | 1. Copy the newly generated token to your clipboard. 26 | 1. In Alfred, type `gistconfig` and select the 'Your API access token is' line to set your token. 27 | 28 | It should look something like this: 29 | ![Setup](https://raw.github.com/phallstrom/AlfredGist/master/screenshots/setup.png) 30 | 31 | ## Configure 32 | 33 | Type `gistconfig` to view the existing configuration or change them. When 34 | changing the token and server the value is taken from the clipboard. 35 | 36 | If you want to share your configuration across multiple machines (ie. via 37 | Dropbox) you can provide a shared configuration directory. This directory must 38 | exist before setting it via the configuration. 39 | 40 | ## Help 41 | 42 | Type `gist help` to view this help. If you need more help 43 | [open an issue](https://github.com/phallstrom/AlfredGist/issues) and I'll see what I can do. 44 | 45 | ## Usage 46 | 47 | ### Files 48 | 49 | If activated as a file action, the contents of the selected file(s) will be 50 | gisted using whatever public/private setting is currently in effect. 51 | 52 | ### Clipboard Contents 53 | 54 | **Public/private gists:** 55 | 56 | * `gist private` - a private gist. 57 | * `gist public` - a public gist. 58 | * `gist p` - a gist using the opposite of your current public configuration value. That is, if by default your gists are private `gist p` will create a public one (and vice versa). 59 | 60 | **Anonymous gists:** 61 | 62 | Gists will be associated with your account by default. 63 | 64 | * `gist a` - an anonymous gist. 65 | * `gist anon` - an anonymous gist. 66 | 67 | **All of the following examples can take the public/private or the anonymous parameter (but only one of them) as the first argument.** 68 | 69 | * `gist rb` - a gist with a filename of "gist.rb" (ie. Ruby syntax). 70 | * `gist .rb` - a gist with a filename of "gist.rb" (ie. Ruby syntax). 71 | * `gist foo.rb` - a gist with a filename of "foo.rb". 72 | * `gist ipsum lorem` - a gist with no filename/syntax and a description of "ipsum lorem" 73 | * `gist - ipsum lorem` - a gist with no filename/syntax and a description of "ipsum lorem" 74 | * `gist .rb ipsum lorem` - a gist with a filename of "gist.rb" and a description of "ipsum lorem" 75 | * `gist foo.rb ipsum lorem` - a gist with a filename of "foo.rb" and a description of "ipsum lorem" 76 | * `gist rb ipsum lorem` - a gist with *no filename* and a description of "rb ipsum lorem" 77 | * `gist - foo.rb ipsum lorem` - a gist with *no filename* and a description of "foo.rb ipsum lorem" 78 | 79 | **Note the lack of a period or the addition of "-" in the filename argument has when specifying a description.** 80 | 81 | ## Contributions & Thanks 82 | 83 | * JJ Asghar 84 | 85 | ## License: 86 | 87 | (The MIT License) 88 | 89 | Copyright (c) 2012 Philip Hallstrom 90 | 91 | Permission is hereby granted, free of charge, to any person obtaining 92 | a copy of this software and associated documentation files (the 93 | 'Software'), to deal in the Software without restriction, including 94 | without limitation the rights to use, copy, modify, merge, publish, 95 | distribute, sublicense, and/or sell copies of the Software, and to 96 | permit persons to whom the Software is furnished to do so, subject to 97 | the following conditions: 98 | 99 | The above copyright notice and this permission notice shall be 100 | included in all copies or substantial portions of the Software. 101 | 102 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 103 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 104 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 105 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 106 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 107 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 108 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 109 | 110 | -------------------------------------------------------------------------------- /functions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OUR_DIR=$(cd $(dirname "$0"); pwd) 4 | [[ ! -d "$PREF_DIR" ]] && mkdir -p "$PREF_DIR" 2>/dev/null 5 | 6 | function echo_start_items() { 7 | echo '' 8 | echo '' 9 | } 10 | 11 | function echo_end_items() { 12 | echo '' 13 | } 14 | 15 | function echo_item() { # uid, arg, valid, autocomplete, title, subtitle, icon 16 | echo "" 17 | echo "$5" 18 | echo "$6" 19 | echo "${7-icon.png}" 20 | echo "" 21 | } 22 | 23 | 24 | # 25 | # Set default settings, then load user's custom settings if config file exists. 26 | # 27 | function load_settings 28 | { 29 | server="api.github.com" 30 | token="" 31 | public="false" 32 | copy_url="true" 33 | open_url="true" 34 | shared_config_dir="" 35 | if [[ -r "$PREF_DIR/config" ]]; then 36 | source "$PREF_DIR/config" 37 | fi 38 | if [[ -n "$shared_config_dir" && -r "$shared_config_dir/config" ]]; then 39 | source "$shared_config_dir/config" 40 | fi 41 | } 42 | 43 | # 44 | # 45 | # 46 | function save_settings 47 | { 48 | if [[ -n "$shared_config_dir" ]]; then 49 | cat << EOT > "$shared_config_dir/config" 50 | server="$server" 51 | token="$token" 52 | public="$public" 53 | copy_url="$copy_url" 54 | open_url="$open_url" 55 | EOT 56 | cat << EOT > "$PREF_DIR/config" 57 | shared_config_dir="$shared_config_dir" 58 | EOT 59 | else 60 | cat << EOT > "$PREF_DIR/config" 61 | server="$server" 62 | token="$token" 63 | public="$public" 64 | copy_url="$copy_url" 65 | open_url="$open_url" 66 | EOT 67 | fi 68 | 69 | } 70 | 71 | # 72 | # 73 | # 74 | function set_option 75 | { 76 | local key=$1 77 | local val=$2 78 | 79 | case $key in 80 | shared_config_dir) 81 | if [[ -z "$val" ]]; then 82 | shared_config_dir="" 83 | elif [[ ! -d "$val" ]]; then 84 | echo "ERROR: '$val' must be an existing directory." 85 | exit 86 | else 87 | shared_config_dir=$val 88 | fi 89 | ;; 90 | server) 91 | if [[ -z "$val" ]]; then 92 | server="api.github.com" 93 | else 94 | server=$val 95 | fi 96 | ;; 97 | token) 98 | if [[ -z "$val" ]]; then 99 | echo "ERROR: Value must be a non-zero length string." 100 | exit 101 | else 102 | token=$val 103 | fi 104 | ;; 105 | public) 106 | if [[ ! "$val" =~ ^(true|false)$ ]]; then 107 | echo "ERROR: Value must be 'true' or 'false'." 108 | exit 109 | fi 110 | public=$val 111 | ;; 112 | copy_url) 113 | if [[ ! "$val" =~ ^(true|false)$ ]]; then 114 | echo "ERROR: Value must be 'true' or 'false'." 115 | exit 116 | fi 117 | copy_url=$val 118 | ;; 119 | open_url) 120 | if [[ ! "$val" =~ ^(true|false)$ ]]; then 121 | echo "ERROR: Value must be 'true' or 'false'." 122 | exit 123 | fi 124 | open_url=$val 125 | ;; 126 | *) 127 | echo "ERROR: Invalid option '$key'. Valid options are:" 128 | echo "token [string]" 129 | echo "public [true|false]" 130 | echo "copy_url [true|false]" 131 | echo "open_url [true|false]" 132 | echo "server [string]" 133 | echo "shared_config_dir [string]" 134 | ;; 135 | esac 136 | 137 | } 138 | 139 | 140 | 141 | # 142 | # Parse the command line and set all global variables we will need to complete 143 | # the script. 144 | # 145 | function parse_cli() 146 | { 147 | action="" 148 | description="" 149 | anonymous="false" 150 | files=() 151 | contents=() 152 | 153 | local arg1 154 | local arg2 155 | local arg3 156 | 157 | IFS=" " read arg1 arg2 arg3 <<< $* 158 | 159 | case $arg1 in 160 | help) 161 | action="help" 162 | return 163 | ;; 164 | configure) 165 | action="configure" 166 | key=$arg2 167 | val=$arg3 168 | return 169 | ;; 170 | anon) 171 | anonymous="true" 172 | ;; 173 | a) 174 | anonymous="true" 175 | ;; 176 | p) 177 | if [[ "$public" = "false" ]]; then 178 | set_option "public" "true" 179 | else 180 | set_option "public" "false" 181 | fi 182 | ;; 183 | public) 184 | set_option "public" "true" 185 | ;; 186 | private) 187 | set_option "public" "false" 188 | ;; 189 | _files) 190 | for i in ${*:2} 191 | do 192 | action="gist" 193 | files=("${files[@]}" "${i##*\/}") 194 | contents=("${contents[@]}" "`cat "$i"`") 195 | done 196 | return 197 | ;; 198 | *) 199 | if [[ -n "$arg3" ]]; then 200 | arg3="$arg2 $arg3" 201 | else 202 | arg3=$arg2 203 | fi 204 | arg2=$arg1 205 | ;; 206 | esac 207 | 208 | file=$arg2 209 | description=$arg3 210 | 211 | if [[ -n "$description" && ! "$file" =~ \. && "$file" != "-" ]]; then 212 | description="$file $description" 213 | file="-" 214 | fi 215 | 216 | if [[ -n "$file" ]]; then 217 | if [[ "$file" = "-" ]]; then 218 | file="" 219 | elif [[ "$file" =~ ^\.[^.]+$ ]]; then 220 | file="gist$file" 221 | elif [[ ! "$file" =~ \. ]]; then 222 | file="gist.$file" 223 | fi 224 | fi 225 | 226 | action="gist" 227 | files[0]=$file 228 | contents[0]=`pbpaste` 229 | } 230 | 231 | # 232 | # Escape JSON string 233 | # 234 | function json_escape() 235 | { 236 | echo -n "$1" | python -c 'import json,sys; print json.dumps(sys.stdin.read())' 237 | } 238 | 239 | # 240 | # Get Gist API endpoint from top level API 241 | # 242 | function get_gist_api() 243 | { 244 | # GitHub.com & GitHub Enterprise have different 245 | if [[ "${server}" == 'api.github.com' ]]; then 246 | echo "https://${server}/gists" 247 | else 248 | curl --silent --header "$auth_header" https://$server/api/v3 | python -c 'import json,sys; print json.loads(sys.stdin.read())["gists_url"].split("{")[0]' 249 | fi 250 | } 251 | 252 | # 253 | # 254 | # 255 | function create_gist 256 | { 257 | if [[ ${#contents[@]} -eq 0 ]]; then 258 | echo "ERROR: No content to gist." 259 | echo "Perhaps the $content_from is blank?" 260 | exit 261 | fi 262 | 263 | description=${description//\\/\\\\} 264 | description=${description//\"/\\\"} 265 | 266 | file_json='' 267 | 268 | for (( i = 0; i < ${#contents[@]}; i++ )) 269 | do 270 | file=${files[$i]} 271 | content=${contents[$i]} 272 | 273 | [[ ${#contents[@]} -gt 1 ]] && file="$i-$file" 274 | 275 | file=${file//\\/\\\\} 276 | file=${file//\"/\\\"} 277 | 278 | content="$(json_escape "$content")" 279 | 280 | file_json="$file_json,\"$file\":{\"content\":$content}" 281 | 282 | done 283 | 284 | 285 | if [[ "$anonymous" = "false" ]]; then 286 | auth_header="Authorization: token $token" 287 | else 288 | auth_header="" 289 | fi 290 | 291 | gist_api="$(get_gist_api)" 292 | 293 | json=`\ 294 | curl \ 295 | --silent \ 296 | --header "$auth_header" \ 297 | --data "{\"description\":\"$description\",\"public\":$public,\"files\":{${file_json#,}}}" \ 298 | ${gist_api} \ 299 | ` 300 | 301 | gist_url=$(get_json_key "html_url" "$json") 302 | 303 | if [[ -n "$gist_url" ]]; then 304 | if [[ "$copy_url" = "true" ]]; then 305 | echo -n $gist_url | pbcopy 306 | echo "Gist URL has been copied to the clipboard." 307 | fi 308 | if [[ "$open_url" = "true" ]]; then 309 | open $gist_url 310 | fi 311 | else 312 | echo "ERROR: An API error occured." 313 | echo "" 314 | echo "$json" 315 | exit 316 | fi 317 | 318 | 319 | } 320 | 321 | # 322 | # Usage: 323 | # val=$(get_json_key "key" "json string") 324 | # 325 | # The quotes are critically important. 326 | # 327 | function get_json_key 328 | { 329 | local key=$1 330 | local json=$2 331 | local val='' 332 | if [[ "$json" =~ \"$key\"\: ]]; then 333 | val=${json#*$key\":\ \"} 334 | val=${val%%\"*} 335 | fi 336 | echo $val 337 | } 338 | 339 | -------------------------------------------------------------------------------- /gist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PREF_DIR="$HOME/Library/Application Support/Alfred 2/Workflow Data/pjkh.gist" 4 | 5 | export LANG=en_US.UTF-8 6 | export LC_ALL=en_US.UTF-8 7 | 8 | source functions.sh 9 | load_settings 10 | parse_cli $* 11 | 12 | if [[ -z "$token" && "$action" != "configure" && "$action" != "help" ]]; then 13 | echo "You need to setup and configure Gist. Type 'gist help' for details." 14 | exit 15 | fi 16 | 17 | case $action in 18 | help) 19 | open "https://github.com/phallstrom/AlfredGist#usage" 20 | exit 21 | ;; 22 | configure) 23 | 24 | newvalue=$(pbpaste | head -1 | iconv -c -t ASCII) 25 | 26 | if [[ -z "$key" && -z "$val" ]]; then 27 | echo_start_items 28 | if [[ "$public" = "true" ]]; then 29 | echo_item "gist_config_public" "configure public false" "yes" "" "Your gists are public by default." "Select to change the default to private." 30 | else 31 | echo_item "gist_config_public" "configure public true" "yes" "" "Your gists are private by default." "Select to change default to public." 32 | fi 33 | if [[ "$copy_url" = "true" ]]; then 34 | echo_item "gist_config_copy_url" "configure copy_url false" "yes" "" "The Gist URL is copied to your clipboard." "Select to not copy the URL." 35 | else 36 | echo_item "gist_config_copy_url" "configure copy_url true" "yes" "" "The Gist URL is not copied to your clipboard." "Select to copy the URL." 37 | fi 38 | if [[ "$open_url" = "true" ]]; then 39 | echo_item "gist_config_open_url" "configure open_url false" "yes" "" "The Gist URL is opened in a browser." "Select to not open the URL." 40 | else 41 | echo_item "gist_config_open_url" "configure open_url true" "yes" "" "The Gist URL is not opened in a browser." "Select to open the URL." 42 | fi 43 | echo_item "gist_config_token" "configure token $newvalue" "yes" "" "Your API access token is '$token'" "Select to change to '$newvalue'." 44 | echo_item "gist_config_server" "configure server $newvalue" "yes" "" "Your API server is '$server'" "Select to change to '$newvalue'." 45 | echo_item "gist_config_shared_config_dir" "configure shared_config_dir $newvalue" "yes" "" "Your shared config directory is '$shared_config_dir'" "Select to change to '$newvalue'." 46 | echo_end_items 47 | exit 48 | fi 49 | 50 | set_option "$key" "$val" 51 | save_settings 52 | echo "Gist configuration has been updated." 53 | exit 54 | ;; 55 | gist) 56 | create_gist 57 | ;; 58 | *) 59 | echo "ERROR: Unknown action '$action'." 60 | ;; 61 | esac 62 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phallstrom/AlfredGist/5a264d156038d97d9139dca57c8308208e983627/icon.png -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | pjkh.gist 7 | connections 8 | 9 | 3CE568C2-0A21-4BE6-97E3-BB057243B669 10 | 11 | 12 | destinationuid 13 | 825AE364-0819-4F85-9021-B9AEA0C64118 14 | modifiers 15 | 0 16 | modifiersubtext 17 | 18 | 19 | 20 | 4D5925E1-8D44-4873-8C32-AD9DEFFECB2D 21 | 22 | 23 | destinationuid 24 | 3CE568C2-0A21-4BE6-97E3-BB057243B669 25 | modifiers 26 | 0 27 | modifiersubtext 28 | 29 | 30 | 31 | 8490ED7E-339D-49CE-91F5-9ED557A5DA90 32 | 33 | 34 | destinationuid 35 | B504F4C6-F55E-4E55-B6A2-7DF195963813 36 | modifiers 37 | 0 38 | modifiersubtext 39 | 40 | 41 | 42 | 8A13345C-4BF4-4E07-A095-0A57B2B12DE4 43 | 44 | 45 | destinationuid 46 | 3CE568C2-0A21-4BE6-97E3-BB057243B669 47 | modifiers 48 | 0 49 | modifiersubtext 50 | 51 | 52 | 53 | B504F4C6-F55E-4E55-B6A2-7DF195963813 54 | 55 | 56 | destinationuid 57 | 825AE364-0819-4F85-9021-B9AEA0C64118 58 | modifiers 59 | 0 60 | modifiersubtext 61 | 62 | 63 | 64 | 65 | createdby 66 | Philip Hallstrom 67 | description 68 | Create Gist from clipboard or selected files 69 | disabled 70 | 71 | name 72 | Gist 73 | objects 74 | 75 | 76 | config 77 | 78 | acceptsmulti 79 | 80 | filetypes 81 | 82 | name 83 | Gist: Create from files 84 | 85 | type 86 | alfred.workflow.trigger.action 87 | uid 88 | 8490ED7E-339D-49CE-91F5-9ED557A5DA90 89 | version 90 | 0 91 | 92 | 93 | config 94 | 95 | escaping 96 | 63 97 | script 98 | bash gist.sh _files {query} 99 | type 100 | 0 101 | 102 | type 103 | alfred.workflow.action.script 104 | uid 105 | B504F4C6-F55E-4E55-B6A2-7DF195963813 106 | version 107 | 0 108 | 109 | 110 | config 111 | 112 | lastpathcomponent 113 | 114 | onlyshowifquerypopulated 115 | 116 | output 117 | 0 118 | removeextension 119 | 120 | sticky 121 | 122 | text 123 | {query} 124 | title 125 | Gist 126 | 127 | type 128 | alfred.workflow.output.notification 129 | uid 130 | 825AE364-0819-4F85-9021-B9AEA0C64118 131 | version 132 | 0 133 | 134 | 135 | config 136 | 137 | argumenttype 138 | 1 139 | keyword 140 | gist 141 | subtext 142 | Optionally specify options. See help for more information. 143 | text 144 | Gist: Create from clipboard 145 | withspace 146 | 147 | 148 | type 149 | alfred.workflow.input.keyword 150 | uid 151 | 8A13345C-4BF4-4E07-A095-0A57B2B12DE4 152 | version 153 | 0 154 | 155 | 156 | config 157 | 158 | escaping 159 | 62 160 | script 161 | bash gist.sh "{query}" 162 | type 163 | 0 164 | 165 | type 166 | alfred.workflow.action.script 167 | uid 168 | 3CE568C2-0A21-4BE6-97E3-BB057243B669 169 | version 170 | 0 171 | 172 | 173 | config 174 | 175 | argumenttype 176 | 2 177 | escaping 178 | 62 179 | keyword 180 | gistconfig 181 | script 182 | bash gist.sh configure 183 | subtext 184 | Public vs. Private, Copy URL to clipboard. 185 | title 186 | Gist: Configure default options 187 | type 188 | 0 189 | withspace 190 | 191 | 192 | type 193 | alfred.workflow.input.scriptfilter 194 | uid 195 | 4D5925E1-8D44-4873-8C32-AD9DEFFECB2D 196 | version 197 | 0 198 | 199 | 200 | readme 201 | 202 | uidata 203 | 204 | 3CE568C2-0A21-4BE6-97E3-BB057243B669 205 | 206 | ypos 207 | 200 208 | 209 | 4D5925E1-8D44-4873-8C32-AD9DEFFECB2D 210 | 211 | ypos 212 | 250 213 | 214 | 825AE364-0819-4F85-9021-B9AEA0C64118 215 | 216 | ypos 217 | 80 218 | 219 | 8490ED7E-339D-49CE-91F5-9ED557A5DA90 220 | 221 | ypos 222 | 10 223 | 224 | 8A13345C-4BF4-4E07-A095-0A57B2B12DE4 225 | 226 | ypos 227 | 120 228 | 229 | B504F4C6-F55E-4E55-B6A2-7DF195963813 230 | 231 | ypos 232 | 30 233 | 234 | 235 | webaddress 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phallstrom/AlfredGist/5a264d156038d97d9139dca57c8308208e983627/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phallstrom/AlfredGist/5a264d156038d97d9139dca57c8308208e983627/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phallstrom/AlfredGist/5a264d156038d97d9139dca57c8308208e983627/screenshots/setup.png -------------------------------------------------------------------------------- /tests/helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PREF_DIR=$PWD 4 | our_dir=$PWD 5 | 6 | source functions.sh 7 | -------------------------------------------------------------------------------- /tests/test_cli.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env roundup 2 | source tests/helper.sh 3 | 4 | describe "command line parsing" 5 | 6 | before() { 7 | unset action 8 | unset description 9 | unset files 10 | unset contents 11 | } 12 | 13 | it_parses_with_a_single_filename() { 14 | parse_cli _files tests/test_cli.sh 15 | test "$action" = "gist" 16 | test "${files[0]}" = "test_cli.sh" 17 | } 18 | 19 | it_parses_help() { 20 | parse_cli help 21 | test "$action" = "help" 22 | } 23 | 24 | it_parses_configure() { 25 | parse_cli configure somekey someval 26 | test "$action" = "configure" 27 | test "$key" = "somekey" 28 | test "$val" = "someval" 29 | } 30 | 31 | it_parses_p_when_public_is_true() { 32 | public="true" 33 | parse_cli p 34 | test "$public" = "false" 35 | } 36 | 37 | it_parses_p_when_public_is_false() { 38 | public="false" 39 | parse_cli p 40 | test "$public" = "true" 41 | } 42 | 43 | it_parses_public() { 44 | public="false" 45 | parse_cli public 46 | test "$public" = "true" 47 | } 48 | 49 | it_parses_private() { 50 | public="true" 51 | parse_cli private 52 | test "$public" = "false" 53 | } 54 | 55 | it_parses_nonanonymous() { 56 | parse_cli 57 | test "$anonymous" = "false" 58 | } 59 | 60 | it_parses_a() { 61 | parse_cli a 62 | test "$anonymous" = "true" 63 | } 64 | 65 | it_parses_anon() { 66 | parse_cli anon 67 | test "$anonymous" = "true" 68 | } 69 | 70 | 71 | it_parses_with_zero_arguments() { 72 | parse_cli 73 | test "$action" = "gist" 74 | test "${files[0]}" = "" 75 | test "$description" = "" 76 | } 77 | 78 | it_parses_with_p_and_file() { 79 | parse_cli private file.rb 80 | test "$action" = "gist" 81 | test "${files[0]}" = "file.rb" 82 | test "$description" = "" 83 | test "$public" = "false" 84 | } 85 | 86 | it_parses_with_p_and_file_and_desc() { 87 | parse_cli private file.rb desc 88 | test "$action" = "gist" 89 | test "${files[0]}" = "file.rb" 90 | test "$description" = "desc" 91 | test "$public" = "false" 92 | } 93 | 94 | it_parses_with_file() { 95 | parse_cli private file.rb 96 | test "$action" = "gist" 97 | test "${files[0]}" = "file.rb" 98 | test "$description" = "" 99 | } 100 | 101 | it_parses_with_file_and_desc() { 102 | parse_cli private file.rb desc 103 | test "$action" = "gist" 104 | test "${files[0]}" = "file.rb" 105 | test "$description" = "desc" 106 | test "$public" = "false" 107 | } 108 | 109 | it_parses_with_ext() { 110 | parse_cli ext 111 | test "$action" = "gist" 112 | test "${files[0]}" = "gist.ext" 113 | test "$description" = "" 114 | } 115 | 116 | it_parses_with_dotext() { 117 | parse_cli .ext 118 | test "$action" = "gist" 119 | test "${files[0]}" = "gist.ext" 120 | test "$description" = "" 121 | } 122 | 123 | it_parses_with_file_as_dash() { 124 | parse_cli - 125 | test "$action" = "gist" 126 | test "${files[0]}" = "" 127 | test "$description" = "" 128 | } 129 | 130 | it_parses_with_dash_and_desc() { 131 | parse_cli - desc 132 | test "$action" = "gist" 133 | test "${files[0]}" = "" 134 | test "$description" = "desc" 135 | } 136 | 137 | it_parses_with_dotext_and_desc() { 138 | parse_cli .ext desc 139 | test "$action" = "gist" 140 | test "${files[0]}" = "gist.ext" 141 | test "$description" = "desc" 142 | } 143 | 144 | it_parses_with_ext_and_desc() { 145 | parse_cli ext desc 146 | test "$action" = "gist" 147 | test "${files[0]}" = "" 148 | test "$description" = "ext desc" 149 | } 150 | -------------------------------------------------------------------------------- /tests/test_configure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env roundup 2 | source tests/helper.sh 3 | 4 | describe "configuring options" 5 | 6 | before() { 7 | server="api.github.com" 8 | token="12345" 9 | public="true" 10 | copy_url="true" 11 | open_url="true" 12 | save_settings 13 | mkdir "/tmp/alfred-gist-shared-config-dir" 14 | } 15 | 16 | after() { 17 | rm -f "$our_dir/config" 18 | rm -rf "/tmp/alfred-gist-shared-config-dir" 19 | } 20 | 21 | ################################################################################ 22 | 23 | it_defaults_when_setting_shared_config_dir_with_no_value() { 24 | set_option "shared_config_dir" "" 25 | test "$shared_config_dir" = "" 26 | } 27 | 28 | it_errors_when_setting_shared_config_dir_to_nonexistent_directory() { 29 | bash gist.sh configure shared_config_dir /tmp/alfred-gist-does-not-exist | grep "ERROR" 30 | } 31 | 32 | 33 | it_sets_shared_config_dir_to_value() { 34 | set_option "shared_config_dir" "/tmp/alfred-gist-shared-config-dir" 35 | test "$shared_config_dir" = "/tmp/alfred-gist-shared-config-dir" 36 | } 37 | 38 | ################################################################################ 39 | 40 | it_defaults_when_setting_server_with_no_value() { 41 | set_option "server" "" 42 | test "$server" = "api.github.com" 43 | } 44 | 45 | it_sets_server_to_value() { 46 | set_option "server" "server999" 47 | test "$server" = "server999" 48 | } 49 | 50 | ################################################################################ 51 | 52 | it_errors_when_setting_token_with_no_value() { 53 | bash gist.sh configure token | grep "ERROR" 54 | } 55 | 56 | it_sets_token_to_value() { 57 | set_option "token" "999" 58 | test "$token" = "999" 59 | } 60 | 61 | ################################################################################ 62 | 63 | it_errors_when_setting_public_to_bad_value() { 64 | bash gist.sh configure public | grep "ERROR" 65 | bash gist.sh configure public foo | grep "ERROR" 66 | } 67 | 68 | it_sets_public_to_true() { 69 | set_option "public" "true" 70 | test "$public" = "true" 71 | } 72 | 73 | it_sets_public_to_false() { 74 | set_option "public" "false" 75 | test "$public" = "false" 76 | } 77 | 78 | ################################################################################ 79 | 80 | it_errors_when_setting_copy_url_to_bad_value() { 81 | bash gist.sh configure copy_url | grep "ERROR" 82 | bash gist.sh configure copy_url foo | grep "ERROR" 83 | } 84 | 85 | it_sets_copy_url_to_true() { 86 | set_option "copy_url" "true" 87 | test "$copy_url" = "true" 88 | } 89 | 90 | it_sets_copy_url_to_false() { 91 | set_option "copy_url" "false" 92 | test "$copy_url" = "false" 93 | } 94 | 95 | ################################################################################ 96 | 97 | it_errors_when_setting_open_url_to_bad_value() { 98 | bash gist.sh configure open_url | grep "ERROR" 99 | bash gist.sh configure open_url foo | grep "ERROR" 100 | } 101 | 102 | it_sets_open_url_to_true() { 103 | set_option "open_url" "true" 104 | test "$open_url" = "true" 105 | } 106 | 107 | it_sets_open_url_to_false() { 108 | set_option "open_url" "false" 109 | test "$open_url" = "false" 110 | } 111 | 112 | ################################################################################ 113 | 114 | it_errors_when_passing_invalid_key() { 115 | bash gist.sh configure invalid bogus | grep "ERROR" 116 | } 117 | 118 | -------------------------------------------------------------------------------- /tests/test_settings.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env roundup 2 | source tests/helper.sh 3 | 4 | describe "load/save options" 5 | 6 | before() { 7 | rm -f "$our_dir/config" 8 | mkdir "/tmp/alfred-gist-shared-config-dir" 9 | } 10 | 11 | after() { 12 | rm -f "$our_dir/config" 13 | rm -rf "/tmp/alfred-gist-shared-config-dir" 14 | } 15 | 16 | it_loads_default_settings() { 17 | load_settings 18 | test "$server" = "api.github.com" 19 | test "$token" = "" 20 | test "$public" = "false" 21 | test "$copy_url" = "true" 22 | test "$open_url" = "true" 23 | test "$shared_config_dir" = "" 24 | } 25 | 26 | it_saves_settings() { 27 | server="server123" 28 | token="token123" 29 | public="public123" 30 | copy_url="copy_url123" 31 | open_url="open_url123" 32 | shared_config_dir="/tmp/alfred-gist-shared-config-dir" 33 | save_settings 34 | unset server token public copy_url open_url shared_config_dir 35 | load_settings 36 | test "$server" = "server123" 37 | test "$token" = "token123" 38 | test "$public" = "public123" 39 | test "$copy_url" = "copy_url123" 40 | test "$open_url" = "open_url123" 41 | test "$shared_config_dir" = "/tmp/alfred-gist-shared-config-dir" 42 | } 43 | --------------------------------------------------------------------------------