Commit 2873acbf1a9bb56b5b21222c78b18a0518292ba4

Authored by Gregory Hugaerts
Committed by Shrikant Sharat
1 parent fdcb458fd9

make bundles install submodules

Showing 1 changed file with 6 additions and 1 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 # <repo-url>, <plugin-location>, <bundle-type>, <has-local-clone> 5 # <repo-url>, <plugin-location>, <bundle-type>, <has-local-clone>
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 # antigen-bundle <url> [<loc>=/] 10 # antigen-bundle <url> [<loc>=/]
11 # Keyword only arguments: 11 # Keyword only arguments:
12 # branch - The branch of the repo to use for this bundle. 12 # branch - The branch of the repo to use for this bundle.
13 antigen-bundle () { 13 antigen-bundle () {
14 14
15 # Bundle spec arguments' default values. 15 # Bundle spec arguments' default values.
16 local url="$ANTIGEN_DEFAULT_REPO_URL" 16 local url="$ANTIGEN_DEFAULT_REPO_URL"
17 local loc=/ 17 local loc=/
18 local branch= 18 local branch=
19 local no_local_clone=false 19 local no_local_clone=false
20 local btype=plugin 20 local btype=plugin
21 21
22 # Parse the given arguments. (Will overwrite the above values). 22 # Parse the given arguments. (Will overwrite the above values).
23 eval "$(-antigen-parse-args \ 23 eval "$(-antigen-parse-args \
24 'url?, loc? ; branch:?, no-local-clone?, btype:?' \ 24 'url?, loc? ; branch:?, no-local-clone?, btype:?' \
25 "$@")" 25 "$@")"
26 26
27 # Check if url is just the plugin name. Super short syntax. 27 # Check if url is just the plugin name. Super short syntax.
28 if [[ "$url" != */* ]]; then 28 if [[ "$url" != */* ]]; then
29 loc="plugins/$url" 29 loc="plugins/$url"
30 url="$ANTIGEN_DEFAULT_REPO_URL" 30 url="$ANTIGEN_DEFAULT_REPO_URL"
31 fi 31 fi
32 32
33 # Resolve the url. 33 # Resolve the url.
34 url="$(-antigen-resolve-bundle-url "$url")" 34 url="$(-antigen-resolve-bundle-url "$url")"
35 35
36 # Add the branch information to the url. 36 # Add the branch information to the url.
37 if [[ ! -z $branch ]]; then 37 if [[ ! -z $branch ]]; then
38 url="$url|$branch" 38 url="$url|$branch"
39 fi 39 fi
40 40
41 # The `make_local_clone` variable better represents whether there should be 41 # The `make_local_clone` variable better represents whether there should be
42 # a local clone made. For cloning to be avoided, firstly, the `$url` should 42 # a local clone made. For cloning to be avoided, firstly, the `$url` should
43 # be an absolute local path and `$branch` should be empty. In addition to 43 # be an absolute local path and `$branch` should be empty. In addition to
44 # these two conditions, either the `--no-local-clone` option should be 44 # these two conditions, either the `--no-local-clone` option should be
45 # given, or `$url` should not a git repo. 45 # given, or `$url` should not a git repo.
46 local make_local_clone=true 46 local make_local_clone=true
47 if [[ $url == /* && -z $branch && 47 if [[ $url == /* && -z $branch &&
48 ( $no_local_clone == true || ! -d $url/.git ) ]]; then 48 ( $no_local_clone == true || ! -d $url/.git ) ]]; then
49 make_local_clone=false 49 make_local_clone=false
50 fi 50 fi
51 51
52 # Add the theme extension to `loc`, if this is a theme. 52 # Add the theme extension to `loc`, if this is a theme.
53 if [[ $btype == theme && $loc != *.zsh-theme ]]; then 53 if [[ $btype == theme && $loc != *.zsh-theme ]]; then
54 loc="$loc.zsh-theme" 54 loc="$loc.zsh-theme"
55 fi 55 fi
56 56
57 # Add it to the record. 57 # Add it to the record.
58 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype" 58 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype"
59 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone" 59 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone"
60 60
61 # Ensure a clone exists for this repo, if needed. 61 # Ensure a clone exists for this repo, if needed.
62 if $make_local_clone; then 62 if $make_local_clone; then
63 -antigen-ensure-repo "$url" 63 -antigen-ensure-repo "$url"
64 fi 64 fi
65 65
66 # Load the plugin. 66 # Load the plugin.
67 -antigen-load "$url" "$loc" "$btype" "$make_local_clone" 67 -antigen-load "$url" "$loc" "$btype" "$make_local_clone"
68 68
69 } 69 }
70 70
71 -antigen-resolve-bundle-url () { 71 -antigen-resolve-bundle-url () {
72 # Given an acceptable short/full form of a bundle's repo url, this function 72 # Given an acceptable short/full form of a bundle's repo url, this function
73 # echoes the full form of the repo's clone url. 73 # echoes the full form of the repo's clone url.
74 74
75 local url="$1" 75 local url="$1"
76 76
77 # Expand short github url syntax: `username/reponame`. 77 # Expand short github url syntax: `username/reponame`.
78 if [[ $url != git://* && 78 if [[ $url != git://* &&
79 $url != https://* && 79 $url != https://* &&
80 $url != /* && 80 $url != /* &&
81 $url != git@github.com:*/* 81 $url != git@github.com:*/*
82 ]]; then 82 ]]; then
83 url="https://github.com/${url%.git}.git" 83 url="https://github.com/${url%.git}.git"
84 fi 84 fi
85 85
86 echo "$url" 86 echo "$url"
87 } 87 }
88 88
89 antigen-bundles () { 89 antigen-bundles () {
90 # Bulk add many bundles at one go. Empty lines and lines starting with a `#` 90 # Bulk add many bundles at one go. Empty lines and lines starting with a `#`
91 # are ignored. Everything else is given to `antigen-bundle` as is, no 91 # are ignored. Everything else is given to `antigen-bundle` as is, no
92 # quoting rules applied. 92 # quoting rules applied.
93 93
94 local line 94 local line
95 95
96 grep -v '^\s*$\|^#' | while read line; do 96 grep -v '^\s*$\|^#' | while read line; do
97 # Using `eval` so that we can use the shell-style quoting in each line 97 # Using `eval` so that we can use the shell-style quoting in each line
98 # piped to `antigen-bundles`. 98 # piped to `antigen-bundles`.
99 eval "antigen-bundle $line" 99 eval "antigen-bundle $line"
100 done 100 done
101 } 101 }
102 102
103 antigen-update () { 103 antigen-update () {
104 # Update your bundles, i.e., `git pull` in all the plugin repos. 104 # Update your bundles, i.e., `git pull` in all the plugin repos.
105 105
106 date > $ADOTDIR/revert-info 106 date > $ADOTDIR/revert-info
107 107
108 -antigen-echo-record | 108 -antigen-echo-record |
109 awk '$4 == "true" {print $1}' | 109 awk '$4 == "true" {print $1}' |
110 sort -u | 110 sort -u |
111 while read url; do 111 while read url; do
112 echo "**** Pulling $url" 112 echo "**** Pulling $url"
113 113
114 local clone_dir="$(-antigen-get-clone-dir "$url")" 114 local clone_dir="$(-antigen-get-clone-dir "$url")"
115 if [[ -d "$clone_dir" ]]; then 115 if [[ -d "$clone_dir" ]]; then
116 (echo -n "$clone_dir:" 116 (echo -n "$clone_dir:"
117 cd "$clone_dir" 117 cd "$clone_dir"
118 git rev-parse HEAD) >> $ADOTDIR/revert-info 118 git rev-parse HEAD) >> $ADOTDIR/revert-info
119 fi 119 fi
120 120
121 -antigen-ensure-repo "$url" --update --verbose 121 -antigen-ensure-repo "$url" --update --verbose
122 122
123 echo 123 echo
124 done 124 done
125 } 125 }
126 126
127 antigen-revert () { 127 antigen-revert () {
128 if ! [[ -f $ADOTDIR/revert-info ]]; then 128 if ! [[ -f $ADOTDIR/revert-info ]]; then
129 echo 'No revert information available. Cannot revert.' >&2 129 echo 'No revert information available. Cannot revert.' >&2
130 fi 130 fi
131 131
132 cat $ADOTDIR/revert-info | sed '1!p' | while read line; do 132 cat $ADOTDIR/revert-info | sed '1!p' | while read line; do
133 dir="$(echo "$line" | cut -d: -f1)" 133 dir="$(echo "$line" | cut -d: -f1)"
134 git --git-dir="$dir/.git" --work-tree="$dir" \ 134 git --git-dir="$dir/.git" --work-tree="$dir" \
135 checkout "$(echo "$line" | cut -d: -f2)" 2> /dev/null 135 checkout "$(echo "$line" | cut -d: -f2)" 2> /dev/null
136 done 136 done
137 137
138 echo "Reverted to state before running -update on $( 138 echo "Reverted to state before running -update on $(
139 cat $ADOTDIR/revert-info | sed -n 1p)." 139 cat $ADOTDIR/revert-info | sed -n 1p)."
140 } 140 }
141 141
142 -antigen-get-clone-dir () { 142 -antigen-get-clone-dir () {
143 # Takes a repo url and gives out the path that this url needs to be cloned 143 # Takes a repo url and gives out the path that this url needs to be cloned
144 # to. Doesn't actually clone anything. 144 # to. Doesn't actually clone anything.
145 echo -n $ADOTDIR/repos/ 145 echo -n $ADOTDIR/repos/
146 146
147 if [[ "$1" == "https://github.com/sorin-ionescu/prezto.git" ]]; then 147 if [[ "$1" == "https://github.com/sorin-ionescu/prezto.git" ]]; then
148 # Prezto's directory *has* to be `.zprezto`. 148 # Prezto's directory *has* to be `.zprezto`.
149 echo .zprezto 149 echo .zprezto
150 150
151 else 151 else
152 echo "$1" | sed \ 152 echo "$1" | sed \
153 -e 's./.-SLASH-.g' \ 153 -e 's./.-SLASH-.g' \
154 -e 's.:.-COLON-.g' \ 154 -e 's.:.-COLON-.g' \
155 -e 's.|.-PIPE-.g' 155 -e 's.|.-PIPE-.g'
156 156
157 fi 157 fi
158 } 158 }
159 159
160 -antigen-get-clone-url () { 160 -antigen-get-clone-url () {
161 # Takes a repo's clone dir and gives out the repo's original url that was 161 # Takes a repo's clone dir and gives out the repo's original url that was
162 # used to create the given directory path. 162 # used to create the given directory path.
163 163
164 if [[ "$1" == ".zprezto" ]]; then 164 if [[ "$1" == ".zprezto" ]]; then
165 # Prezto's (in `.zprezto`), is assumed to be from `sorin-ionescu`'s 165 # Prezto's (in `.zprezto`), is assumed to be from `sorin-ionescu`'s
166 # remote. 166 # remote.
167 echo https://github.com/sorin-ionescu/prezto.git 167 echo https://github.com/sorin-ionescu/prezto.git
168 168
169 else 169 else
170 echo "$1" | sed \ 170 echo "$1" | sed \
171 -e "s:^$ADOTDIR/repos/::" \ 171 -e "s:^$ADOTDIR/repos/::" \
172 -e 's.-SLASH-./.g' \ 172 -e 's.-SLASH-./.g' \
173 -e 's.-COLON-.:.g' \ 173 -e 's.-COLON-.:.g' \
174 -e 's.-PIPE-.|.g' 174 -e 's.-PIPE-.|.g'
175 175
176 fi 176 fi
177 } 177 }
178 178
179 -antigen-ensure-repo () { 179 -antigen-ensure-repo () {
180 180
181 # Ensure that a clone exists for the given repo url and branch. If the first 181 # Ensure that a clone exists for the given repo url and branch. If the first
182 # argument is `--update` and if a clone already exists for the given repo 182 # argument is `--update` and if a clone already exists for the given repo
183 # and branch, it is pull-ed, i.e., updated. 183 # and branch, it is pull-ed, i.e., updated.
184 184
185 # Argument defaults. 185 # Argument defaults.
186 # The url. No sane default for this, so just empty. 186 # The url. No sane default for this, so just empty.
187 local url= 187 local url=
188 # Check if we have to update. 188 # Check if we have to update.
189 local update=false 189 local update=false
190 # Verbose output. 190 # Verbose output.
191 local verbose=false 191 local verbose=false
192 192
193 eval "$(-antigen-parse-args 'url ; update?, verbose?' "$@")" 193 eval "$(-antigen-parse-args 'url ; update?, verbose?' "$@")"
194 shift $# 194 shift $#
195 195
196 # Get the clone's directory as per the given repo url and branch. 196 # Get the clone's directory as per the given repo url and branch.
197 local clone_dir="$(-antigen-get-clone-dir $url)" 197 local clone_dir="$(-antigen-get-clone-dir $url)"
198 198
199 # A temporary function wrapping the `git` command with repeated arguments. 199 # A temporary function wrapping the `git` command with repeated arguments.
200 --plugin-git () { 200 --plugin-git () {
201 eval git --no-pager \ 201 eval git --no-pager \
202 --git-dir=$clone_dir/.git --work-tree=$clone_dir "$@" 202 --git-dir=$clone_dir/.git --work-tree=$clone_dir "$@"
203 } 203 }
204 204
205 # Clone if it doesn't already exist. 205 # Clone if it doesn't already exist.
206 if [[ ! -d $clone_dir ]]; then 206 if [[ ! -d $clone_dir ]]; then
207 git clone "${url%|*}" "$clone_dir" 207 git clone --recursive "${url%|*}" "$clone_dir"
208 elif $update; then 208 elif $update; then
209 # Save current revision. 209 # Save current revision.
210 local old_rev="$(--plugin-git rev-parse HEAD)" 210 local old_rev="$(--plugin-git rev-parse HEAD)"
211 # Pull changes if update requested. 211 # Pull changes if update requested.
212 --plugin-git pull 212 --plugin-git pull
213 # update submodules
214 pushd
215 cd "$clone_dir"
216 git submodule update --recursive
217 popd
213 # Get the new revision. 218 # Get the new revision.
214 local new_rev="$(--plugin-git rev-parse HEAD)" 219 local new_rev="$(--plugin-git rev-parse HEAD)"
215 fi 220 fi
216 221
217 # If its a specific branch that we want, checkout that branch. 222 # If its a specific branch that we want, checkout that branch.
218 if [[ $url == *\|* ]]; then 223 if [[ $url == *\|* ]]; then
219 local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/} 224 local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/}
220 local requested_branch="${url#*|}" 225 local requested_branch="${url#*|}"
221 # Only do the checkout when we are not already on the branch. 226 # Only do the checkout when we are not already on the branch.
222 [[ $requested_branch != $current_branch ]] && 227 [[ $requested_branch != $current_branch ]] &&
223 --plugin-git checkout $requested_branch 228 --plugin-git checkout $requested_branch
224 fi 229 fi
225 230
226 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then 231 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then
227 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}. 232 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}.
228 if $verbose; then 233 if $verbose; then
229 --plugin-git log --oneline --reverse --no-merges --stat '@{1}..' 234 --plugin-git log --oneline --reverse --no-merges --stat '@{1}..'
230 fi 235 fi
231 fi 236 fi
232 237
233 # Remove the temporary git wrapper function. 238 # Remove the temporary git wrapper function.
234 unfunction -- --plugin-git 239 unfunction -- --plugin-git
235 240
236 } 241 }
237 242
238 -antigen-load () { 243 -antigen-load () {
239 244
240 local url="$1" 245 local url="$1"
241 local loc="$2" 246 local loc="$2"
242 local btype="$3" 247 local btype="$3"
243 local make_local_clone="$4" 248 local make_local_clone="$4"
244 249
245 # The full location where the plugin is located. 250 # The full location where the plugin is located.
246 local location 251 local location
247 if $make_local_clone; then 252 if $make_local_clone; then
248 location="$(-antigen-get-clone-dir "$url")/$loc" 253 location="$(-antigen-get-clone-dir "$url")/$loc"
249 else 254 else
250 location="$url" 255 location="$url"
251 fi 256 fi
252 257
253 if [[ $btype == theme ]]; then 258 if [[ $btype == theme ]]; then
254 259
255 # Of course, if its a theme, the location would point to the script 260 # Of course, if its a theme, the location would point to the script
256 # file. 261 # file.
257 source "$location" 262 source "$location"
258 263
259 else 264 else
260 265
261 # Source the plugin script. 266 # Source the plugin script.
262 # FIXME: I don't know. Looks very very ugly. Needs a better 267 # FIXME: I don't know. Looks very very ugly. Needs a better
263 # implementation once tests are ready. 268 # implementation once tests are ready.
264 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')" 269 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')"
265 270
266 if [[ -f $location/$script_loc ]]; then 271 if [[ -f $location/$script_loc ]]; then
267 # If we have a `*.plugin.zsh`, source it. 272 # If we have a `*.plugin.zsh`, source it.
268 source "$location/$script_loc" 273 source "$location/$script_loc"
269 274
270 elif [[ -f $location/init.zsh ]]; then 275 elif [[ -f $location/init.zsh ]]; then
271 # If we have a `init.zsh`, source it. 276 # If we have a `init.zsh`, source it.
272 source "$location/init.zsh" 277 source "$location/init.zsh"
273 278
274 elif ls "$location" | grep -qm1 '\.zsh$'; then 279 elif ls "$location" | grep -qm1 '\.zsh$'; then
275 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh` 280 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh`
276 # files. 281 # files.
277 for script ($location/*.zsh(N)) source "$script" 282 for script ($location/*.zsh(N)) source "$script"
278 283
279 elif ls "$location" | grep -qm1 '\.sh$'; then 284 elif ls "$location" | grep -qm1 '\.sh$'; then
280 # If there are no `*.zsh` files either, we look for and source any 285 # If there are no `*.zsh` files either, we look for and source any
281 # `*.sh` files instead. 286 # `*.sh` files instead.
282 for script ($location/*.sh(N)) source "$script" 287 for script ($location/*.sh(N)) source "$script"
283 288
284 fi 289 fi
285 290
286 # Add to $fpath, for completion(s). 291 # Add to $fpath, for completion(s).
287 fpath=($location $fpath) 292 fpath=($location $fpath)
288 293
289 fi 294 fi
290 295
291 } 296 }
292 297
293 antigen-cleanup () { 298 antigen-cleanup () {
294 299
295 # Cleanup unused repositories. 300 # Cleanup unused repositories.
296 301
297 local force=false 302 local force=false
298 if [[ $1 == --force ]]; then 303 if [[ $1 == --force ]]; then
299 force=true 304 force=true
300 fi 305 fi
301 306
302 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then 307 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then
303 echo "You don't have any bundles." 308 echo "You don't have any bundles."
304 return 0 309 return 0
305 fi 310 fi
306 311
307 # Find directores in ADOTDIR/repos, that are not in the bundles record. 312 # Find directores in ADOTDIR/repos, that are not in the bundles record.
308 local unused_clones="$(comm -13 \ 313 local unused_clones="$(comm -13 \
309 <(-antigen-echo-record | 314 <(-antigen-echo-record |
310 awk '$4 == "true" {print $1}' | 315 awk '$4 == "true" {print $1}' |
311 while read line; do 316 while read line; do
312 -antigen-get-clone-dir "$line" 317 -antigen-get-clone-dir "$line"
313 done | 318 done |
314 sort -u) \ 319 sort -u) \
315 <(ls -d "$ADOTDIR/repos/"* | sort -u))" 320 <(ls -d "$ADOTDIR/repos/"* | sort -u))"
316 321
317 if [[ -z $unused_clones ]]; then 322 if [[ -z $unused_clones ]]; then
318 echo "You don't have any unidentified bundles." 323 echo "You don't have any unidentified bundles."
319 return 0 324 return 0
320 fi 325 fi
321 326
322 echo 'You have clones for the following repos, but are not used.' 327 echo 'You have clones for the following repos, but are not used.'
323 echo "$unused_clones" | 328 echo "$unused_clones" |
324 while read line; do 329 while read line; do
325 -antigen-get-clone-url "$line" 330 -antigen-get-clone-url "$line"
326 done | 331 done |
327 sed -e 's/^/ /' -e 's/|/, branch /' 332 sed -e 's/^/ /' -e 's/|/, branch /'
328 333
329 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then 334 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then
330 echo 335 echo
331 echo 336 echo
332 echo "$unused_clones" | while read line; do 337 echo "$unused_clones" | while read line; do
333 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..." 338 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..."
334 rm -rf "$line" 339 rm -rf "$line"
335 echo ' done.' 340 echo ' done.'
336 done 341 done
337 else 342 else
338 echo 343 echo
339 echo Nothing deleted. 344 echo Nothing deleted.
340 fi 345 fi
341 } 346 }
342 347
343 antigen-lib () { 348 antigen-lib () {
344 antigen-bundle --loc=lib 349 antigen-bundle --loc=lib
345 } 350 }
346 351
347 antigen-prezto-lib () { 352 antigen-prezto-lib () {
348 antigen-bundle sorin-ionescu/prezto 353 antigen-bundle sorin-ionescu/prezto
349 export ZDOTDIR=$ADOTDIR/repos/ 354 export ZDOTDIR=$ADOTDIR/repos/
350 } 355 }
351 356
352 antigen-theme () { 357 antigen-theme () {
353 358
354 if [[ "$1" != */* && "$1" != --* ]]; then 359 if [[ "$1" != */* && "$1" != --* ]]; then
355 # The first argument is just a name of the plugin, to be picked up from 360 # The first argument is just a name of the plugin, to be picked up from
356 # the default repo. 361 # the default repo.
357 local name="${1:-robbyrussell}" 362 local name="${1:-robbyrussell}"
358 antigen-bundle --loc=themes/$name --btype=theme 363 antigen-bundle --loc=themes/$name --btype=theme
359 364
360 else 365 else
361 antigen-bundle "$@" --btype=theme 366 antigen-bundle "$@" --btype=theme
362 367
363 fi 368 fi
364 369
365 } 370 }
366 371
367 antigen-apply () { 372 antigen-apply () {
368 # Initialize completion. 373 # Initialize completion.
369 # TODO: Only load completions if there are any changes to the bundle 374 # TODO: Only load completions if there are any changes to the bundle
370 # repositories. 375 # repositories.
371 compinit -i 376 compinit -i
372 } 377 }
373 378
374 antigen-list () { 379 antigen-list () {
375 # List all currently installed bundles. 380 # List all currently installed bundles.
376 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then 381 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
377 echo "You don't have any bundles." >&2 382 echo "You don't have any bundles." >&2
378 return 1 383 return 1
379 else 384 else
380 -antigen-echo-record | sort -u 385 -antigen-echo-record | sort -u
381 fi 386 fi
382 } 387 }
383 388
384 antigen-snapshot () { 389 antigen-snapshot () {
385 390
386 local snapshot_file="${1:-antigen-shapshot}" 391 local snapshot_file="${1:-antigen-shapshot}"
387 392
388 # The snapshot content lines are pairs of repo-url and git version hash, in 393 # The snapshot content lines are pairs of repo-url and git version hash, in
389 # the form: 394 # the form:
390 # <version-hash> <repo-url> 395 # <version-hash> <repo-url>
391 local snapshot_content="$(-antigen-echo-record | 396 local snapshot_content="$(-antigen-echo-record |
392 grep 'true$' | 397 grep 'true$' |
393 sed 's/ .*$//' | 398 sed 's/ .*$//' |
394 sort -u | 399 sort -u |
395 while read url; do 400 while read url; do
396 local dir="$(-antigen-get-clone-dir "$url")" 401 local dir="$(-antigen-get-clone-dir "$url")"
397 local version_hash="$(cd "$dir" && git rev-parse HEAD)" 402 local version_hash="$(cd "$dir" && git rev-parse HEAD)"
398 echo "$version_hash $url" 403 echo "$version_hash $url"
399 done)" 404 done)"
400 405
401 { 406 {
402 # The first line in the snapshot file is for metadata, in the form: 407 # The first line in the snapshot file is for metadata, in the form:
403 # key='value'; key='value'; key='value'; 408 # key='value'; key='value'; key='value';
404 # Where `key`s are valid shell variable names. 409 # Where `key`s are valid shell variable names.
405 410
406 # Snapshot version. Has no relation to antigen version. If the snapshot 411 # Snapshot version. Has no relation to antigen version. If the snapshot
407 # file format changes, this number can be incremented. 412 # file format changes, this number can be incremented.
408 echo -n "version='1';" 413 echo -n "version='1';"
409 414
410 # Snapshot creation date+time. 415 # Snapshot creation date+time.
411 echo -n " created_on='$(date)';" 416 echo -n " created_on='$(date)';"
412 417
413 # Add a checksum with the md5 checksum of all the snapshot lines. 418 # Add a checksum with the md5 checksum of all the snapshot lines.
414 local checksum="$(echo "$snapshot_content" | md5sum)" 419 local checksum="$(echo "$snapshot_content" | md5sum)"
415 echo -n " checksum='${checksum%% *}';" 420 echo -n " checksum='${checksum%% *}';"
416 421
417 # A newline after the metadata and then the snapshot lines. 422 # A newline after the metadata and then the snapshot lines.
418 echo "\n$snapshot_content" 423 echo "\n$snapshot_content"
419 424
420 } > "$snapshot_file" 425 } > "$snapshot_file"
421 426
422 } 427 }
423 428
424 antigen-restore () { 429 antigen-restore () {
425 430
426 if [[ $# == 0 ]]; then 431 if [[ $# == 0 ]]; then
427 echo 'Please provide a snapshot file to restore from.' >&2 432 echo 'Please provide a snapshot file to restore from.' >&2
428 return 1 433 return 1
429 fi 434 fi
430 435
431 local snapshot_file="$1" 436 local snapshot_file="$1"
432 437
433 # TODO: Before doing anything with the snapshot file, verify its checksum. 438 # TODO: Before doing anything with the snapshot file, verify its checksum.
434 # If it fails, notify this to the user and confirm if restore should 439 # If it fails, notify this to the user and confirm if restore should
435 # proceed. 440 # proceed.
436 441
437 echo -n "Restoring from $snapshot_file..." 442 echo -n "Restoring from $snapshot_file..."
438 443
439 sed -n '1!p' "$snapshot_file" | 444 sed -n '1!p' "$snapshot_file" |
440 while read line; do 445 while read line; do
441 446
442 local version_hash="${line%% *}" 447 local version_hash="${line%% *}"
443 local url="${line##* }" 448 local url="${line##* }"
444 local clone_dir="$(-antigen-get-clone-dir "$url")" 449 local clone_dir="$(-antigen-get-clone-dir "$url")"
445 450
446 if [[ ! -d $clone_dir ]]; then 451 if [[ ! -d $clone_dir ]]; then
447 git clone "$url" "$clone_dir" > /dev/null 452 git clone "$url" "$clone_dir" > /dev/null
448 fi 453 fi
449 454
450 (cd "$clone_dir" && git checkout $version_hash) 2> /dev/null 455 (cd "$clone_dir" && git checkout $version_hash) 2> /dev/null
451 456
452 done 457 done
453 458
454 echo ' done.' 459 echo ' done.'
455 echo 'Please open a new shell to get the restored changes.' 460 echo 'Please open a new shell to get the restored changes.'
456 } 461 }
457 462
458 antigen-help () { 463 antigen-help () {
459 cat <<EOF 464 cat <<EOF
460 Antigen is a plugin management system for zsh. It makes it easy to grab awesome 465 Antigen is a plugin management system for zsh. It makes it easy to grab awesome
461 shell scripts and utilities, put up on github. For further details and complete 466 shell scripts and utilities, put up on github. For further details and complete
462 documentation, visit the project's page at 'http://antigen.sharats.me'. 467 documentation, visit the project's page at 'http://antigen.sharats.me'.
463 EOF 468 EOF
464 } 469 }
465 470
466 # A syntax sugar to avoid the `-` when calling antigen commands. With this 471 # A syntax sugar to avoid the `-` when calling antigen commands. With this
467 # function, you can write `antigen-bundle` as `antigen bundle` and so on. 472 # function, you can write `antigen-bundle` as `antigen bundle` and so on.
468 antigen () { 473 antigen () {
469 local cmd="$1" 474 local cmd="$1"
470 shift 475 shift
471 "antigen-$cmd" "$@" 476 "antigen-$cmd" "$@"
472 } 477 }
473 478
474 -antigen-parse-args () { 479 -antigen-parse-args () {
475 # An argument parsing functionality to parse arguments the *antigen* way :). 480 # An argument parsing functionality to parse arguments the *antigen* way :).
476 # Takes one first argument (called spec), which dictates how to parse and 481 # Takes one first argument (called spec), which dictates how to parse and
477 # the rest of the arguments are parsed. Outputs a piece of valid shell code 482 # the rest of the arguments are parsed. Outputs a piece of valid shell code
478 # that can be passed to `eval` inside a function which creates the arguments 483 # that can be passed to `eval` inside a function which creates the arguments
479 # and their values as local variables. Suggested use is to set the defaults 484 # and their values as local variables. Suggested use is to set the defaults
480 # to all arguments first and then eval the output of this function. 485 # to all arguments first and then eval the output of this function.
481 486
482 # Spec: Only long argument supported. No support for parsing short options. 487 # Spec: Only long argument supported. No support for parsing short options.
483 # The spec must have two sections, separated by a `;`. 488 # The spec must have two sections, separated by a `;`.
484 # '<positional-arguments>;<keyword-only-arguments>' 489 # '<positional-arguments>;<keyword-only-arguments>'
485 # Positional arguments are passed as just values, like `command a b`. 490 # Positional arguments are passed as just values, like `command a b`.
486 # Keyword arguments are passed as a `--name=value` pair, like `command 491 # Keyword arguments are passed as a `--name=value` pair, like `command
487 # --arg1=a --arg2=b`. 492 # --arg1=a --arg2=b`.
488 493
489 # Each argument in the spec is separated by a `,`. Each keyword argument can 494 # Each argument in the spec is separated by a `,`. Each keyword argument can
490 # end in a `:` to specifiy that this argument wants a value, otherwise it 495 # end in a `:` to specifiy that this argument wants a value, otherwise it
491 # doesn't take a value. (The value in the output when the keyword argument 496 # doesn't take a value. (The value in the output when the keyword argument
492 # doesn't have a `:` is `true`). 497 # doesn't have a `:` is `true`).
493 498
494 # Arguments in either section can end with a `?` (should come after `:`, if 499 # Arguments in either section can end with a `?` (should come after `:`, if
495 # both are present), means optional. FIXME: Not yet implemented. 500 # both are present), means optional. FIXME: Not yet implemented.
496 501
497 # See the test file, tests/arg-parser.t for (working) examples. 502 # See the test file, tests/arg-parser.t for (working) examples.
498 503
499 local spec="$1" 504 local spec="$1"
500 shift 505 shift
501 506
502 # Sanitize the spec 507 # Sanitize the spec
503 spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')" 508 spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')"
504 509
505 local code='' 510 local code=''
506 511
507 --add-var () { 512 --add-var () {
508 test -z "$code" || code="$code\n" 513 test -z "$code" || code="$code\n"
509 code="${code}local $1='$2'" 514 code="${code}local $1='$2'"
510 } 515 }
511 516
512 local positional_args="$(echo "$spec" | cut -d\; -f1)" 517 local positional_args="$(echo "$spec" | cut -d\; -f1)"
513 local positional_args_count="$(echo $positional_args | 518 local positional_args_count="$(echo $positional_args |
514 awk -F, '{print NF}')" 519 awk -F, '{print NF}')"
515 520
516 # Set spec values based on the positional arguments. 521 # Set spec values based on the positional arguments.
517 local i=1 522 local i=1
518 while ! [[ -z $1 || $1 == --* ]]; do 523 while ! [[ -z $1 || $1 == --* ]]; do
519 524
520 if (( $i > $positional_args_count )); then 525 if (( $i > $positional_args_count )); then
521 echo "Only $positional_args_count positional arguments allowed." >&2 526 echo "Only $positional_args_count positional arguments allowed." >&2
522 echo "Found at least one more: '$1'" >&2 527 echo "Found at least one more: '$1'" >&2
523 return 528 return
524 fi 529 fi
525 530
526 local name_spec="$(echo "$positional_args" | cut -d, -f$i)" 531 local name_spec="$(echo "$positional_args" | cut -d, -f$i)"
527 local name="${${name_spec%\?}%:}" 532 local name="${${name_spec%\?}%:}"
528 local value="$1" 533 local value="$1"
529 534
530 if echo "$code" | grep -qm1 "^local $name="; then 535 if echo "$code" | grep -qm1 "^local $name="; then
531 echo "Argument '$name' repeated with the value '$value'". >&2 536 echo "Argument '$name' repeated with the value '$value'". >&2
532 return 537 return
533 fi 538 fi
534 539
535 --add-var $name "$value" 540 --add-var $name "$value"
536 541
537 shift 542 shift
538 i=$(($i + 1)) 543 i=$(($i + 1))
539 done 544 done
540 545
541 local keyword_args="$( 546 local keyword_args="$(
542 # Positional arguments can double up as keyword arguments too. 547 # Positional arguments can double up as keyword arguments too.
543 echo "$positional_args" | tr , '\n' | 548 echo "$positional_args" | tr , '\n' |
544 while read line; do 549 while read line; do
545 if [[ $line == *\? ]]; then 550 if [[ $line == *\? ]]; then
546 echo "${line%?}:?" 551 echo "${line%?}:?"
547 else 552 else
548 echo "$line:" 553 echo "$line:"
549 fi 554 fi
550 done 555 done
551 556
552 # Specified keyword arguments. 557 # Specified keyword arguments.
553 echo "$spec" | cut -d\; -f2 | tr , '\n' 558 echo "$spec" | cut -d\; -f2 | tr , '\n'
554 )" 559 )"
555 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')" 560 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')"
556 561
557 # Set spec values from keyword arguments, if any. The remaining arguments 562 # Set spec values from keyword arguments, if any. The remaining arguments
558 # are all assumed to be keyword arguments. 563 # are all assumed to be keyword arguments.
559 while [[ $1 == --* ]]; do 564 while [[ $1 == --* ]]; do
560 # Remove the `--` at the start. 565 # Remove the `--` at the start.
561 local arg="${1#--}" 566 local arg="${1#--}"
562 567
563 # Get the argument name and value. 568 # Get the argument name and value.
564 if [[ $arg != *=* ]]; then 569 if [[ $arg != *=* ]]; then
565 local name="$arg" 570 local name="$arg"
566 local value='' 571 local value=''
567 else 572 else
568 local name="${arg%\=*}" 573 local name="${arg%\=*}"
569 local value="${arg#*=}" 574 local value="${arg#*=}"
570 fi 575 fi
571 576
572 if echo "$code" | grep -qm1 "^local $name="; then 577 if echo "$code" | grep -qm1 "^local $name="; then
573 echo "Argument '$name' repeated with the value '$value'". >&2 578 echo "Argument '$name' repeated with the value '$value'". >&2
574 return 579 return
575 fi 580 fi
576 581
577 # The specification for this argument, used for validations. 582 # The specification for this argument, used for validations.
578 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")" 583 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")"
579 584
580 # Validate argument and value. 585 # Validate argument and value.
581 if [[ -z $arg_line ]]; then 586 if [[ -z $arg_line ]]; then
582 # This argument is not known to us. 587 # This argument is not known to us.
583 echo "Unknown argument '$name'." >&2 588 echo "Unknown argument '$name'." >&2
584 return 589 return
585 590
586 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then 591 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then
587 # This argument needs a value, but is not provided. 592 # This argument needs a value, but is not provided.
588 echo "Required argument for '$name' not provided." >&2 593 echo "Required argument for '$name' not provided." >&2
589 return 594 return
590 595
591 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then 596 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then
592 # This argument doesn't need a value, but is provided. 597 # This argument doesn't need a value, but is provided.
593 echo "No argument required for '$name', but provided '$value'." >&2 598 echo "No argument required for '$name', but provided '$value'." >&2
594 return 599 return
595 600
596 fi 601 fi
597 602
598 if [[ -z $value ]]; then 603 if [[ -z $value ]]; then
599 value=true 604 value=true
600 fi 605 fi
601 606
602 --add-var "${name//-/_}" "$value" 607 --add-var "${name//-/_}" "$value"
603 shift 608 shift
604 done 609 done
605 610
606 echo "$code" 611 echo "$code"
607 612
608 unfunction -- --add-var 613 unfunction -- --add-var
609 614
610 } 615 }
611 616
612 # Echo the bundle specs as in the record. The first line is not echoed since it 617 # Echo the bundle specs as in the record. The first line is not echoed since it
613 # is a blank line. 618 # is a blank line.
614 -antigen-echo-record () { 619 -antigen-echo-record () {
615 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p' 620 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
616 } 621 }
617 622
618 -antigen-env-setup () { 623 -antigen-env-setup () {
619 # Pre-startup initializations. 624 # Pre-startup initializations.
620 -set-default ANTIGEN_DEFAULT_REPO_URL \ 625 -set-default ANTIGEN_DEFAULT_REPO_URL \
621 https://github.com/robbyrussell/oh-my-zsh.git 626 https://github.com/robbyrussell/oh-my-zsh.git
622 -set-default ADOTDIR $HOME/.antigen 627 -set-default ADOTDIR $HOME/.antigen
623 628
624 # Load the compinit module. Required for `compdef` to be defined, which is 629 # Load the compinit module. Required for `compdef` to be defined, which is
625 # used by many plugins to define completions. 630 # used by many plugins to define completions.
626 autoload -U compinit 631 autoload -U compinit
627 compinit -i 632 compinit -i
628 633
629 # Setup antigen's own completion. 634 # Setup antigen's own completion.
630 compdef _antigen antigen 635 compdef _antigen antigen
631 } 636 }
632 637
633 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is 638 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is
634 # not already set. 639 # not already set.
635 -set-default () { 640 -set-default () {
636 local arg_name="$1" 641 local arg_name="$1"
637 local arg_value="$2" 642 local arg_value="$2"
638 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'" 643 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
639 } 644 }
640 645
641 # Setup antigen's autocompletion 646 # Setup antigen's autocompletion
642 _antigen () { 647 _antigen () {
643 compadd \ 648 compadd \
644 bundle\ 649 bundle\
645 bundles\ 650 bundles\
646 update\ 651 update\
647 revert\ 652 revert\
648 list\ 653 list\
649 cleanup\ 654 cleanup\
650 lib\ 655 lib\
651 theme\ 656 theme\
652 apply\ 657 apply\
653 help 658 help
654 } 659 }
655 660
656 -antigen-env-setup 661 -antigen-env-setup
657 662