]> git.wh0rd.org Git - home.git/blob - .bin/r
glinux-vapier-setup: update for latest distro
[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 -x) set -x; shift;;
8 esac
9
10 case $1 in
11 rb-all)
12         cmd=rebase
13         shift
14         set -- all "$@"
15         ;;
16 esac
17
18 mj_init() {
19         pipe=$(mktemp)
20         rm -f "${pipe}"
21         mkfifo "${pipe}"
22         exec {ctlfd}<>"${pipe}"
23         rm -f "${pipe}"
24         jobs=0
25         jobs_max=${1:-$(getconf _NPROCESSORS_ONLN)}
26 }
27 _mj_child() { echo ${BASHPID} $? >&${ctlfd} ; }
28 mj_child() {
29         (
30         "$@"
31         _mj_child
32         ) &
33         mj_post_child
34 }
35 mj_post_child() {
36         : $(( ++jobs ))
37         if [[ ${jobs} -eq ${jobs_max} ]] ; then
38                 read -r -u ${ctlfd} pid ret
39                 : $(( --jobs ))
40         fi
41 }
42 mj_finish() {
43         wait
44 }
45
46 repo_root() {
47         local root=${PWD}
48         while [[ ! -d ${root}/.repo && ${root:-/} != "/" ]] ; do
49                 root=${root%/*}
50         done
51         echo "${root}"
52 }
53
54 process_reviewers() {
55         local r arr=()
56         for r in ${*//,/ } ; do
57                 case ${r} in
58                 OWNERS*|*/OWNERS*)
59                         local owners=$(
60                                 awk -F'@' '
61                                         ($2 == "chromium.org" || $2 == "google.com") {list = list "," $1}
62                                         END {print substr(list, 2)}
63                                 ' "${r}"
64                         )
65                         if [[ -z ${owners} ]] ; then
66                                 err "cannot find OWNERS list"
67                         else
68                                 echo "Auto setting reviewers to: ${owners}"
69                         fi
70                         arr+=( ${owners} )
71                         ;;
72                 *)
73                         arr+=( "${r}" )
74                         ;;
75                 esac
76         done
77         reviewers=$(printf '%s,' "${arr[@]}")
78         reviewers=${reviewers%,}
79 }
80
81 find_repo() {
82         # Diff projects have diff versions of repo.  Find a compatible one.
83         local root=$(repo_root)
84
85         # Use the manifest repo URL.
86         local manifest_dir="${root}/.repo/manifests.git"
87         local d
88
89         # Default to the local repo if it's there.
90         local search=(
91                 "${root}/.repo/repo"
92         )
93
94         case $(g --git-dir="${manifest_dir}" config remote.origin.url) in
95         *android*)
96                 search+=(
97                         /usr/local/src/repo
98                         ~/src/repo
99                 )
100                 ;;
101         *chromium*|*chrome*)
102                 search+=(
103                         ~/depot_tools
104                         ~/chromiumos/depot_tools
105                         /usr/local/src/depot_tools
106                         ~/src/depot_tools
107                 )
108                 ;;
109         esac
110         for d in "${search[@]}" ; do
111                 if [[ -x ${d}/repo ]] ; then
112                         echo "${d}"/repo
113                         return
114                 fi
115         done
116
117         # Fallback: use $PATH.
118         type -P repo
119 }
120
121 case ${acmd:-${cmd}} in
122 rebase)
123         if [[ $1 == "all" ]] ; then
124                 shift
125                 if [[ $# -eq 0 ]] ; then
126                         # This bash version is still slightly faster than repo!
127                         #exec r forall -j$(getconf _NPROCESSORS_ONLN) -p -c git rb-all
128
129                         eval "$(bash-colors --env | sed 's:^:export :')"
130                         root=$(repo_root)
131                         mj_init
132                         while read -a line ; do
133                                 dir=${line[0]}
134                                 proj=${line[2]}
135                                 if ! cd "${root}/${dir}" ; then
136                                         echo "bad ${proj}"
137                                         continue
138                                 fi
139                                 (
140                                 out=$(r rb-all . 2>&1)
141                                 if [[ -n ${out} ]] ; then
142                                         head=$(printf "%-40s" "${proj}")
143                                         echo "${out}" | sed "s:^:${head} :"
144                                 fi
145                                 _mj_child
146                                 ) &
147                                 mj_post_child
148                         done < <(r l)
149                         mj_finish
150                         exit 0
151                 fi
152
153                 exec git rb-all -q
154         fi
155         ;;
156 clean)
157         root=$(repo_root)
158         cd "${root}" || exit 1
159         mj_init
160         while read -a line ; do
161                 dir=${line[0]}
162                 proj=${line[2]}
163                 cd "${root}/${dir}"
164                 (
165                 out=$(g clean "$@" 2>&1)
166                 if [[ -n ${out} ]] ; then
167                         echo "### ${proj}"
168                         echo "${out}"
169                 fi
170                 _mj_child
171                 ) &
172                 mj_post_child
173         done < <(r l)
174         mj_finish
175         exit
176         ;;
177 sb)
178         sb_cmd=$1
179         case ${sb_cmd} in
180         pull) ;;
181         push) ;;
182         f|fetch) sb_cmd="fetch" ;;
183         *) err "unknown sandbox command: $1"
184         esac
185
186         sync_branch="v"
187
188         root=$(repo_root)
189         cd "${root}" || exit 1
190
191         if [[ ! -e .repo/sandbox-url ]] ; then
192                 err "Please configure remote url base in ${root}/.repo/sandbox-url"
193         fi
194         remote=$(<.repo/sandbox-url) || exit 1
195
196         echo "pushing projects from ${root}"
197
198         # ssh servers do not like it when you hammer them :)
199         #       Received disconnect from 74.125.248.80: 7: Too many concurrent connections
200         #       fatal: The remote end hung up unexpectedly
201         mj_init 16
202
203         rlist=$(r l)
204         tcnt=$(echo "${rlist}" | wc -l)
205         cnt=1
206         while read line ; do
207                 line=( ${line} )
208                 path=${line[0]}
209                 export GIT_DIR=${path}/.git
210                 proj=${line[2]}
211                 printf '### (%*i/%i %3i%%) %s\n' \
212                         ${#tcnt} $((cnt++)) ${tcnt} $(( cnt * 100 / tcnt )) ${proj}
213                 src="${sync_branch}"
214                 case ${sb_cmd} in
215                 push)
216                         g l -1 ${src} >& /dev/null || src=
217                         mj_child g push --force ${remote}/${proj} ${src}:refs/sandbox/${USER}/${sync_branch} >/dev/null
218                         ;;
219                 pull)
220                         ;;
221                 fetch)
222                         mj_child g fetch ${remote}/${proj} refs/sandbox/${USER}/${sync_branch}:refs/remotes/sb/${sync_branch} >/dev/null
223                         ;;
224                 esac
225         done < <(echo "${rlist}")
226         mj_finish
227
228         exit 0
229         ;;
230 upload)
231         args=()
232         while [[ $# -gt 0 ]] ; do
233                 case $1 in
234                 --re)
235                         process_reviewers "$2"
236                         args+=( --re "${reviewers}" )
237                         shift 2
238                         continue
239                         ;;
240                 esac
241                 args+=( "$1" )
242                 shift
243         done
244         set -- "${args[@]}"
245         ;;
246 email)
247         email=${1:-${USER}@chromium.org}
248
249         root=$(repo_root)
250         git --git-dir="${root}/.repo/manifests.git" cfg user.email "${email}"
251         git --git-dir="${root}/.repo/repo/.git" cfg user.email "${email}"
252
253         cmd='forall'
254         set -- -c "git cfg user.email '${email}'"
255         ;;
256 esac
257
258 exec $(find_repo) ${acmd:-${cmd}} "$@"