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