OLD | NEW |
1 #!/bin/bash | 1 #!/bin/bash |
2 | 2 |
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 # This script moves ebuilds between 'stable' and 'live' states. | 7 # This script moves ebuilds between 'stable' and 'live' states. |
8 # By default 'stable' ebuilds point at and build from source at the | 8 # By default 'stable' ebuilds point at and build from source at the |
9 # last known good commit. Moving an ebuild to 'live' (via cros_workon start) | 9 # last known good commit. Moving an ebuild to 'live' (via cros_workon start) |
10 # is intended to support development. The current source tip is fetched, | 10 # is intended to support development. The current source tip is fetched, |
(...skipping 13 matching lines...) Expand all Loading... |
24 SCRIPT_ROOT=${path} | 24 SCRIPT_ROOT=${path} |
25 break | 25 break |
26 fi | 26 fi |
27 done | 27 done |
28 } | 28 } |
29 | 29 |
30 find_common_sh | 30 find_common_sh |
31 . "${SCRIPT_ROOT}/common.sh" || (echo "Unable to load common.sh" && exit 1) | 31 . "${SCRIPT_ROOT}/common.sh" || (echo "Unable to load common.sh" && exit 1) |
32 # --- END COMMON.SH BOILERPLATE --- | 32 # --- END COMMON.SH BOILERPLATE --- |
33 | 33 |
34 # Script must be run inside the chroot | 34 die "error: Please run cros_workon from chroot:/usr/bin/cros_workon" |
35 restart_in_chroot_if_needed "$@" | |
36 get_default_board | |
37 | |
38 DEFINE_string board "${DEFAULT_BOARD}" \ | |
39 "The board to set package keywords for." | |
40 DEFINE_boolean host "${FLAGS_FALSE}" \ | |
41 "Uses the host instead of board" | |
42 DEFINE_string command "git status" \ | |
43 "The command to be run by forall." | |
44 DEFINE_boolean all "${FLAGS_FALSE}" \ | |
45 "Apply to all possible packages for the given command" | |
46 | |
47 FLAGS_HELP="usage: $0 <command> [flags] [<list of packages>|--all] | |
48 commands: | |
49 start: Moves an ebuild to live (intended to support development) | |
50 stop: Moves an ebuild to stable (use last known good) | |
51 list: List of live ebuilds (workon ebuilds if --all) | |
52 list-all: List all of the live ebuilds for all setup boards | |
53 iterate: For each ebuild, cd to the source dir and run a commond" | |
54 FLAGS "$@" || exit 1 | |
55 eval set -- "${FLAGS_ARGV}" | |
56 | |
57 | |
58 # eat the workon command keywords: start, stop or list. | |
59 WORKON_CMD=$1 | |
60 shift | |
61 | |
62 # Board dir config | |
63 | |
64 # If both are specified, just use host, because board does not | |
65 # have to be specified and may come from default, in which case | |
66 # there's no way to override. | |
67 [ -n "${FLAGS_board}" ] && [ "${FLAGS_host}" = ${FLAGS_TRUE} ] && \ | |
68 FLAGS_board="" # kill board | |
69 [ -z "${FLAGS_board}" ] && [ "${FLAGS_host}" = ${FLAGS_FALSE} ] && \ | |
70 [ "${WORKON_CMD}" != "list-all" ] && \ | |
71 die "You must specify either --host or --board=" | |
72 | |
73 if [ -n "${FLAGS_board}" ]; then | |
74 BOARD_DIR=/build/"${FLAGS_board}" # --board specified | |
75 EQUERYCMD=equery-"${FLAGS_board}" | |
76 EBUILDCMD=ebuild-"${FLAGS_board}" | |
77 PORTAGEQCMD=portageq-"${FLAGS_board}" | |
78 BOARD_STR="${FLAGS_board}" | |
79 BOARD_KEYWORD="$(portageq-${FLAGS_board} envvar ARCH)" | |
80 else | |
81 BOARD_DIR="" # --host specified | |
82 EQUERYCMD=equery | |
83 EBUILDCMD=ebuild | |
84 PORTAGEQCMD=portageq | |
85 BOARD_STR="host" | |
86 BOARD_KEYWORD="$(portageq envvar ARCH)" | |
87 fi | |
88 | |
89 WORKON_DIR=${CHROOT_TRUNK_DIR}/.config/cros_workon | |
90 KEYWORDS_DIR=${BOARD_DIR}/etc/portage/package.keywords | |
91 UNMASK_DIR=${BOARD_DIR}/etc/portage/package.unmask | |
92 WORKON_FILE=${WORKON_DIR}/${FLAGS_board:-host} | |
93 KEYWORDS_FILE=${KEYWORDS_DIR}/cros-workon | |
94 UNMASK_FILE=${UNMASK_DIR}/cros-workon | |
95 | |
96 # TODO(msb): remove the backward compatibility after 10/01/2010 | |
97 if [ -d "${WORKON_DIR}" ]; then | |
98 sudo chown -R "${USER}" "${WORKON_DIR}" | |
99 fi | |
100 | |
101 mkdir -p "${WORKON_DIR}" || die "mkdir -p ${WORKON_DIR}" | |
102 touch "${WORKON_FILE}" || die "touch ${WORKON_FILE}" | |
103 sudo mkdir -p "${KEYWORDS_DIR}" "${UNMASK_DIR}" || \ | |
104 die "mkdir -p ${KEYWORDS_DIR} ${UNMASK_DIR}" | |
105 if [ ! -L "${KEYWORDS_FILE}" ]; then | |
106 sudo rm -f "${KEYWORDS_FILE}" | |
107 sudo ln -s "${WORKON_FILE}" "${KEYWORDS_FILE}" || \ | |
108 die "ln -s ${WORKON_FILE} ${KEYWORDS_FILE}" | |
109 fi | |
110 if [ ! -L "${UNMASK_FILE}" ]; then | |
111 [ -f "${UNMASK_FILE}" ] && sudo mv "${UNMASK_FILE}" "${WORKON_FILE}" | |
112 sudo ln -s "${WORKON_FILE}" "${UNMASK_FILE}" || \ | |
113 die "ln -s ${WORKON_FILE} ${UNMASK_FILE}" | |
114 fi | |
115 | |
116 find_keyword_workon_ebuilds() { | |
117 local keyword="${1}" | |
118 local overlay | |
119 | |
120 local cros_overlays=$("${PORTAGEQCMD}" envvar PORTDIR_OVERLAY) | |
121 | |
122 # NOTE: overlay may be a symlink, and we have to use ${overlay}/ | |
123 for overlay in ${cros_overlays}; do | |
124 # only look up ebuilds named 9999 to eliminate duplicates | |
125 find ${overlay}/ -name '*9999.ebuild' | \ | |
126 xargs grep -l "inherit.*cros-workon" | \ | |
127 xargs grep -l "KEYWORDS=.*${keyword}.*" | |
128 done | |
129 } | |
130 | |
131 show_workon_ebuilds() { | |
132 local keyword=$1 | |
133 | |
134 find_keyword_workon_ebuilds ${keyword} | \ | |
135 sed -e 's/.*\/\([^/]*\)\/\([^/]*\)\/.*\.ebuild/\1\/\2/' | \ | |
136 sort -u | |
137 # This changes the absolute path to ebuilds into category/package. | |
138 } | |
139 | |
140 # Canonicalize package name to category/package. | |
141 canonicalize_name () { | |
142 local pkgfile | |
143 local pkgname | |
144 | |
145 if grep -qx "=$1-9999" "${WORKON_FILE}" ; then | |
146 echo $1 | |
147 return 0 | |
148 fi | |
149 | |
150 if ! pkgfile=$(ACCEPT_KEYWORDS="~${BOARD_KEYWORD}" ${EQUERYCMD} which $1); the
n | |
151 warn "error looking up package $1" 1>&2 | |
152 return 1 | |
153 fi | |
154 | |
155 pkgname=$(\ | |
156 echo "${pkgfile}" |awk -F '/' '{ print $(NF-2) "/" $(NF-1) }') | |
157 | |
158 if ! grep -q "cros-workon" ${pkgfile}; then | |
159 warn "${pkgname} is not a cros-workon package" 1>&2 | |
160 return 1 | |
161 fi | |
162 echo "${pkgname}" | |
163 return 0 | |
164 } | |
165 | |
166 # Canonicalize a list of names. | |
167 canonicalize_names () { | |
168 local atoms=$1 | |
169 local names="" | |
170 local atom | |
171 | |
172 for atom in ${atoms}; do | |
173 local name=$(canonicalize_name "${atom}") | |
174 [ -n "${name}" ] || return 1 | |
175 names+=" ${name}" | |
176 done | |
177 | |
178 echo "${names}" | |
179 } | |
180 | |
181 # Display ebuilds currently part of the live branch and open for development. | |
182 show_live_ebuilds () { | |
183 sed -n 's/^=\(.*\)-9999$/\1/p' "${WORKON_FILE}" | |
184 } | |
185 | |
186 # Display ebuilds currently part of the live branch and open for development | |
187 # for any board that currently has live ebuilds. | |
188 show_all_live_ebuilds () { | |
189 local workon_file | |
190 for workon_file in ${WORKON_DIR}/*; do | |
191 if [ -s "${workon_file}" ]; then | |
192 echo -e "${V_BOLD_GREEN}$(basename ${workon_file}):${V_VIDOFF}" | |
193 sed -n 's/^=\(.*\)-9999$/ \1/p' "${workon_file}" | |
194 echo "" | |
195 fi | |
196 done | |
197 } | |
198 | |
199 # This is called only for "cros-workon start". We dont handle the | |
200 # "stop" case since the local changes are ignored anyway since the | |
201 # 9999.ebuild is masked and we dont want to deal with what to do with | |
202 # the user's local changes. | |
203 regen_manifest_and_sync() { | |
204 # Nothing to do unless you are working on the minilayout | |
205 local manifest=${CHROOT_TRUNK_DIR}/.repo/manifest.xml | |
206 if [ $(basename $(readlink -f ${manifest})) != "minilayout.xml" ]; then | |
207 return | |
208 fi | |
209 | |
210 local pkgname | |
211 for pkgname in $(show_live_ebuilds); do | |
212 eval $(${EBUILDCMD} $(${EQUERYCMD} which ${pkgname}) info) | |
213 local srcdir=$(readlink -m ${CROS_WORKON_SRCDIR}) | |
214 local trunkdir=$(readlink -m ${CHROOT_TRUNK_DIR}) | |
215 local project_path=${srcdir#${trunkdir}/} | |
216 | |
217 loman add --workon "${CROS_WORKON_PROJECT}" "${project_path}" | |
218 done | |
219 echo "Please run \"repo sync\" now." | |
220 } | |
221 | |
222 # Move a stable ebuild to the live development catgeory. The ebuild | |
223 # src_unpack step fetches the package source for local development. | |
224 ebuild_to_live () { | |
225 local atoms=$1 | |
226 local atoms_success="" | |
227 local atom | |
228 | |
229 for atom in ${atoms}; do | |
230 if ! grep -qx "=${atom}-9999" "${WORKON_FILE}" ; then | |
231 if sudo bash -c "echo \"=${atom}-9999\" >> \"${WORKON_FILE}\""; then | |
232 atoms_success="${atoms_success} ${atom}" | |
233 fi | |
234 else | |
235 warn "Already working on ${atom}" | |
236 fi | |
237 done | |
238 [ -n "${atoms_success}" ] && regen_manifest_and_sync && \ | |
239 info "Started working on '${atoms_success/ /}' for '${BOARD_STR}'" | |
240 } | |
241 | |
242 # Move a live development ebuild back to stable. | |
243 ebuild_to_stable () { | |
244 local atoms=$1 | |
245 local atoms_success="" | |
246 local atom | |
247 | |
248 for atom in ${atoms}; do | |
249 if grep -qx "=${atom}-9999" "${WORKON_FILE}" ; then | |
250 if sudo sed -e "/^=${atom/\//\\/}-9999\$/d" -i "${WORKON_FILE}"; then | |
251 atoms_success="${atoms_success} ${atom}" | |
252 fi | |
253 else | |
254 warn "Not working on ${atom}" | |
255 fi | |
256 done | |
257 [ -n "${atoms_success}" ] && \ | |
258 info "Stopped working on '${atoms_success/ /}' for '${BOARD_STR}'" | |
259 } | |
260 | |
261 # Run a command on all or a set of repos. | |
262 ebuild_iterate() { | |
263 local atoms=$1 | |
264 local atom | |
265 | |
266 for atom in ${atoms}; do | |
267 info "Running \"${FLAGS_command}\" on ${atom}" | |
268 eval $(${EBUILDCMD} $(${EQUERYCMD} which ${atom}) info) | |
269 (cd "${CROS_WORKON_SRCDIR}" && bash -c "${FLAGS_command}") | |
270 done | |
271 } | |
272 | |
273 # --all makes commands operate on different lists | |
274 if [ ${FLAGS_all} = "${FLAGS_TRUE}" ]; then | |
275 case ${WORKON_CMD} in | |
276 start) ATOM_LIST=$(show_workon_ebuilds ${BOARD_KEYWORD});; | |
277 stop|iterate) ATOM_LIST=$(show_live_ebuilds);; | |
278 list) ;; | |
279 *) die "--all is invalid for the given command";; | |
280 esac | |
281 else # not selected --all | |
282 case ${WORKON_CMD} in | |
283 start|stop|iterate) | |
284 ATOM_LIST=$@ | |
285 if [ -z "${ATOM_LIST}" ]; then | |
286 die "${WORKON_CMD}: No packages specified" | |
287 elif ! ATOM_LIST=$(canonicalize_names "${ATOM_LIST}"); then | |
288 die "Error parsing package list" | |
289 fi;; | |
290 *) ;; | |
291 esac | |
292 fi | |
293 | |
294 case ${WORKON_CMD} in | |
295 start) ebuild_to_live "${ATOM_LIST}" ;; | |
296 stop) ebuild_to_stable "${ATOM_LIST}" ;; | |
297 list) [ ${FLAGS_all} = "${FLAGS_FALSE}" ] && show_live_ebuilds || \ | |
298 show_workon_ebuilds ${BOARD_KEYWORD} ;; | |
299 list-all) show_all_live_ebuilds ;; | |
300 iterate) ebuild_iterate "${ATOM_LIST}" ;; | |
301 *) die "$(basename $0): command '${WORKON_CMD}' not recognized" ;; | |
302 esac | |
OLD | NEW |