├── .gitignore ├── LICENCE ├── README.md ├── README.txt ├── cdwf ├── config.sh ├── createwf ├── findwf ├── info.plist ├── lib └── const.sh └── syncwf /.gitignore: -------------------------------------------------------------------------------- 1 | test/ 2 | *.swp 3 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Zhechen Min 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alfred Workflow CLI Utilities 2 | 3 | Bash script utilities package to help developing Alfred workflows in command lines. 4 | 5 | 6 | ###Install 7 | 1. Download the package to a dedicated scripts folder. 8 | 2. Make sure this folder has been added to `$PATH`. 9 | 3. Put `source /your/path/to/this/package/config.sh` in `.bashrc`, `.zshrc` or other shell config files to enable `cdwf` command. 10 | 11 | ###Command 12 | * createwf -- create a new alfred workflow 13 | * Usage: `createwf workflow-name` 14 | * Description: 15 | * A folder and an `info.plist` file will be generated for this new workflow in Alfred's directory system. This process is the same as `Alfred -> Workflows -> + -> Blank Workflow`. 16 | * Workflow's attributes, which are name / bundleid / author / readme / website, are based on `workflow-name` and default setting in `Alfred -> Workflows -> + -> Workflow Defaults...`. 17 | 18 | * cdwf -- cd to the workflow folder 19 | * Usage: `cdwf [-c|-d] [workflow-name|bundle-id]` 20 | * Description: 21 | * Changing folder to workflow directory based on `workflow-name` or `bundle-id`. If there is an `info.plist` file in current folder, this command will also bring you to the corresponding workflow directory. When workflow cannot be found, you will be brought to `~/Library/Application Support/Alfred 2/Alfred.alfredpreferences/workflows`. 22 | * **-c** Instead of workflow directory, changing directory to workflow cache folder under `~/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data` 23 | * **-d** Instead of workflow directory, changing directory to workflow data folder under `~/Library/Application Support/Alfred 2/Workflow Data`. 24 | 25 | * syncwf -- two way synchronization between current directory and workflow directory 26 | * Usage: `syncwf -gp [-f] [-o rsync-options [-a]] [workflow-name|bundle-id]` 27 | * Description: 28 | * Update content between current and workflow directory with `rsync` 29 | * **-g** _(Get)_ Copy content from workflow directory to the current one. 30 | * **-p** _(Put)_ Copy content from current directory to the workflow one. 31 | * **-f** _(Force Mode)_ Synchronize without confirmation. 32 | * **-o** _(Options)_ Use custom options for `rsync`. Defalut `rsync` options are `-av --update --delete --exclude=.* --exclude-from=.gitignore`. 33 | * **-a** _(Options)_ Append custom options to the default one instead of replacement. 34 | * **-n** _(Dry run)_ Show what would have been transferred by `rsync`. 35 | * **[workflow-name|bundle-id]** Use `workflow-name`, `bundle-id` or `info.plist` file (if exists in current folder) to determine the path of workflow directory. Another way is to read path from pipeline directly, e.g. `echo $path_of_workflow_directory | syncwf`. 36 | 37 | * findwf -- print the path to workflow based on `workflow-name`, `bundle-id` or `info.plist` (if exists in current folder) 38 | * Usage: `findwf [workflow-name or bundle-id]` 39 | 40 | ###Copyright and Licensing 41 | 42 | * All code and documents are licensed under [MIT](http://opensource.org/licenses/MIT) 43 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | # Alfred Workflow CLI Utilities 2 | 3 | Bash script utilities package to help developing Alfred workflows in command lines. 4 | 5 | 6 | ###Install 7 | 1. Download the package to a dedicated scripts folder. 8 | 2. Make sure this folder has been added to $PATH. 9 | 3. Put source /your/path/to/this/package/config.sh in .bashrc, .zshrc or other shell config files to enable cdwf command. 10 | 11 | ###Command 12 | * createwf -- create a new alfred workflow 13 | * Usage: createwf workflow-name 14 | * Description: 15 | * A folder and an info.plist file will be generated for this new workflow in Alfred's directory system. This process is the same as "Alfred -> Workflows -> + -> Blank Workflow". 16 | * Workflow's attributes, which are name / bundleid / author / readme / website, are based on workflow-name and default setting in "Alfred -> Workflows -> + -> Workflow Defaults...". 17 | 18 | * cdwf -- cd to the workflow folder 19 | * Usage: cdwf [-c|-d] [workflow-name|bundle-id] 20 | * Description: 21 | Changing folder to workflow directory based on workflow-name or bundle-id. If there is an info.plist file in current folder, this command will also bring you to the corresponding workflow directory. When workflow cannot be found, you will be brought to "~/Library/Application Support/Alfred 2/Alfred.alfredpreferences/workflows". 22 | -c Instead of workflow directory, changing directory to workflow cache folder under ~/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data 23 | -d Instead of workflow directory, changing directory to workflow data folder under ~/Library/Application Support/Alfred 2/Workflow Data. 24 | 25 | * syncwf -- two way synchronization between current directory and workflow directory 26 | * Usage: syncwf -gp [-f] [-o rsync-options [-a]] [workflow-name|bundle-id] 27 | * Description: 28 | Update content between current and workflow directory with rsync 29 | -g (Get) -- Copy content from workflow directory to the current one. 30 | -p (Put) -- Copy content from current directory to the workflow one. 31 | -f (Force Mode) -- Synchronize without confirmation. 32 | -o (Options) -- Use custom options for rsync. Defalut rsync options are "-av --update --delete --exclude=.* --exclude-from=.gitignore". 33 | -a (Options) -- Append custom options to the default one instead of replacement. 34 | -n (Dry run) -- Show what would have been transferred by rsync. 35 | [workflow-name|bundle-id]** Use workflow-name, bundle-id or info.plist file (if exists in current folder) to determine the path of workflow directory. Another way is to read path from pipeline directly, e.g. echo $path_of_workflow_directory | syncwf. 36 | 37 | * findwf -- print the path to workflow based on workflow-name, bundle-id or info.plist (if exists in current folder) 38 | * Usage: findwf [workflow-name or bundle-id] 39 | 40 | ###Copyright and Licensing 41 | 42 | * All code and documents are licensed under MIT.(http://opensource.org/licenses/MIT) 43 | -------------------------------------------------------------------------------- /cdwf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEFAULT_WORKFLOW_PATH="/Users/$USER/Library/Application Support/Alfred 2/Alfred.alfredpreferences/workflows" 4 | if ! alfred_path="`defaults read com.runningwithcrayons.Alfred-Preferences syncfolder 2>/dev/null`" ; then 5 | WORKFLOW_PATH="$DEFAULT_WORKFLOW_PATH" 6 | else 7 | WORKFLOW_PATH="`eval echo ${alfred_path}`/Alfred.alfredpreferences/workflows" 8 | fi 9 | 10 | CACHE_PATH="/Users/$USER/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data" 11 | DATA_PATH="/Users/$USER/Library/Application Support/Alfred 2/Workflow Data" 12 | INFO_PLIST="info.plist" 13 | PLIST="/usr/libexec/PlistBuddy" 14 | CMD="`basename $0`" 15 | 16 | OPTIND=1 17 | usage=false 18 | usage() { 19 | echo "usage: $CMD [-c|-d] [name/bundleid] " 20 | usage=true 21 | } 22 | 23 | is_data_dir=false 24 | is_cache_dir=false 25 | 26 | while getopts "hdc" opt 27 | do 28 | case $opt in 29 | h) 30 | usage 31 | ;; 32 | c) 33 | is_cache_dir=true 34 | ;; 35 | d) 36 | is_data_dir=true 37 | ;; 38 | \?) 39 | usage 40 | ;; 41 | esac 42 | done 43 | shift $((OPTIND-1)) 44 | 45 | if ($is_cache_dir) && ($is_data_dir); then 46 | usage 47 | fi 48 | 49 | if $usage; then 50 | return -1 51 | fi 52 | 53 | if ! target_dir="`findwf \"$1\"`"; then 54 | target_dir="$WORKFLOW_PATH" 55 | fi 56 | 57 | parent_dir="" 58 | 59 | if $is_data_dir; then 60 | parent_dir="$DATA_PATH" 61 | elif $is_cache_dir; then 62 | parent_dir="$CACHE_PATH" 63 | fi 64 | 65 | 66 | if [ -n "$parent_dir" ]; then 67 | wf_dir="$target_dir" 68 | target_dir="$parent_dir" 69 | if [ -f "$wf_dir/$INFO_PLIST" ]; then 70 | bundle_id="`$PLIST -c \"Print bundleid\" \"$wf_dir/$INFO_PLIST\" 2>/dev/null`" 71 | if [ -n "$bundle_id" ]; then 72 | dir="$parent_dir/$bundle_id" 73 | if [ -d "$dir" ]; then 74 | target_dir="$dir" 75 | else 76 | search_result="`find \"$parent_dir\" -type d -name \"*$bundle_id*\" | head -1`" 77 | if [ -n "$search_result" ]; then 78 | target_dir="$search_result" 79 | fi 80 | fi 81 | fi 82 | fi 83 | 84 | fi 85 | 86 | cd "$target_dir" 87 | -------------------------------------------------------------------------------- /config.sh: -------------------------------------------------------------------------------- 1 | alias cdwf='. cdwf' 2 | -------------------------------------------------------------------------------- /createwf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | current_dir="`dirname $0`" 4 | source $current_dir/lib/const.sh 5 | 6 | get_default_value() { 7 | default_value="`$PLIST -c \"Print $1\" \"$DEFAULT_SETTING\" 2>/dev/null`" 8 | } 9 | 10 | create_plist() { 11 | #read default settings from prefs.plist 12 | get_default_value 'defaultBundleId' 13 | bundle_id_prefix="$default_value" 14 | 15 | get_default_value 'defaultCreatedBy' 16 | author="$default_value" 17 | 18 | get_default_value 'defaultReadme' 19 | readme="$default_value" 20 | 21 | get_default_value 'defaultWebsite' 22 | website="$default_value" 23 | 24 | bundle_id="$bundle_id_prefix`echo $1 | tr '[:upper:]' '[:lower:]'`" 25 | name="$1" 26 | 27 | 28 | #create new info.plist 29 | values=("$bundle_id" "$author" "$name" "$readme" "$website") 30 | keys=("bundleid" "createdby" "name" "readme" "webaddress") 31 | 32 | dir="$WORKFLOW_PATH/$WORKFLOW_DIR_PREFIX$name"".`date +'%Y_%m_%d'`" 33 | if [ ! -d "$dir" ]; then 34 | mkdir "$dir" 35 | fi 36 | 37 | cp "$current_dir/$INFO_PLIST" "$dir/$INFO_PLIST" 38 | 39 | for i in "${!values[@]}"; do 40 | $PLIST -c "Set ${keys[$i]} ${values[$i]}" "$dir/$INFO_PLIST" 41 | done 42 | } 43 | 44 | if [ -n "$1" ]; then 45 | if findwf "$1" > /dev/null ; then 46 | echo "$CMD: workflow is already existed" 47 | exit -1 48 | fi 49 | create_plist "$1" 50 | else 51 | echo "$CMD: please provides workflow name" 52 | exit -1 53 | fi 54 | -------------------------------------------------------------------------------- /findwf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | current_dir="`dirname $0`" 4 | source $current_dir/lib/const.sh 5 | 6 | get_plist_value() { 7 | value="`$PLIST -c \"Print $1\" \"$2\" 2>/dev/null`" 8 | } 9 | 10 | if [ -n "$1" ]; 11 | then 12 | current_bundle_id="$1" 13 | current_name="$1" 14 | else 15 | if [ ! -f "$INFO_PLIST" ]; 16 | then 17 | echo "$CMD Please provides workflow name/bundleid or info.plist file" 18 | exit -1 19 | fi 20 | get_plist_value "bundleid" "$INFO_PLIST" 21 | current_bundle_id="$value" 22 | get_plist_value "name" "$INFO_PLIST" 23 | current_name="$value" 24 | fi 25 | 26 | cd "$WORKFLOW_PATH" 27 | 28 | wf_list=() 29 | 30 | for wf in */ ; 31 | do 32 | wf_list+=("$WORKFLOW_PATH/$wf") 33 | done 34 | 35 | cd - > /dev/null 36 | 37 | for ((i = 0; i < ${#wf_list[@]}; i++)) 38 | do 39 | plist="${wf_list[$i]}/$INFO_PLIST" 40 | get_plist_value "bundleid" "$plist" 41 | bundle_id="$value" 42 | get_plist_value "name" "$plist" 43 | name="$value" 44 | if [ "$current_bundle_id" == "$bundle_id" -o "$current_name" == "$name" ]; 45 | then 46 | echo "${wf_list[$i]}" 47 | exit 0 48 | fi 49 | done 50 | 51 | echo "$CMD: Can't find workflow associated with current directory" 52 | exit -1 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | 7 | connections 8 | 9 | createdby 10 | 11 | description 12 | 13 | disabled 14 | 15 | name 16 | 17 | objects 18 | 19 | readme 20 | 21 | uidata 22 | 23 | webaddress 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/const.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEFAULT_WORKFLOW_PATH="/Users/$USER/Library/Application Support/Alfred 2/Alfred.alfredpreferences/workflows" 4 | DEFAULT_SETTING_PATH="/Users/$USER/Library/Application Support/Alfred 2/Alfred.alfredpreferences/preferences/workflows/prefs.plist" 5 | 6 | WORKFLOW_DIR_PREFIX="user.workflow." 7 | INFO_PLIST="info.plist" 8 | 9 | PLIST="/usr/libexec/PlistBuddy" 10 | CMD="`basename $0`" 11 | 12 | if ! alfred_path="`defaults read com.runningwithcrayons.Alfred-Preferences syncfolder 2>/dev/null`" ; then 13 | WORKFLOW_PATH="$DEFAULT_WORKFLOW_PATH" 14 | DEFAULT_SETTING="$DEFAULT_SETTING_PATH" 15 | else 16 | WORKFLOW_PATH="`eval echo ${alfred_path}`/Alfred.alfredpreferences/workflows" 17 | DEFAULT_SETTING="`eval echo ${alfred_path}`/Alfred.alfredpreferences/preferences/workflows/prefs.plist" 18 | fi 19 | -------------------------------------------------------------------------------- /syncwf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | current_dir="`dirname $0`" 4 | source $current_dir/lib/const.sh 5 | 6 | OPTIND=1 7 | usage() { 8 | echo "usage: $CMD -gp [-f] [-n] [-o rsync-options [-a]] [name/bundleid] " 9 | exit 0 10 | } 11 | 12 | get=false 13 | put=false 14 | confirm=true 15 | options="-av --update --delete --exclude=.*" 16 | dryrun=false 17 | gitignore=".gitignore" 18 | append=false 19 | option_enable=false 20 | customer_options="" 21 | if [[ -f "$gitignore" ]]; then 22 | options+=" --exclude-from=$gitignore" 23 | fi 24 | 25 | while getopts "hngpo:a" opt 26 | do 27 | case $opt in 28 | h) 29 | usage 30 | ;; 31 | a) 32 | append=true 33 | ;; 34 | g) 35 | get=true 36 | ;; 37 | p) 38 | put=true 39 | ;; 40 | o) 41 | customer_options="$OPTARG" 42 | option_enable=true 43 | ;; 44 | n) 45 | dryrun=true 46 | ;; 47 | \?) 48 | usage 49 | ;; 50 | esac 51 | done 52 | shift $((OPTIND-1)) 53 | 54 | if $option_enable; then 55 | if $append; then 56 | options="$options $customer_options" 57 | else 58 | options="$customer_options" 59 | fi 60 | fi 61 | 62 | 63 | if ! $get && ! $put ; then 64 | echo "$CMD: Neither -g nor -p be selected, exiting..." 65 | exit -1 66 | fi 67 | 68 | search_word="$1" 69 | if target_dir="`findwf \"$search_word\"`"; then 70 | : 71 | elif [ -n "$search_word" ]; then 72 | echo "$CMD can't find workflow" 73 | exit -1 74 | else 75 | read line 76 | target_dir="$line" 77 | if [ ! -d "$target_dir" ]; 78 | then 79 | echo "$CMD can't find workflow" 80 | exit -1 81 | fi 82 | fi 83 | 84 | if $dryrun; then 85 | options+=" -n" 86 | fi 87 | 88 | if $confirm; then 89 | if $get && $put; then 90 | msg= "Sync content between: `pwd` and $target_dir" 91 | elif $get; then 92 | msg="Copy content from $target_dir to `pwd`" 93 | elif $put; then 94 | msg="Copy content from `pwd` to $target_dir" 95 | fi 96 | read -p "$CMD: $msg with option \"$options\", continue? [y/n]" -n 1 -r reply 97 | echo 98 | if [[ ! $reply =~ [yY] ]]; then 99 | exit -1 100 | fi 101 | fi 102 | 103 | sync_folder() { 104 | rsync $options "$1" "$2" 105 | } 106 | 107 | 108 | if $put; then 109 | sync_folder "./" "$target_dir" 110 | fi 111 | 112 | if $get; then 113 | sync_folder "$target_dir" "./" 114 | fi 115 | 116 | --------------------------------------------------------------------------------