Commit fdcb458fd98460bc8e1532121d54acfda7fab4cb

Authored by Shrikant Sharat
1 parent 889cc93f91

Update messes plugins with `--no-local-clone` set.

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