Remove cros_workon implementation

Leave a helpful hint to developers to update their chroot if haven't
rebuilt their chroot recently.

BUG=brillo:817
TEST=exit chroot, enter chroot, cros_workon list-all works

CQ-DEPEND=CL:266773
Change-Id: I6f7fc646cde0062526feaba6b6fd5023ab8d4576
Reviewed-on: https://chromium-review.googlesource.com/266753
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
Tested-by: Christopher Wiley <wiley@chromium.org>
diff --git a/cros_workon b/cros_workon
index 5169017..4ba50a5 100755
--- a/cros_workon
+++ b/cros_workon
@@ -4,484 +4,7 @@
 # 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.
-
-. "$(dirname "$0")/common.sh" || exit 1
-
-assert_not_root_user
-
-# Script must be run inside the chroot
-
-DEFINE_string board "${DEFAULT_BOARD}" \
-  "The board to set package keywords for."
-DEFINE_string brick "" \
-  "The brick to set package keywords for."
-DEFINE_boolean host "${FLAGS_FALSE}" \
-  "Uses the host instead of board"
-DEFINE_string remote "" \
-  "For non-workon projects, the git remote to use."
-DEFINE_string revision "" \
-  "Use to override the manifest defined default revision used for a project"
-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"
-DEFINE_boolean workon_only "${FLAGS_FALSE}" \
-  "Apply to packages that have a workon ebuild only"
-
-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)
-  info:      Print package name, repo name, and source directory.
-  list:      List of live ebuilds (workon ebuilds if --all)
-  list-all:  List all of the live ebuilds for all setup boards
-  iterate:   For each ebuild, cd to the source dir and run a command"
-FLAGS "$@" || { [ "${FLAGS_help}" = "${FLAGS_TRUE}" ]  && exit 0; } || exit 1
-eval set -- "${FLAGS_ARGV}"
-
-
-# eat the workon command keywords: start, stop or list.
-WORKON_CMD=$1
-shift
-
-# Board dir config
-
-# --host takes precedence over --{brick,board}; --brick takes precedence over
-# --board. This preserves prior behavior meant to accommodate default values.
-if [[ "${FLAGS_host}" == ${FLAGS_TRUE} ]]; then
-  if [[ -n "${FLAGS_board}" ]] || [[ -n "${FLAGS_brick}" ]]; then
-    warn "--host was used, ignoring --brick and --board values"
-    FLAGS_brick=""
-    FLAGS_board=""
-  fi
-elif [[ -n "${FLAGS_brick}" ]]; then
-  # Override board name with the brick's friendly name (backward compatibility).
-  [[ -z "${FLAGS_board}" ]] || warn "--brick was used, ignoring --board value"
-  FLAGS_board="$(cros_brick_utils --friendly-name "${FLAGS_brick}")"
-  [[ -n "${FLAGS_board}" ]] || die_notrace
-fi
-
-if [ -z "${FLAGS_board}" ] && \
-   [ "${FLAGS_host}" = ${FLAGS_FALSE} ] && \
-   [ "${WORKON_CMD}" != "list-all" ]; then
-  flags_help
-  die "You must specify either --host, --board or --brick"
-fi
-
-if [ -n "${FLAGS_board}" ]; then
-  BOARD_DIR=/build/"${FLAGS_board}" # --board specified
-  EQUERYCMD=equery-"${FLAGS_board}"
-  EBUILDCMD=ebuild-"${FLAGS_board}"
-  PORTAGEQCMD=portageq-"${FLAGS_board}"
-  BOARD_STR="${FLAGS_board}"
-else
-  BOARD_DIR="" # --host specified
-  EQUERYCMD=equery
-  EBUILDCMD=ebuild
-  PORTAGEQCMD=portageq
-  BOARD_STR="host"
-fi
-
-WORKON_DIR="${CHROOT_TRUNK_DIR}/.config/cros_workon"
-CONFIG_DIR="${BOARD_DIR}/etc/portage"
-KEYWORDS_DIR="${CONFIG_DIR}/package.keywords"
-MASK_DIR="${CONFIG_DIR}/package.mask"
-UNMASK_DIR="${CONFIG_DIR}/package.unmask"
-WORKON_FILE="${WORKON_DIR}/${BOARD_STR}"
-MASK_WORKON_FILE="${WORKON_FILE}.mask"
-KEYWORDS_FILE="${KEYWORDS_DIR}/cros-workon"
-MASK_FILE="${MASK_DIR}/cros-workon"
-UNMASK_FILE="${UNMASK_DIR}/cros-workon"
-CHROME_ATOM=chromeos-base/chromeos-chrome
-
-mkdir -p "${WORKON_DIR}" || die "mkdir -p ${WORKON_DIR}"
-touch "${WORKON_FILE}" "${MASK_WORKON_FILE}" || \
-  die "touch ${WORKON_FILE} ${MASK_WORKON_FILE}"
-cmds=(
-  "mkdir -p '${KEYWORDS_DIR}' '${MASK_DIR}' '${UNMASK_DIR}'"
-
-  # Clobber and re-create the WORKON_FILE symlinks every time. This
-  # is a trivial operation and eliminates all kinds of corner cases
-  # as well as any possible future renames of WORKON_FILE.
-  # In particular, chroot is usually built as "amd64-host" but becomes
-  # just "host" after installation. crosbug.com/23096
-  "ln -sf '${WORKON_FILE}' '${KEYWORDS_FILE}'"
-  "ln -sf '${MASK_WORKON_FILE}' '${MASK_FILE}'"
-  "ln -sf '${WORKON_FILE}' '${UNMASK_FILE}'"
-)
-# If the board dir doesn't exist yet, we don't want to create it as
-# that'll screw up ./setup_board later on.
-if [[ -d ${BOARD_DIR:-/} ]] ; then
-  sudo_multi "${cmds[@]}"
-else
-  die "${BOARD_STR} has not been setup yet"
-fi
-
-
-find_keyword_workon_ebuilds() {
-  local keyword="${1}"
-  local overlay
-
-  # NOTE: overlay may be a symlink, and we have to use ${overlay}/
-  for overlay in "${OVERLAYS[@]}"; do
-    # Only look up ebuilds named 9999 to eliminate duplicates.
-    # Packages inheriting from cros-workon or chromium-source are considered
-    # workon-able.
-    find "${overlay}"/*-* -maxdepth 2 -type f -name '*9999.ebuild' \
-      -exec egrep -l '^inherit.*\<(cros-workon|chromium-source)\>' {} + \
-      2>/dev/null | xargs egrep -l "KEYWORDS=\".*~([*]|${keyword})[ \"]"
-  done
-}
-
-ebuild_to_package() {
-  # This changes the absolute path to ebuilds into category/package.
-  sed -e 's/.*\/\([^/]*\)\/\([^/]*\)\/.*\.ebuild/\1\/\2/'
-}
-
-show_project_ebuild_map() {
-  local keyword="$1"
-  local project_var
-
-  # Column 1: Repo name
-  # Column 2: Package name
-  for EBUILD in $(find_keyword_workon_ebuilds ${keyword}); do
-    (
-      project_var=$(awk -- \
-        '/CROS_WORKON_PROJECT=/,/CROS_WORKON_PROJECT=[^(]|\)/' "${EBUILD}")
-      # Can only detect syntax errors in subshells; not in our own.
-      if ( eval "${project_var}" ); then
-        eval "${project_var}"
-      else
-        error "From $EBUILD, failed to eval:"
-        error "$project_var"
-        continue
-      fi
-      CP=$(echo "$EBUILD" | ebuild_to_package)
-      projects=$(echo "${CROS_WORKON_PROJECT[@]}" | sed 's/ /,/g')
-      echo "${projects:--}" "${CP}"
-    )
-  done
-}
-
-show_project_path_map() {
-  # Column 1: Repo name
-  # Column 2: Source directory
-  repo list | awk -F ' : ' '{ print $2, $1 }'
-}
-
-show_workon_ebuilds() {
-  local keyword="$1"
-  find_keyword_workon_ebuilds "${keyword}" | ebuild_to_package | sort -u
-}
-
-# Prints only the atoms that have nothing but 9999 ebuilds across all overlays.
-filter_workon_only() {
-  local atoms="$1"
-  local atom
-  local num_ebuilds
-  local overlay
-  for atom in ${atoms}; do
-    num_ebuilds=0
-    for overlay in "${OVERLAYS[@]}"; do
-      num_ebuilds=$(ls -1 "${overlay}"/${atom}/*.ebuild 2>/dev/null | wc -l)
-      [[ "${num_ebuilds}" -gt 1 ]] && break
-    done
-    [[ "${num_ebuilds}" -le 1 ]] && echo ${atom}
-  done
-}
-
-show_workon_info() {
-   local atoms="$1"
-   local keyword="$2"
-   local sort="sort -k1b,1"
-   # Column 1: Package name
-   # Column 2: Repo name
-   # Column 3: Source directory (if present locally)
-   join \
-     <(echo "${atoms}" | sed -e 's/ /\n/g' | ${sort}) \
-     <(join -a 1 -e - -o 1.2,1.1,2.2 \
-       <(show_project_ebuild_map "${keyword}" | ${sort}) \
-       <(show_project_path_map | ${sort}) \
-       | ${sort})
-}
-
-# Canonicalize package name to category/package.
-canonicalize_name() {
-  local pkgfile
-  local pkgname
-
-  if grep -qx "=$1-9999" "${WORKON_FILE}" ; then
-    echo $1
-    return 0
-  fi
-
-  if ! pkgfile=$(ACCEPT_KEYWORDS="~${ARCH}" ${EQUERYCMD} \
-                 which --include-masked $1); then
-    # Try to auto-complete it.
-    local autopkgs=()
-    for pkgname in $(show_workon_ebuilds); do
-      if [[ ${pkgname} == *"$1"* ]]; then
-        autopkgs+=( ${pkgname} )
-      fi
-    done
-    case ${#autopkgs[@]} in
-    0)
-      warn "error looking up package $1" 1>&2
-      return 1
-      ;;
-    1)
-      # Do nothing -- fall through.
-      ;;
-    *)
-      warn "Multiple autocompletes found: ${autopkgs[*]}"
-      ;;
-    esac
-    pkgname=${autopkgs[0]}
-    info "Autocompleted '$1' to: ${pkgname}"
-    canonicalize_name "${pkgname}"
-    return
-  fi
-
-  pkgname=$(echo "${pkgfile}" | awk -F '/' '{ print $(NF-2) "/" $(NF-1) }')
-
-  # TODO(rcui): remove special casing of chromeos-chrome here when we make it
-  # inherit from cros-workon / chromium-source class (chromium-os:19259).
-  if [ "${pkgname}" != "${CHROME_ATOM}" ] && \
-     ! grep -q "^inherit.*\<chromium-source\>" ${pkgfile} && \
-     ! 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=()
-  local atom
-
-  for atom in ${atoms}; do
-    names+=( $(canonicalize_name "${atom}") ) || return 1
-  done
-
-  echo "${names[*]}"
-}
-
-# Locate the package name based on the current directory
-locate_package() {
-  local projectname=$(git config --get remote.cros.projectname ||
-                      git config --get remote.cros-internal.projectname)
-  if [ -z "${projectname}" ]; then
-    die "No project in git config: Can not cros_workon . here"
-  fi
-  local reponame=$(show_project_ebuild_map |
-                   grep "^${projectname} " | cut -d" " -f2)
-  if [ -z "${reponame}" ]; then
-    die "No matching package for ${projectname}: Can not cros_workon . here"
-  else
-    echo "${reponame}"
-  fi
-}
-
-# Display ebuilds currently part of the live branch and open for development.
-show_live_ebuilds() {
-  sed -n 's/^=\(.*\)-9999$/\1/p' "${WORKON_FILE}"
-}
-
-# Display ebuilds currently part of the live branch and open for development
-# for any board that currently has live ebuilds.
-show_all_live_ebuilds() {
-  local workon_file
-  for workon_file in ${WORKON_DIR}/*; do
-    if [[ -s ${workon_file} && ${workon_file} != *.mask ]] ; then
-      echo -e "${V_BOLD_GREEN}$(basename ${workon_file}):${V_VIDOFF}"
-      sed -n 's/^=\(.*\)-9999$/    \1/p' "${workon_file}"
-      echo ""
-    fi
-  done
-}
-
-# This is called only for "cros-workon start". We dont handle the
-# "stop" case since the local changes are ignored anyway since the
-# 9999.ebuild is masked and we dont want to deal with what to do with
-# the user's local changes.
-regen_manifest_and_sync() {
-  # Nothing to do unless you are working on the minilayout
-  local manifest=${CHROOT_TRUNK_DIR}/.repo/manifest.xml
-  if [ $(basename $(readlink -f ${manifest})) != "minilayout.xml" ]; then
-    if [ -z "$(git config -f "${CHROOT_TRUNK_DIR}/.repo/manifests.git/config" \
-               --get manifest.groups)" ]; then
-      # Reaching here means that it's a full manifest w/out any groups set-
-      # literal full manifest.
-      return
-    fi
-  fi
-
-  local need_repo_sync=
-  local pkgname
-  for pkgname in $(show_live_ebuilds); do
-    local pkgpath="$(${EQUERYCMD} which "${pkgname}")"
-    local pkginfo="$(${EBUILDCMD} "${pkgpath}" info |
-                   grep -v 'pkg_info() is not defined')"
-    if [ -z "${pkginfo}" ]; then
-      continue  # No package information available
-    fi
-
-    eval "${pkginfo}"
-    local trunkdir=$(readlink -m "${CHROOT_TRUNK_DIR}")
-
-    local i
-    for (( i=0; i < ${#CROS_WORKON_SRCDIR[@]}; ++i )); do
-      [ -z "${CROS_WORKON_PROJECT[i]}" ] && continue
-      need_repo_sync='yes'
-      local srcdir=$(readlink -m "${CROS_WORKON_SRCDIR[i]}")
-      local revision="${FLAGS_revision:+--revision=${FLAGS_revision}}"
-      if [ -z "${FLAGS_remote}" ]; then
-        loman add --workon "${CROS_WORKON_PROJECT[i]}" ${revision}
-      else
-        loman add --remote "${FLAGS_remote}" ${revision} \
-          "${CROS_WORKON_PROJECT[i]}" "${srcdir#${trunkdir}/}"
-      fi
-    done
-  done
-  if [ -n "${need_repo_sync}" ]; then
-    echo "Please run \"repo sync\" now."
-  fi
-}
-
-# 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
-  local atoms_success=()
-  local atom
-
-  for atom in ${atoms}; do
-    if ! grep -qx "=${atom}-9999" "${WORKON_FILE}" ; then
-      echo "=${atom}-9999" >> "${WORKON_FILE}" || \
-        die "Could not update ${WORKON_FILE} with ${atom}"
-      echo "<${atom}-9999" >> "${MASK_WORKON_FILE}" || \
-        die "Could not update ${MASK_WORKON_FILE} with ${atom}"
-      atoms_success+=( ${atom} )
-    else
-      warn "Already working on ${atom}"
-    fi
-  done
-  if [ ${#atoms_success[@]} -gt 0 ]; then
-    regen_manifest_and_sync
-    info "Started working on '${atoms_success[*]}' for '${BOARD_STR}'"
-  fi
-}
-
-# Move a live development ebuild back to stable.
-ebuild_to_stable() {
-  local atoms=$1
-  local atoms_success=()
-  local atom
-
-  for atom in ${atoms}; do
-    if grep -qx "=${atom}-9999" "${WORKON_FILE}" "${MASK_WORKON_FILE}" ; then
-      sed -i -e "/^=${atom/\//\\/}-9999\$/d" "${WORKON_FILE}" || \
-        die "Could not update ${WORKON_FILE} with ${atom}"
-      sed -i -e "/^<${atom/\//\\/}-9999\$/d" "${MASK_WORKON_FILE}" || \
-        die "Could not update ${WORKON_FILE} with ${atom}"
-      atoms_success+=( ${atom} )
-    else
-      warn "Not working on ${atom}"
-    fi
-  done
-  if [ ${#atoms_success[@]} -gt 0 ]; then
-    info "Stopped working on '${atoms_success[*]}' for '${BOARD_STR}'"
-  fi
-}
-
-# Run a command on all or a set of repos.
-ebuild_iterate() {
-  local atoms=$1
-  local atom
-
-  for atom in ${atoms}; do
-    info "Running \"${FLAGS_command}\" on ${atom}"
-    eval $(${EBUILDCMD} $(${EQUERYCMD} which ${atom}) info)
-    for S in "${CROS_WORKON_SRCDIR[@]}"; do
-      (cd "${S}" && bash -c "${FLAGS_command}")
-    done
-  done
-}
-
-unset use_list
-[[ ${FLAGS_workon_only} = ${FLAGS_TRUE} ]] && use_list="--workon_only"
-[[ ${FLAGS_all} = ${FLAGS_TRUE} ]] && use_list="--all"
-
-# Only call portageq when absolutely required, and when we do, only run it
-# once -- it's a slow beast and can easily take hundreds of milliseconds :(.
-if [[ ${WORKON_CMD} != "list" || -n "${use_list}" ]] ; then
-  ARCH=$(${PORTAGEQCMD} envvar ARCH)
-  cmd=( cros_list_overlays )
-  if [[ -n "${FLAGS_brick}" ]]; then
-    cmd+=( --brick "${FLAGS_brick}" )
-  else
-    cmd+=( --all )
-    if [[ -n "${FLAGS_board}" ]]; then
-      cmd+=( --board "${FLAGS_board}" )
-    fi
-  fi
-  OVERLAYS=( $("${cmd[@]}") )
-fi
-
-# --all and --workon_only make commands operate on different lists.
-if [[ -n "${use_list}" ]]; then
-  case ${WORKON_CMD} in
-    start|info|list)
-      ATOM_LIST=$(show_workon_ebuilds ${ARCH})
-      if [[ "${use_list}" = "--workon_only" ]]; then
-        ATOM_LIST=$(filter_workon_only "${ATOM_LIST}")
-      fi;;
-    stop|iterate)
-      ATOM_LIST=$(show_live_ebuilds)
-      if [[ "${use_list}" = "--workon_only" ]]; then
-        ATOM_LIST=$(filter_workon_only "${ATOM_LIST}")
-      fi;;
-    *) die "${use_list} is invalid for the given command";;
-  esac
-else
-  case ${WORKON_CMD} in
-    start|stop|info|iterate)
-      ATOM_LIST=$@
-      if [ -z "${ATOM_LIST}" ]; then
-        die "${WORKON_CMD}: No packages specified"
-      fi
-      if [ "${ATOM_LIST}" = "." ]; then
-        ATOM_LIST=$(locate_package)
-      fi
-      if ! 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}" ;;
-  info) show_workon_info "${ATOM_LIST}" "${ARCH}" ;;
-  list)
-    if [[ -n "${use_list}" ]]; then
-      for atom in ${ATOM_LIST}; do echo ${atom}; done
-    else
-      show_live_ebuilds
-    fi;;
-  list-all) show_all_live_ebuilds ;;
-  iterate) ebuild_iterate "${ATOM_LIST}" ;;
-  *)
-    flags_help
-    die "$(basename $0): command '${WORKON_CMD}' not recognized"
-    ;;
-esac
+# TODO(wiley) Remove this on July 20 2015.
+echo 'The logic in this script has moved.'
+echo 'Please run `/mnt/host/source/src/scripts/update_chroot`'
+exit 1