blob: 9ae5e00f631f12b4d43c81b2c3e8a260f1dea606 [file] [log] [blame]
Chirayu Desaid3082102013-04-10 21:11:02 +05301# -*- mode: sh; -*-
Chirayu Desaia8305562013-03-16 20:01:16 +05302
Chirayu Desaid3082102013-04-10 21:11:02 +05303declare -A CMD_HANDLERS
4CMD_HANDLERS=(
5 ["init"]=_repo_init
6 ["help"]=_repo_help
7 ["abandon"]=_repo_abandon
8 ["branch"]=_repo_branch
9 ["branches"]=_repo_branches
10 ["checkout"]=_repo_checkout
11 ["cherry-pick"]=_repo_cherry_pick
12 ["diff"]=_repo_diff
13 ["download"]=_repo_download
14 ["forall"]=_repo_forall
15 ["grep"]=_repo_grep
16 ["list"]=_repo_list
17 ["prune"]=_repo_prune
18 ["rebase"]=_repo_rebase
19 ["selfupdate"]=_repo_selfupdate
20 ["smartsync"]=_repo_smartsync
21 ["stage"]=_repo_stage
22 ["start"]=_repo_start
23 ["status"]=_repo_status
24 ["sync"]=_repo_sync
25 ["upload"]=_repo_upload
26 ["version"]=_repo_version
27)
Chirayu Desaia8305562013-03-16 20:01:16 +053028
Chirayu Desaid3082102013-04-10 21:11:02 +053029# To be populated by command handlers.
30declare -a OPTIONS
31declare -A ARG_OPTIONS
32
33declare cur
34declare prev
35
36_init_cur_prev() {
37 cur=$(_get_cword "=")
38 prev=$(_get_cword "=" 1)
39
40 _split_longopt
Chirayu Desaia8305562013-03-16 20:01:16 +053041}
42
Chirayu Desaid3082102013-04-10 21:11:02 +053043_find_repo() {
44 local dir=$(pwd)
45 local found=1
Chirayu Desaia8305562013-03-16 20:01:16 +053046
Chirayu Desaid3082102013-04-10 21:11:02 +053047 while [ "${dir}" != / ]
48 do
Chirayu Desai58bc76b2013-04-30 10:33:11 +053049 if [ -e "${dir}/.repo/repo/main.py" ]
Chirayu Desaid3082102013-04-10 21:11:02 +053050 then
51 found=0
52 break
53 fi
Chirayu Desaia8305562013-03-16 20:01:16 +053054
Chirayu Desaid3082102013-04-10 21:11:02 +053055 dir=$(cd "${dir}/.." && pwd)
56 done
Chirayu Desaia8305562013-03-16 20:01:16 +053057
Chirayu Desaid3082102013-04-10 21:11:02 +053058 if [ ${found} -eq 0 ]
59 then
60 echo "${dir}"
Chirayu Desaia8305562013-03-16 20:01:16 +053061 fi
Chirayu Desaid3082102013-04-10 21:11:02 +053062}
63
64_is_repo_dir() {
65 local repo_root=$(_find_repo)
66
67 [ -n "${repo_root}" ]
68}
69
70_gen_comps() {
71 local completions="$1"
72 local suffix="${2:- }"
73
74 local -i i
75 local -a tmp=( $(compgen -W "${completions}" -- ${cur}) )
76
77 for (( i=0; i < ${#tmp[*]}; i++ ))
78 do
79 tmp[$i]="${tmp[$i]}${suffix}"
80 done
81
82 COMPREPLY=(
83 "${COMPREPLY[@]}"
84 "${tmp[@]}"
85 )
86}
87
88_strip_colors () {
89 # taken from http://goo.gl/7KlLZ
90 sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
91}
92
93_no_completion() {
94 true
95}
96
97_command_completion() {
98 local cmds
99
100 if _is_repo_dir
101 then
102 cmds=("abandon" "branch" "branches" "checkout" "cherry-pick" "diff"
103 "download" "forall" "grep" "help" "init" "list" "prune" "rebase"
104 "selfupdate" "smartsync" "stage" "start" "status" "sync"
105 "upload" "version")
106 else
107 cmds=("help" "init")
108 fi
109
110 _gen_comps "${cmds[*]}"
111}
112
113_branch_completion() {
114 local raw_branches
115
116 # separate statement required to be able to access exit code
117 raw_branches=$(repo branches 2>/dev/null)
118
119 if [ $? -eq 0 ]
120 then
121 local branches=$(
122 echo "${raw_branches}" |
123 _strip_colors | awk 'BEGIN { FS="|" } { print $1 }' | cut -c 3-
124 )
125
126 _gen_comps "${branches}"
127 fi
128}
129
130_dir_completion() {
131 _filedir -d
132}
133
134_project_completion() {
135 local repo_root=$(_find_repo)
136
137 if [ -n "${repo_root}" -a -f "${repo_root}/.repo/project.list" ]
138 then
139 local projects=$(cat "${repo_root}/.repo/project.list")
140 _gen_comps "${projects}"
141 fi
142}
143
144_manifest_completion() {
145 local repo_root=$(_find_repo)
146
147 if [ -n "${repo_root}" ]
148 then
149 local manifests_dir="${repo_root}/.repo/manifests"
150 local git_dir="${manifests_dir}/.git"
151 local candidates
152
153 manifests=$(
154 git --git-dir "${git_dir}" ls-files "*.xml" 2>/dev/null)
155
156 if [ $? -eq 0 ]
157 then
158 _gen_comps "${manifests}"
159 fi
160 fi
161}
162
163_path_cmd_completion() {
164 _gen_comps "$(compgen -c ${cur})"
165}
166
167_is_option() {
168 local opt="$1"
169
170 [[ "${opt}" == -* ]]
171}
172
173_is_long_option() {
174 local opt="$1"
175
176 [[ "${opt}" == --* ]]
177}
178
179_expects_arg() {
180 local opt="$1"
181
182 if [[ ${ARG_OPTIONS[$opt]} ]]
183 then
184 return 0
185 else
186 return 1
187 fi
188}
189
190_handle_options() {
191 if _expects_arg "${prev}"
192 then
193 local handler=${ARG_OPTIONS[$prev]}
194 eval ${handler} "${cur}"
195 elif _is_option "${cur}"
196 then
197 _gen_comps "${OPTIONS[*]}"
198
199 local arg_short
200 local arg_long
201
202 for opt in "${!ARG_OPTIONS[@]}"
203 do
204 if _is_long_option "${opt}"
205 then
206 arg_long="${arg_long} ${opt}"
207 else
208 arg_short="${arg_short} ${opt}"
209 fi
210 done
211
212 _gen_comps "${arg_short}"
213 _gen_comps "${arg_long}" "="
214 else
215 return 1
216 fi
217
Chirayu Desaia8305562013-03-16 20:01:16 +0530218 return 0
Chirayu Desaid3082102013-04-10 21:11:02 +0530219}
220
221_is_known_shortopt() {
222 local needle="$1"
223
224 for opt in ${OPTIONS[@]}
225 do
226 if [ "${opt}" = "${needle}" ]
227 then
228 return 0
229 fi
230 done
231
232 return 1
233}
234
235_is_known_longopt() {
236 local needle="$1"
237
238 [[ ${ARG_OPTIONS[$1]} ]]
239}
240
241_arg_index() {
242 local -i i=2 # skip repo and command
243 local -i ix=0
244
245 while [ ${i} -lt ${COMP_CWORD} ]
246 do
247 if _is_known_shortopt "${COMP_WORDS[i]}"
248 then
249 i+=1
250 elif _is_known_longopt "${COMP_WORDS[i]}"
251 then
252 i+=2
253 elif _is_option "${COMP_WORDS[i]}"
254 then
255 i+=1
256 else
257 i+=1
258 ix+=1
259 fi
260 done
261
262 eval $1="${ix}"
263}
264
265_when_ix() {
266 local ix="$1"
267 local completion="$2"
268
269 _arg_index arg_ix
270
271 if [ ${arg_ix} -eq ${ix} ]
272 then
273 ${completion}
274 return 0
275 else
276 return 1
277 fi
278}
279
280_when_first() {
281 _when_ix 0 "$1"
282}
283
284_when_even() {
285 local completion="$1"
286
287 _arg_index arg_ix
288
289 if [ $(( ${arg_ix} % 2 )) -eq 0 ]
290 then
291 ${completion}
292 return 0
293 else
294 return 1
295 fi
296}
297
298_cmp_opts() {
299 local opt="$1"
300 local word="$2"
301
302 if _is_option "${opt}" && ! _is_long_option "${opt}"
303 then
304 [ "${word}" == "${opt}" ]
305 else
306 [[ "${word}" == "${opt}"=* || "${word}" == "${opt}" ]]
307 fi
308}
309
310_before() {
311 local completion="$1"
312 local words
313
314 shift
315
316 _get_comp_words_by_ref -n = words
317
318 for word in "${words[@]}"
319 do
320 for needle in "$@"
321 do
322 if _cmp_opts "${needle}" "${word}"
323 then
324 return 1
325 fi
326 done
327 done
328
329 ${completion}
Chirayu Desaia8305562013-03-16 20:01:16 +0530330 return 0
Chirayu Desaid3082102013-04-10 21:11:02 +0530331}
332
333_repo_init() {
334 OPTIONS=(
335 "-h" "--help"
336 "-q" "--quite"
337 "--mirror"
338 "--no-repo-verify"
339 )
340
341 ARG_OPTIONS=(
342 ["-u"]=_no_completion
343 ["--manifest-url"]=_no_completion
344 ["-b"]=_no_completion
345 ["--manifest-branch"]=_no_completion
346 ["-m"]=_manifest_completion
347 ["--manifest-name"]=_manifest_completion
348 ["--reference"]=_dir_completion
349 ["--repo-url"]=_no_completion
350 ["--repo-branch"]=_no_completion
351 )
352
353 _handle_options
354}
355
356_repo_help() {
357 OPTIONS=(
358 "-a" "--all"
359 "-h" "--help"
360 )
361
362 ARG_OPTIONS=()
363
364 _handle_options || _when_first _command_completion
365}
366
367_repo_abandon() {
368 OPTIONS=(
369 "-h" "--help"
370 )
371
372 ARG_OPTIONS=()
373
374 _handle_options || _when_first _branch_completion || _project_completion
375}
376
377_repo_branch() {
378 OPTIONS=(
379 "-h" "--help"
380 )
381
382 ARG_OPTIONS=()
383
384 _handle_options
385}
386
387_repo_branches() {
388 OPTIONS=(
389 "-h" "--help"
390 )
391
392 ARG_OPTIONS=()
393
394 _handle_options
395}
396
397_repo_checkout() {
398 OPTIONS=(
399 "-h" "--help"
400 )
401
402 ARG_OPTIONS=()
403
404 _handle_options || _when_first _branch_completion || _project_completion
405}
406
407_repo_cherry_pick() {
408 OPTIONS=(
409 "-h" "--help"
410 )
411
412 ARG_OPTIONS=()
413
414 _handle_options
415}
416
417_repo_diff() {
418 OPTIONS=(
419 "-h" "--help"
420 )
421
422 ARG_OPTIONS=()
423
424 _handle_options || _project_completion
425}
426
427_repo_download() {
428 OPTIONS=(
429 "-h" "--help"
430 )
431
432 ARG_OPTIONS=()
433
434 _handle_options || _when_even _project_completion
435}
436
437_repo_forall() {
438 OPTIONS=(
439 "-h" "--help"
440 "-p"
441 "-v" "--verbose"
442 )
443
444 ARG_OPTIONS=(
445 ["-c"]=_path_cmd_completion
446 ["--command"]=_path_cmd_completion
447 )
448
449 _handle_options || _before _project_completion -c --command || _filedir
450}
451
452_repo_grep() {
453 OPTIONS=(
454 "-h" "--help"
455 "--cached"
456 "-r" "--revision"
457 "-i" "--ignore-case"
458 "-a" "--text"
459 "-I"
460 "-w" "--word-regexp"
461 "-v" "--invert-match"
462 "-G" "--basic-regexp"
463 "-E" "--extended-regexp"
464 "-F" "--fixed-strings"
465 "--all-match"
466 "--and" "--or" "--not"
467 "-(" "-)"
468 "-n"
469 "-l" "--name-only" "--files-with-matches"
470 "-L" "--files-without-match"
471 )
472
473 ARG_OPTIONS=(
474 ["-e"]=_no_completion
475 ["-C"]=_no_completion
476 ["-B"]=_no_completion
477 ["-A"]=_no_completion
478 )
479
480 _handle_options || _project_completion
481}
482
483_repo_list() {
484 OPTIONS=(
485 "-h" "--help"
486 )
487
488 ARG_OPTIONS=()
489
490 _handle_options || _project_completion
491}
492
493_repo_prune() {
494 OPTIONS=(
495 "-h" "--help"
496 )
497
498 ARG_OPTIONS=()
499
500 _handle_options || _project_completion
501}
502
503_repo_rebase() {
504 OPTIONS=(
505 "-h" "--help"
506 "-i" "--interactive"
507 "-f" "--force-rebase"
508 "--no-ff"
509 "-q" "--quiet"
510 "--autosquash"
511 )
512
513 ARG_OPTIONS=(
514 ["--whitespace"]=_no_completion
515 )
516
517 _handle_options || _project_completion
518}
519
520_repo_selfupdate() {
521 OPTIONS=(
522 "-h" "--help"
523 "--no-repo-verify"
524 )
525
526 ARG_OPTIONS=()
527
528 _handle_options
529}
530
531_repo_smartsync() {
532 OPTIONS=(
533 "-h" "--help"
534 "-f" "--force-broken"
535 "-l" "--local-only"
536 "-n" "--network-only"
537 "-d" "--detach"
538 "-q" "--quiet"
539 "--no-repo-verify"
540 )
541
542 ARG_OPTIONS=(
543 ["-j"]=_no_completion
544 ["--jobs"]=_no_completion
545
546 )
547
548 _handle_options || _project_completion
549}
550
551_repo_stage() {
552 OPTIONS=(
553 "-h" "--help"
554 "-i" "--interactive"
555 )
556
557 ARG_OPTIONS=()
558
559 _handle_options || _project_completion
560}
561
562_repo_start() {
563 OPTIONS=(
564 "-h" "--help"
565 "--all"
566 )
567
568 ARG_OPTIONS=()
569
570 _handle_options || _when_first _branch_completion || _project_completion
571}
572
573_repo_status() {
574 OPTIONS=(
575 "-h" "--help"
576 )
577
578 ARG_OPTIONS=(
579 ["-j"]=_no_completion
580 ["--jobs"]=_no_completion
581 )
582
583 _handle_options || _project_completion
584}
585
586_repo_sync() {
587 OPTIONS=(
588 "-h" "--help"
589 "-f" "--force-broken"
zh012200eb9ce2015-07-30 15:08:32 +0800590 "--force-sync"
Chirayu Desaid3082102013-04-10 21:11:02 +0530591 "-l" "--local-only"
592 "-n" "--network-only"
593 "-d" "--detach"
594 "-q" "--quiet"
595 "-s" "--smart-sync"
596 "--no-repo-verify"
597 )
598
599 ARG_OPTIONS=(
600 ["-j"]=_no_completion
601 ["--jobs"]=_no_completion
602 )
603
604 _handle_options || _project_completion
605}
606
607_repo_upload() {
608 OPTIONS=(
609 "-h" "--help"
610 "-t"
611 "--no-verify"
612 "--verify"
613 )
614
615 ARG_OPTIONS=(
616 ["--re"]=_no_completion
617 ["--reviewers"]=_no_completion
618 ["--cc"]=_no_completion
619 ["--br"]=_branch_completion
620 )
621
622 _handle_options || _project_completion
623}
624
625_repo_version() {
626 OPTIONS=(
627 "-h" "--help"
628 )
629
630 ARG_OPTIONS=()
631
632 _handle_options
633}
634
635_repo() {
636 COMPREPLY=()
637
638 _init_cur_prev
639
640 if [ ${COMP_CWORD} -eq 1 ]
641 then
642 _command_completion
643 else
644 local cmd=${COMP_WORDS[1]}
645 local handler=${CMD_HANDLERS["${cmd}"]}
646 if [ -n ${handler} ]
647 then
648 eval ${handler}
649 fi
650 fi
651
Chirayu Desaia8305562013-03-16 20:01:16 +0530652 return 0
Chirayu Desaia8305562013-03-16 20:01:16 +0530653}
654
Chirayu Desaid3082102013-04-10 21:11:02 +0530655complete -o nospace -F _repo repo