]> git.wh0rd.org Git - home.git/blob - .bin/r
71541f6d2a5ebbd4143e3a62df2a52c7d6e61aef
[home.git] / .bin / r
1 #!/bin/bash
2 g() { git "$@"; }
3 err() { printf '%b\n' "$*" 1>&2; exit 1; }
4 vr() { echo "$@"; "$@"; }
5
6 case $1 in
7 ""|-*) ;;
8 l)
9         cmd=list
10         shift
11         ;;
12 s)
13         cmd=sync
14         shift
15         ;;
16 *)
17         cmd=$1
18         shift
19         acmd=$(git config --get "alias.${cmd}" | sed 's: -.*::')
20         ;;
21 esac
22
23 mj_init() {
24         pipe=$(mktemp)
25         rm -f "${pipe}"
26         mkfifo "${pipe}"
27         exec {ctlfd}<>"${pipe}"
28         rm -f "${pipe}"
29         jobs=0
30         jobs_max=${1:-$(getconf _NPROCESSORS_ONLN)}
31 }
32 _mj_child() { echo ${BASHPID} $? >&${ctlfd} ; }
33 mj_child() {
34         (
35         "$@"
36         _mj_child
37         ) &
38         mj_post_child
39 }
40 mj_post_child() {
41         : $(( ++jobs ))
42         if [[ ${jobs} -eq ${jobs_max} ]] ; then
43                 read -r -u ${ctlfd} pid ret
44                 : $(( --jobs ))
45         fi
46 }
47 mj_finish() {
48         wait
49 }
50
51 repo_root() {
52         local root=${PWD}
53         while [[ ! -d ${root}/.repo && ${root} != "/" ]] ; do
54                 root=${root%/*}
55         done
56         echo "${root}"
57 }
58
59 case ${acmd:-${cmd}} in
60 rebase)
61         if [[ $1 == "all" ]] ; then
62                 shift
63                 if [[ $# -eq 0 ]] ; then
64                         eval $(bash-colors --env | sed 's:^:export :')
65                         root=$(repo_root)
66                         mj_init
67                         while read -a line ; do
68                                 dir=${line[0]}
69                                 proj=${line[2]}
70                                 cd "${root}/${dir}"
71                                 (
72                                 out=$(env _proj=${proj} r rb all . 2>&1)
73                                 if [[ -n ${out} ]] ; then
74                                         while read line ; do
75                                                 if [[ ${line} == "# "* ]] ; then
76                                                         line="${line#[#] }"
77                                                         printf '%s### %s%-40s%s: %s\n' \
78                                                                 "${BRACKET}" "${GOOD}" "${line%%:*}" "${NORMAL}" "${line#*:}"
79                                                 else
80                                                         echo "${line}"
81                                                 fi
82                                         done < <(echo "${out}")
83                                 fi
84                                 _mj_child
85                                 ) &
86                                 mj_post_child
87                         done < <(r l)
88                         mj_finish
89                         exit 0
90                         #exec r forall -p -c 'r rb all .' </dev/null
91                 fi
92
93                 branches=$(g b | awk '
94                         {
95                                 if ($0 ~ "^[*] *[(]no branch[)]") {
96                                         next
97                                 } else if ($1 == "*") {
98                                         b = $2
99                                 } else {
100                                         list = list $1 " "
101                                 }
102                         }
103                         END { print list b }')
104                 [[ -z ${branches} ]] && exit 0
105
106                 [[ -z ${GOOD} ]] && eval $(bash-colors --env)
107                 #echo "${GOOD}### ${PWD}${NORMAL}"
108                 # Skip if rebase is in progress.
109                 if [[ -e .git/rebase-merge/interactive ]] ; then
110                         echo -e "# ${_proj}: ${WARN}skipping due to active rebase${NORMAL}"
111                         exit 1
112                 fi
113                 for b in ${branches} ; do
114                         #echo " ${HILITE}### $b${NORMAL}"
115                         g co -q $b || exit 1
116                         if ! r rb -q "$@" ; then
117                                 g rb-a
118                         fi
119                 done
120                 exit 0
121         fi
122         ;;
123 clean)
124         root=$(repo_root)
125         cd "${root}" || exit 1
126         mj_init
127         while read -a line ; do
128                 dir=${line[0]}
129                 proj=${line[2]}
130                 cd "${root}/${dir}"
131                 (
132                 out=$(g clean "$@" 2>&1)
133                 if [[ -n ${out} ]] ; then
134                         echo "### ${proj}"
135                         echo "${out}"
136                 fi
137                 _mj_child
138                 ) &
139                 mj_post_child
140         done < <(r l)
141         mj_finish
142         exit
143         ;;
144 sb-push)
145         sync_branch="v"
146
147         root=$(repo_root)
148         cd "${root}" || exit 1
149
150         if [[ ! -e .repo/sandbox-url ]] ; then
151                 err "Please configure remote url base in ${root}/.repo/sandbox-url"
152         fi
153         remote=$(<.repo/sandbox-url) || exit 1
154
155         echo "pushing projects from ${root}"
156
157         # ssh servers do not like it when you hammer them :)
158         #       Received disconnect from 74.125.248.80: 7: Too many concurrent connections
159         #       fatal: The remote end hung up unexpectedly
160         mj_init 16
161
162         rlist=$(r l)
163         tcnt=$(echo "${rlist}" | wc -l)
164         cnt=1
165         while read line ; do
166                 line=( ${line} )
167                 path=${line[0]}
168                 export GIT_DIR=${path}/.git
169                 proj=${line[2]}
170                 printf '### (%*i/%i %3i%%) %s\n' \
171                         ${#tcnt} $((cnt++)) ${tcnt} $(( cnt * 100 / tcnt )) ${proj}
172                 src="${sync_branch}"
173                 g l -1 ${src} >& /dev/null || src=
174                 mj_child g push --force ${remote}/${proj} ${src}:refs/sandbox/${USER}/${sync_branch} >/dev/null
175         done < <(echo "${rlist}")
176         mj_finish
177
178         exit 0
179         ;;
180 g-push)
181         # For the times when repo is being stupid, push directly to gerrit myself.
182         if ! branch=$(g symbolic-ref -q HEAD) ; then
183                 err "could not figure out active branch"
184         fi
185         branch=${branch#refs/heads/}
186         if ! remote_branch=$(g cfg --get "branch.${branch}.merge") ; then
187                 err "could not figure out remote branch"
188         fi
189         if ! remote=$(g cfg --get "branch.${branch}.remote") ; then
190                 for remote in cros-internal cros origin ; do
191                          g cfg --get "remote.${remote}.url" >/dev/null && break
192                 done
193         fi
194         remote_branch=${remote_branch#refs/heads/}
195
196         git_args=()
197         reviewers=""
198         while [[ $# -gt 0 ]] ; do
199                 case $1 in
200                 --re)
201                         reviewers=$2
202                         shift
203                         ;;
204                 -n|--dry-run)
205                         git_args+=( $1 )
206                         ;;
207                 *)
208                         err "unknown option: $1"
209                         ;;
210                 esac
211                 shift
212         done
213
214         if [[ -n ${reviewers} ]] ; then
215                 reviewers=( ${reviewers//,/ } )
216                 git_args+=( "--receive-pack=git receive-pack ${reviewers[*]/#/--reviewer=}" )
217         fi
218
219         vr git push "${git_args[@]}" ${remote} ${branch}:refs/for/${remote_branch} && exit
220         err "could not figure out remote to push to"
221         ;;
222 sync)
223         set -- -j16 "$@"
224         ;;
225 upload)
226         args=()
227         while [[ $# -gt 0 ]] ; do
228                 case $1 in
229                 --re)
230                         if [[ $2 == *"OWNERS" ]] ; then
231                                 owners=$(awk -F'@' '{list = list "," $1} END {print substr(list, 2)}' "$2")
232                                 if [[ -z ${owners} ]] ; then
233                                         err "cannot find OWNERS list"
234                                 else
235                                         echo "Auto setting reviewers to: ${owners}"
236                                 fi
237                                 args+=( --re "${owners}" )
238                                 shift 2
239                                 continue
240                         fi
241                         ;;
242                 esac
243                 args+=( "$1" )
244                 shift
245         done
246         set -- "${args[@]}"
247         ;;
248 esac
249
250 exec repo ${acmd:-${cmd}} "$@"