Commit 02f4901c547d302bea9cd489300f4d79d520ec35

Authored by Shrikant Sharat
1 parent fe44337cbb

Tests for all valid bundle command syntaxes.

And a couple of fixes for bugs discovered along the way. These are tests *only*
for the valid syntaxes. Its currently undefined behavior for invalid syntaxes.
Tests for proper error reporting should also be added soon.

Showing 2 changed files with 8 additions and 3 deletions Inline Diff

1 #!/bin/zsh 1 #!/bin/zsh
2 2
3 # Each line in this string has the following entries separated by a space 3 # Each line in this string has the following entries separated by a space
4 # character. 4 # character.
5 # <bundle-name>, <repo-url>, <plugin-location>, <repo-local-clone-dir> 5 # <bundle-name>, <repo-url>, <plugin-location>, <repo-local-clone-dir>
6 # FIXME: Is not kept local by zsh! 6 # FIXME: Is not kept local by zsh!
7 local _ANTIGEN_BUNDLE_RECORD="" 7 local _ANTIGEN_BUNDLE_RECORD=""
8 8
9 # Syntaxes 9 # Syntaxes
10 # bundle <url> [<loc>=/] [<name>] 10 # bundle <url> [<loc>=/] [<name>]
11 bundle () { 11 bundle () {
12 12
13 # Bundle spec arguments' default values. 13 # Bundle spec arguments' default values.
14 local url="$ANTIGEN_DEFAULT_REPO_URL" 14 local url="$ANTIGEN_DEFAULT_REPO_URL"
15 local loc=/ 15 local loc=/
16 local name= 16 local name=
17 local load=true 17 local load=true
18 18
19 # Set spec values based on the positional arguments. 19 # Set spec values based on the positional arguments.
20 local position_args='url loc name' 20 local position_args='url loc name'
21 local i=1 21 local i=1
22 while ! [[ -z $1 || $1 == --*=* ]]; do 22 while ! [[ -z $1 || $1 == --*=* ]]; do
23 local arg_name="$(echo "$position_args" | cut -d\ -f$i)" 23 local arg_name="$(echo "$position_args" | cut -d\ -f$i)"
24 local arg_value="$1" 24 local arg_value="$1"
25 eval "local $arg_name='$arg_value'" 25 eval "local $arg_name='$arg_value'"
26 shift 26 shift
27 i=$(($i + 1)) 27 i=$(($i + 1))
28 done 28 done
29 29
30 # Check if url is just the plugin name. Super short syntax. 30 # Check if url is just the plugin name. Super short syntax.
31 if [[ "$url" != */* ]]; then 31 if [[ "$url" != */* ]]; then
32 loc="plugins/$url" 32 loc="plugins/$url"
33 url="$ANTIGEN_DEFAULT_REPO_URL" 33 url="$ANTIGEN_DEFAULT_REPO_URL"
34 fi 34 fi
35 35
36 # Set spec values from keyword arguments, if any. The remaining arguments 36 # Set spec values from keyword arguments, if any. The remaining arguments
37 # are all assumed to be keyword arguments. 37 # are all assumed to be keyword arguments.
38 while [[ $1 == --*=* ]]; do 38 while [[ $1 == --*=* ]]; do
39 local arg_name="$(echo "$1" | cut -d= -f1 | sed 's/^--//')" 39 local arg_name="$(echo "$1" | cut -d= -f1 | sed 's/^--//')"
40 local arg_value="$(echo "$1" | cut -d= -f2)" 40 local arg_value="$(echo "$1" | cut -d= -f2)"
41 eval "local $arg_name='$arg_value'" 41 eval "local $arg_name='$arg_value'"
42 shift 42 shift
43 done 43 done
44 44
45 # Resolve the url. 45 # Resolve the url.
46 if [[ $url != git://* && $url != https://* ]]; then 46 if [[ $url != git://* && $url != https://* ]]; then
47 url="${url%.git}" 47 url="${url%.git}"
48 name="$(basename "$url")" 48 test -z "$name" && name="$(basename "$url")"
49 url="https://github.com/$url.git" 49 url="https://github.com/$url.git"
50 fi 50 fi
51 51
52 # Plugin's repo will be cloned here. 52 # Plugin's repo will be cloned here.
53 local clone_dir="$ADOTDIR/repos/$(echo "$url" \ 53 local clone_dir="$ADOTDIR/repos/$(echo "$url" \
54 | sed -e 's/\.git$//' -e 's./.-SLASH-.g' -e 's.:.-COLON-.g')" 54 | sed -e 's/\.git$//' -e 's./.-SLASH-.g' -e 's.:.-COLON-.g')"
55 55
56 # Make an intelligent guess about the name of the plugin, if not already 56 # Make an intelligent guess about the name of the plugin, if not already
57 # done or is explicitly specified. 57 # done or is explicitly specified.
58 if [[ -z $name ]]; then 58 if [[ -z $name ]]; then
59 name="$(basename $url/$loc)" 59 name="$(basename $(echo $url | sed 's/\.git$//')/$loc)"
60 fi 60 fi
61 61
62 # Add it to the record. 62 # Add it to the record.
63 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$name $url $loc $clone_dir" 63 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$name $url $loc $clone_dir"
64 64
65 # Load it, unless specified otherwise. 65 # Load it, unless specified otherwise.
66 if $load; then 66 if $load; then
67 bundle-load "$name" 67 bundle-load "$name"
68 fi 68 fi
69 } 69 }
70 70
71 bundle-install () { 71 bundle-install () {
72 72
73 local update=false 73 local update=false
74 if [[ $1 == --update ]]; then 74 if [[ $1 == --update ]]; then
75 update=true 75 update=true
76 shift 76 shift
77 fi 77 fi
78 78
79 mkdir -p "$ADOTDIR/bundles" 79 mkdir -p "$ADOTDIR/bundles"
80 80
81 local handled_repos="" 81 local handled_repos=""
82 local install_bundles="" 82 local install_bundles=""
83 83
84 if [[ $# != 0 ]]; then 84 if [[ $# != 0 ]]; then
85 # Record and install just the given plugin here and now. 85 # Record and install just the given plugin here and now.
86 bundle "$@" 86 bundle "$@"
87 install_bundles="$(-bundle-echo-record | tail -1)" 87 install_bundles="$(-bundle-echo-record | tail -1)"
88 else 88 else
89 # Install all the plugins, previously recorded. 89 # Install all the plugins, previously recorded.
90 install_bundles="$(-bundle-echo-record)" 90 install_bundles="$(-bundle-echo-record)"
91 fi 91 fi
92 92
93 # If the above `if` is directly piped to the below `while`, the contents 93 # If the above `if` is directly piped to the below `while`, the contents
94 # inside the `if` construct are run in a new subshell, so changes to the 94 # inside the `if` construct are run in a new subshell, so changes to the
95 # `$_ANTIGEN_BUNDLE_RECORD` variable are lost after the `if` construct 95 # `$_ANTIGEN_BUNDLE_RECORD` variable are lost after the `if` construct
96 # finishes. So, we need the temporary `$install_bundles` variable. 96 # finishes. So, we need the temporary `$install_bundles` variable.
97 echo "$install_bundles" | while read spec; do 97 echo "$install_bundles" | while read spec; do
98 98
99 local name="$(echo "$spec" | awk '{print $1}')" 99 local name="$(echo "$spec" | awk '{print $1}')"
100 local url="$(echo "$spec" | awk '{print $2}')" 100 local url="$(echo "$spec" | awk '{print $2}')"
101 local loc="$(echo "$spec" | awk '{print $3}')" 101 local loc="$(echo "$spec" | awk '{print $3}')"
102 local clone_dir="$(echo "$spec" | awk '{print $4}')" 102 local clone_dir="$(echo "$spec" | awk '{print $4}')"
103 103
104 if [[ -z "$(echo "$handled_repos" | grep -Fm1 "$url")" ]]; then 104 if [[ -z "$(echo "$handled_repos" | grep -Fm1 "$url")" ]]; then
105 if [[ ! -d $clone_dir ]]; then 105 if [[ ! -d $clone_dir ]]; then
106 git clone "$url" "$clone_dir" 106 git clone "$url" "$clone_dir"
107 elif $update; then 107 elif $update; then
108 git --git-dir "$clone_dir/.git" pull 108 git --git-dir "$clone_dir/.git" pull
109 fi 109 fi
110 110
111 handled_repos="$handled_repos\n$url" 111 handled_repos="$handled_repos\n$url"
112 fi 112 fi
113 113
114 if [[ $name != *.theme ]]; then 114 if [[ $name != *.theme ]]; then
115 echo Installing $name 115 echo Installing $name
116 local bundle_dest="$ADOTDIR/bundles/$name" 116 local bundle_dest="$ADOTDIR/bundles/$name"
117 test -e "$bundle_dest" && rm -rf "$bundle_dest" 117 test -e "$bundle_dest" && rm -rf "$bundle_dest"
118 ln -s "$clone_dir/$loc" "$bundle_dest" 118 ln -s "$clone_dir/$loc" "$bundle_dest"
119 else 119 else
120 mkdir -p "$ADOTDIR/bundles/$name" 120 mkdir -p "$ADOTDIR/bundles/$name"
121 cp "$clone_dir/$loc" "$ADOTDIR/bundles/$name" 121 cp "$clone_dir/$loc" "$ADOTDIR/bundles/$name"
122 fi 122 fi
123 123
124 bundle-load "$name" 124 bundle-load "$name"
125 125
126 done 126 done
127 127
128 # Initialize completions after installing 128 # Initialize completions after installing
129 bundle-apply 129 bundle-apply
130 130
131 } 131 }
132 132
133 bundle-install! () { 133 bundle-install! () {
134 bundle-install --update 134 bundle-install --update
135 } 135 }
136 136
137 bundle-cleanup () { 137 bundle-cleanup () {
138 138
139 if [[ ! -d "$ADOTDIR/bundles" || \ 139 if [[ ! -d "$ADOTDIR/bundles" || \
140 "$(ls "$ADOTDIR/bundles/" | wc -l)" == 0 ]]; then 140 "$(ls "$ADOTDIR/bundles/" | wc -l)" == 0 ]]; then
141 echo "You don't have any bundles." 141 echo "You don't have any bundles."
142 return 0 142 return 0
143 fi 143 fi
144 144
145 # Find directores in ADOTDIR/bundles, that are not in the bundles record. 145 # Find directores in ADOTDIR/bundles, that are not in the bundles record.
146 local unidentified_bundles="$(comm -13 \ 146 local unidentified_bundles="$(comm -13 \
147 <(-bundle-echo-record | awk '{print $1}' | sort) \ 147 <(-bundle-echo-record | awk '{print $1}' | sort) \
148 <(ls -1 "$ADOTDIR/bundles"))" 148 <(ls -1 "$ADOTDIR/bundles"))"
149 149
150 if [[ -z $unidentified_bundles ]]; then 150 if [[ -z $unidentified_bundles ]]; then
151 echo "You don't have any unidentified bundles." 151 echo "You don't have any unidentified bundles."
152 return 0 152 return 0
153 fi 153 fi
154 154
155 echo The following bundles are not recorded: 155 echo The following bundles are not recorded:
156 echo "$unidentified_bundles" | sed 's/^/ /' 156 echo "$unidentified_bundles" | sed 's/^/ /'
157 157
158 echo -n '\nDelete them all? [y/N] ' 158 echo -n '\nDelete them all? [y/N] '
159 if read -q; then 159 if read -q; then
160 echo 160 echo
161 echo 161 echo
162 echo "$unidentified_bundles" | while read name; do 162 echo "$unidentified_bundles" | while read name; do
163 echo -n Deleting $name... 163 echo -n Deleting $name...
164 rm -rf "$ADOTDIR/bundles/$name" 164 rm -rf "$ADOTDIR/bundles/$name"
165 echo ' done.' 165 echo ' done.'
166 done 166 done
167 else 167 else
168 echo 168 echo
169 echo Nothing deleted. 169 echo Nothing deleted.
170 fi 170 fi
171 } 171 }
172 172
173 bundle-load () { 173 bundle-load () {
174 174
175 local name="$1" 175 local name="$1"
176 local bundle_dir="$ADOTDIR/bundles/$name" 176 local bundle_dir="$ADOTDIR/bundles/$name"
177 177
178 # Source the plugin script 178 # Source the plugin script
179 local script_loc="$bundle_dir/$name.plugin.zsh" 179 local script_loc="$bundle_dir/$name.plugin.zsh"
180 if [[ -f $script_loc ]]; then 180 if [[ -f $script_loc ]]; then
181 source "$script_loc" 181 source "$script_loc"
182 fi 182 fi
183 183
184 # If the name of the plugin ends with `.lib`, all the *.zsh files in it are 184 # If the name of the plugin ends with `.lib`, all the *.zsh files in it are
185 # sourced. This is kind of a hack to source the libraries of oh-my-zsh. 185 # sourced. This is kind of a hack to source the libraries of oh-my-zsh.
186 if [[ $name == *.lib ]]; then 186 if [[ $name == *.lib ]]; then
187 # FIXME: This throws an error if no files match the given glob pattern. 187 # FIXME: This throws an error if no files match the given glob pattern.
188 for lib ($bundle_dir/*.zsh) source $lib 188 for lib ($bundle_dir/*.zsh) source $lib
189 fi 189 fi
190 190
191 # If the name ends with `.theme`, it is handled as if it were a zsh-theme 191 # If the name ends with `.theme`, it is handled as if it were a zsh-theme
192 # plugin. 192 # plugin.
193 if [[ $name == *.theme ]]; then 193 if [[ $name == *.theme ]]; then
194 local theme_file="$bundle_dir/${name%.theme}.zsh-theme" 194 local theme_file="$bundle_dir/${name%.theme}.zsh-theme"
195 test -f "$theme_file" && source "$theme_file" 195 test -f "$theme_file" && source "$theme_file"
196 fi 196 fi
197 197
198 # Add to $fpath, for completion(s) 198 # Add to $fpath, for completion(s)
199 fpath=($bundle_dir $fpath) 199 fpath=($bundle_dir $fpath)
200 200
201 } 201 }
202 202
203 bundle-lib () { 203 bundle-lib () {
204 bundle --name=oh-my-zsh.lib --loc=lib 204 bundle --name=oh-my-zsh.lib --loc=lib
205 } 205 }
206 206
207 bundle-theme () { 207 bundle-theme () {
208 local url="$ANTIGEN_DEFAULT_REPO_URL" 208 local url="$ANTIGEN_DEFAULT_REPO_URL"
209 local name="${1:-robbyrussell}" 209 local name="${1:-robbyrussell}"
210 bundle-install "$url" --name=$name.theme --loc=themes/$name.zsh-theme 210 bundle-install "$url" --name=$name.theme --loc=themes/$name.zsh-theme
211 } 211 }
212 212
213 bundle-apply () { 213 bundle-apply () {
214 # Initialize completion. 214 # Initialize completion.
215 compinit -i 215 compinit -i
216 } 216 }
217 217
218 bundle-list () { 218 bundle-list () {
219 # List all currently installed bundles 219 # List all currently installed bundles
220 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then 220 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
221 echo "You don't have any bundles." >&2 221 echo "You don't have any bundles." >&2
222 return 1 222 return 1
223 else 223 else
224 -bundle-echo-record | awk '{print $1 " " $2 " " $3}' 224 -bundle-echo-record | awk '{print $1 " " $2 " " $3}'
225 fi 225 fi
226 } 226 }
227 227
228 # Echo the bundle specs as in the record. The first line is not echoed since it 228 # Echo the bundle specs as in the record. The first line is not echoed since it
229 # is a blank line. 229 # is a blank line.
230 -bundle-echo-record () { 230 -bundle-echo-record () {
231 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p' 231 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
232 } 232 }
233 233
234 -bundle-env-setup () { 234 -bundle-env-setup () {
235 # Pre-startup initializations 235 # Pre-startup initializations
236 -set-default ANTIGEN_DEFAULT_REPO_URL \ 236 -set-default ANTIGEN_DEFAULT_REPO_URL \
237 https://github.com/robbyrussell/oh-my-zsh.git 237 https://github.com/robbyrussell/oh-my-zsh.git
238 -set-default ADOTDIR $HOME/.antigen 238 -set-default ADOTDIR $HOME/.antigen
239 239
240 # Load the compinit module 240 # Load the compinit module
241 autoload -U compinit 241 autoload -U compinit
242 242
243 # Without the following, `compdef` function is not defined. 243 # Without the following, `compdef` function is not defined.
244 compinit -i 244 compinit -i
245 } 245 }
246 246
247 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is 247 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is
248 # not already set. 248 # not already set.
249 -set-default () { 249 -set-default () {
250 local arg_name="$1" 250 local arg_name="$1"
251 local arg_value="$2" 251 local arg_value="$2"
252 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'" 252 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
253 } 253 }
254 254
255 -bundle-env-setup 255 -bundle-env-setup
256 256
tests/bundle-syntaxes.t
1 Helper aliases. 1 Helper aliases.
2 2
3 $ alias b=bundle 3 $ alias b=bundle
4 $ alias lb='bundle-list | tail -1' # lb = last bundle 4 $ alias lb='bundle-list | tail -1' # lb = last bundle
5 5
6 Short and sweet. 6 Short and sweet.
7 7
8 $ b plugin-name 8 $ b plugin-name
9 $ lb 9 $ lb
10 plugin-name https://github.com/robbyrussell/oh-my-zsh.git plugins/plugin-name 10 plugin-name https://github.com/robbyrussell/oh-my-zsh.git plugins/plugin-name
11 11
12 Short repo url. 12 Short repo url.
13 13
14 $ b github-username/repo-name 14 $ b github-username/repo-name
15 $ lb 15 $ lb
16 repo-name https://github.com/github-username/repo-name.git / 16 repo-name https://github.com/github-username/repo-name.git /
17 17
18 Short repo url with `.git` suffix. 18 Short repo url with `.git` suffix.
19 19
20 $ b github-username/repo-name.git 20 $ b github-username/repo-name.git
21 $ lb 21 $ lb
22 repo-name https://github.com/github-username/repo-name.git / 22 repo-name https://github.com/github-username/repo-name.git /
23 23
24 Long repo url. 24 Long repo url.
25 25
26 $ b https://github.com/user/repo.git 26 $ b https://github.com/user/repo.git
27 $ lb 27 $ lb
28 repo https://github.com/user/repo.git / 28 repo https://github.com/user/repo.git /
29 29
30 Long repo url with missing `.git` suffix (should'nt add the suffix). 30 Long repo url with missing `.git` suffix (should'nt add the suffix).
31 31
32 $ b https://github.com/user/repo 32 $ b https://github.com/user/repo
33 $ lb 33 $ lb
34 repo https://github.com/user/repo / 34 repo https://github.com/user/repo /
35 35
36 Short repo with location. 36 Short repo with location.
37 37
38 $ b user/plugin path/to/plugin 38 $ b user/plugin path/to/plugin
39 $ lb 39 $ lb
40 plugin https://github.com/user/plugin.git path/to/plugin 40 plugin https://github.com/user/plugin.git path/to/plugin
41 41
42 Short repo with location and name. 42 Short repo with location and name.
43 43
44 $ b user/repo plugin/path plugin-name 44 $ b user/repo plugin/path plugin-name
45 $ lb 45 $ lb
46 plugin-name https://github.com/user/repo.git plugin/path 46 plugin-name https://github.com/user/repo.git plugin/path
47 47
48 Long repo with location and name. 48 Long repo with location and name.
49 49
50 $ b https://github.com/user/repo plugin/path plugin-name 50 $ b https://github.com/user/repo.git plugin/path plugin-name
51 $ lb 51 $ lb
52 plugin-name https://github.com/user/repo.git plugin/path 52 plugin-name https://github.com/user/repo.git plugin/path
53 53
54 Keyword arguments, in respective places. 54 Keyword arguments, in respective places.
55 55
56 $ b --url=user/repo --loc=path/of/plugin --name=plugin-name 56 $ b --url=user/repo --loc=path/of/plugin --name=plugin-name
57 $ lb 57 $ lb
58 plugin-name https://github.com/user/repo.git path/of/plugin 58 plugin-name https://github.com/user/repo.git path/of/plugin
59 59
60 Keyword arguments, in respective places, with full repo url. 60 Keyword arguments, in respective places, with full repo url.
61 61
62 $ b --url=https://github.com/user/repo.git --loc=plugin/path --name=name 62 $ b --url=https://github.com/user/repo.git --loc=plugin/path --name=name
63 $ lb 63 $ lb
64 name https://github.com/user/repo.git plugin/path 64 name https://github.com/user/repo.git plugin/path
65 65
66 Keyword arguments, in reversed order. 66 Keyword arguments, in reversed order.
67 67
68 $ b --name=plugin-name --loc=path/of/plugin --url=user/repo 68 $ b --name=plugin-name --loc=path/of/plugin --url=user/repo
69 $ lb 69 $ lb
70 plugin-name https://github.com/user/repo.git path/of/plugin 70 plugin-name https://github.com/user/repo.git path/of/plugin
71 71
72 Mixed positional and keyword arguments, and skip `loc`. 72 Mixed positional and keyword arguments, and skip `loc`.
73 73
74 $ b user/repo --name=plugin 74 $ b user/repo --name=plugin
75 $ lb
75 plugin https://github.com/user/repo.git / 76 plugin https://github.com/user/repo.git /
76 77
77 Just `loc`, using keyword arguments. 78 Just `loc`, using keyword arguments.
78 79
79 $ b --loc=plugin/path 80 $ b --loc=plugin/path
81 $ lb
80 path https://github.com/robbyrussell/oh-my-zsh.git plugin/path 82 path https://github.com/robbyrussell/oh-my-zsh.git plugin/path
81 83
82 Just `name`, using keyword arguments. 84 Just `name`, using keyword arguments.
83 85
84 $ b --name=robby-oh-my-zsh 86 $ b --name=robby-oh-my-zsh
87 $ lb
85 robby-oh-my-zsh https://github.com/robbyrussell/oh-my-zsh.git / 88 robby-oh-my-zsh https://github.com/robbyrussell/oh-my-zsh.git /
89
90 TODO: Error reporting with erroneous arguments or usage with incorrect syntax.
86 91