| 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 |