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