| #!/bin/bash |
| |
| # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # This script moves ebuilds between 'stable' and 'live' states. |
| # By default 'stable' ebuilds point at and build from source at the |
| # last known good commit. Moving an ebuild to 'live' (via cros_workon start) |
| # is intended to support development. The current source tip is fetched, |
| # source modified and built using the unstable 'live' (9999) ebuild. |
| |
| # Load common constants. This should be the first executable line. |
| # The path to common.sh should be relative to your script's location. |
| . "$(dirname "$0")/common.sh" |
| |
| # Load common functions for workon scripts. |
| . "$(dirname "$0")/lib/cros_workon_common.sh" |
| |
| # Script must be run inside the chroot |
| restart_in_chroot_if_needed $* |
| get_default_board |
| |
| DEFINE_string board "${DEFAULT_BOARD}" \ |
| "The board to set package keywords for." |
| DEFINE_boolean host "${FLAGS_FALSE}" \ |
| "Uses the host instead of board" |
| DEFINE_string command "git status" \ |
| "The command to be run by forall." |
| DEFINE_boolean all "${FLAGS_FALSE}" \ |
| "Apply to all possible packages for the given command" |
| |
| FLAGS_HELP="usage: $0 <command> [flags] [<list of packages>|--all] |
| commands: |
| start: Moves an ebuild to live (intended to support development) |
| stop: Moves an ebuild to stable (use last known good) |
| list: List of live ebuilds (workon ebuilds if --all) |
| iterate: For each ebuild, cd to the source dir and run a commond" |
| FLAGS "$@" || exit 1 |
| eval set -- "${FLAGS_ARGV}" |
| |
| |
| # eat the workon command keywords: start, stop or list. |
| WORKON_CMD=$1 |
| shift |
| |
| |
| # board dir config |
| [ -n "${FLAGS_board}" ] && [ "${FLAGS_host}" = ${FLAGS_TRUE} ] && \ |
| die "Flags --host and --board are mutually exclusive." |
| [ -z "${FLAGS_board}" ] && [ "${FLAGS_host}" = ${FLAGS_FALSE} ] && \ |
| die "You must specify either --host or --board=" |
| |
| if [ -n "${FLAGS_board}" ]; then |
| BOARD_DIR=/build/"${FLAGS_board}" # --board specified |
| EQUERYCMD=equery-"${FLAGS_board}" |
| EBUILDCMD=ebuild-"${FLAGS_board}" |
| else |
| BOARD_DIR="" # --host specified |
| EQUERYCMD=equery |
| EBUILDCMD=ebuild |
| fi |
| |
| KEYWORDS_DIR=${BOARD_DIR}/etc/portage/package.keywords |
| UNMASK_DIR=${BOARD_DIR}/etc/portage/package.unmask |
| KEYWORDS_FILE=${KEYWORDS_DIR}/cros-workon |
| UNMASK_FILE=${UNMASK_DIR}/cros-workon |
| |
| sudo mkdir -p "${KEYWORDS_DIR}" "${UNMASK_DIR}" || \ |
| die "mkdir -p ${KEYWORDS_DIR} ${UNMASK_DIR}" |
| sudo touch "${KEYWORDS_FILE}" "${UNMASK_FILE}" || \ |
| die "touch ${KEYWORDS_FILE} ${UNMASK_FILE}" |
| |
| # Canonicalize package name to category/package. |
| canonicalize_name () { |
| local pkgfile |
| local pkgname |
| |
| if ! pkgfile=$(${EQUERYCMD} which $1); then |
| warn "error looking up package $1" 1>&2 |
| return 1 |
| fi |
| |
| pkgname=$(\ |
| echo "${pkgfile}" |awk -F '/' '{ print $(NF-2) "/" $(NF-1) }') |
| |
| if ! grep -q "cros-workon" ${pkgfile}; then |
| warn "${pkgname} is not a cros-workon package" 1>&2 |
| return 1 |
| fi |
| echo "${pkgname}" |
| return 0 |
| } |
| |
| # Canonicalize a list of names. |
| canonicalize_names () { |
| local atoms=$1 |
| local names="" |
| |
| for atom in ${atoms}; do |
| local name=$(canonicalize_name "${atom}") |
| [ -n "${name}" ] || return 1 |
| names+=" ${name}" |
| done |
| |
| echo "${names}" |
| } |
| |
| # Display ebuilds currently part of the live branch and open for development. |
| show_live_ebuilds () { |
| cat "${KEYWORDS_FILE}" |
| } |
| |
| # Move a stable ebuild to the live development catgeory. The ebuild |
| # src_unpack step fetches the package source for local development. |
| ebuild_to_live () { |
| local atoms=$1 |
| |
| for atom in ${atoms}; do |
| if ! grep -qx "${atom}" "${KEYWORDS_FILE}" ; then |
| sudo bash -c "echo \"${atom}\" >> \"${KEYWORDS_FILE}\"" |
| sudo bash -c "echo \"~${atom}-9999\" >> \"${UNMASK_FILE}\"" |
| else |
| warn "Already working on ${atom}" |
| fi |
| done |
| } |
| |
| # Move a live development ebuild back to stable. |
| ebuild_to_stable () { |
| local atoms=$1 |
| |
| for atom in ${atoms}; do |
| if grep -qx "${atom}" "${KEYWORDS_FILE}" ; then |
| # remove the keyword |
| sudo bash -c "grep -v '^${atom}\$' \"${KEYWORDS_FILE}\" > \ |
| \"${KEYWORDS_FILE}+\"" |
| sudo mv "${KEYWORDS_FILE}+" "${KEYWORDS_FILE}" |
| # remove the unmask |
| sudo bash -c "grep -v '^~${atom}-9999\$' \"${UNMASK_FILE}\" > \ |
| \"${UNMASK_FILE}+\"" |
| sudo mv "${UNMASK_FILE}+" "${UNMASK_FILE}" |
| else |
| warn "Not working on ${atom}" |
| fi |
| done |
| } |
| |
| # Run a command on all or a set of repos. |
| ebuild_iterate() { |
| local atoms=$1 |
| |
| for atom in ${atoms}; do |
| info "Running \"${FLAGS_command}\" on ${atom}" |
| eval $(${EBUILDCMD} $(${EQUERYCMD} which ${atom}) info) |
| (cd "${CROS_WORKON_SRCDIR}" && bash -c "${FLAGS_command}") |
| done |
| } |
| |
| # --all makes commands operate on different lists |
| if [ ${FLAGS_all} = "${FLAGS_TRUE}" ]; then |
| case ${WORKON_CMD} in |
| start) ATOM_LIST=$(show_workon_ebuilds);; |
| stop|iterate) ATOM_LIST=$(show_live_ebuilds);; |
| list) ;; |
| *) die "--all is invalid for the given command";; |
| esac |
| else # not selected --all |
| case ${WORKON_CMD} in |
| start|stop|iterate) |
| ATOM_LIST=$@ |
| if [ -z "${ATOM_LIST}" ]; then |
| die "${WORKON_CMD}: No packages specified" |
| elif ! ATOM_LIST=$(canonicalize_names "${ATOM_LIST}"); then |
| die "Error parsing package list" |
| fi;; |
| *) ;; |
| esac |
| fi |
| |
| case ${WORKON_CMD} in |
| start) ebuild_to_live "${ATOM_LIST}" ;; |
| stop) ebuild_to_stable "${ATOM_LIST}" ;; |
| list) [ ${FLAGS_all} = "${FLAGS_FALSE}" ] && show_live_ebuilds || show_workon_ebuilds ;; |
| iterate)ebuild_iterate "${ATOM_LIST}" ;; |
| *) die "invalid cros_workon command" ;; |
| esac |