flatcar-scripts/cros_workon
Jon Kliegman 03a4dad734 Whitespace/tab cleanup for cros_workon
Change-Id: I17379dc302fcad0f3a7f59771c48d86df320c0d0

BUG=NONE
TEST=Manual diff inspection.  Ran scripts and confirmed no syntax errors.

Review URL: http://codereview.chromium.org/3335004
2010-09-07 11:12:20 -04:00

277 lines
8.9 KiB
Bash
Executable File

#!/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
# If both are specified, just use host, because board does not
# have to be specified and may come from default, in which case
# there's no way to override.
[ -n "${FLAGS_board}" ] && [ "${FLAGS_host}" = ${FLAGS_TRUE} ] && \
FLAGS_board="" # kill board
[ -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}"
BOARD_STR="${FLAGS_board}"
else
BOARD_DIR="" # --host specified
EQUERYCMD=equery
EBUILDCMD=ebuild
BOARD_STR="host"
fi
WORKON_DIR=${CHROOT_TRUNK_DIR}/.config/cros_workon
KEYWORDS_DIR=${BOARD_DIR}/etc/portage/package.keywords
UNMASK_DIR=${BOARD_DIR}/etc/portage/package.unmask
WORKON_FILE=${WORKON_DIR}/${FLAGS_board:-host}
KEYWORDS_FILE=${KEYWORDS_DIR}/cros-workon
UNMASK_FILE=${UNMASK_DIR}/cros-workon
# TODO(msb): remove the backward compatibility after 09/01/2010
sudo mkdir -p "${WORKON_DIR}" "${KEYWORDS_DIR}" "${UNMASK_DIR}" || \
die "mkdir -p ${WORKON_DIR} ${KEYWORDS_DIR} ${UNMASK_DIR}"
if [ ! -L "${KEYWORDS_FILE}" ]; then
sudo rm -f "${KEYWORDS_FILE}"
sudo ln -s "${WORKON_FILE}" "${KEYWORDS_FILE}" || \
die "ln -s ${WORKON_FILE} ${KEYWORDS_FILE}"
fi
if [ ! -L "${UNMASK_FILE}" ]; then
[ -f "${UNMASK_FILE}" ] && sudo mv "${UNMASK_FILE}" "${WORKON_FILE}"
sudo ln -s "${WORKON_FILE}" "${UNMASK_FILE}" || \
die "ln -s ${WORKON_FILE} ${UNMASK_FILE}"
fi
sudo touch "${WORKON_FILE}" || \
die "touch ${WORKON_FILE}"
# Canonicalize package name to category/package.
canonicalize_name () {
local pkgfile
local pkgname
if ! pkgfile=$(ACCEPT_KEYWORDS="**" ${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 () {
sed -n 's/^[~=]\(.*\)-9999$/\1/p' "${WORKON_FILE}"
}
find_repo_dir () {
curdir=`pwd`
while [ $curdir != / ]; do
if [ -d "$curdir/.repo" ]; then
#echo "Found .repo directory at ${curdir}"
REPODIR=${curdir}/.repo
return 0
fi
curdir=`dirname "$curdir"`
done
echo "Unable to find .repo directory. Did you checkout with repo?"
exit 1
}
# 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() {
find_repo_dir
local_manifest="${REPODIR}/local_manifest.xml"
# ensure we don't clobber existing manifest entries
if [ -f "${local_manifest}" ]; then
grep -q -i "<remote" "${local_manifest}"
if [ $? -ne 1 ]; then
die "Your local manifest will be clobbered running cros_workon. You can not have any <remote> tags at all."
fi
sed -ne '/^[[:space:]]\+[^[:space:]]/q1' "${local_manifest}"
if [ $? -ne 0 ]; then
die "Your local manifest will be clobbered running cros_workon. You can not have any tags that span multiple lines or are indented."
fi
egrep -q "^[^<]" "${local_manifest}"
if [ $? -ne 1 ]; then
die "Your local manifest will be clobbered running cros_workon. You can not have any tags that span multiple lines"
fi
grep -v "<project" "${local_manifest}" | grep -q -i "<project"
if [ $? -eq 0 ]; then
die "Your local manifest has mixed case tags for project. You can not have mixed case tags"
fi
fi
# preserve old manifest entries
[ -f "${local_manifest}" ] && \
MANIFEST_ENTRIES_OLD=$(cat "${local_manifest}" | grep "^<project")
rm -f "${local_manifest}"
# get new manifest entries
MANIFEST_ENTRIES=$(show_live_ebuilds |
{
while read line
do
pkgname=`basename ${line}`
eval $(${EBUILDCMD} $(${EQUERYCMD} which ${pkgname}) info)
REPO_ELEMENT=$(sed -n '/START_MINILAYOUT/,/STOP_MINILAYOUT/p' $REPODIR/manifest.xml | grep "name=\"${CROS_WORKON_PROJECT}\"" | sed -e 's/^[ \t]*//')
echo "$REPO_ELEMENT"
done
})
if [ -n "${MANIFEST_ENTRIES}" ] || [ -n "${MANIFEST_ENTRIES_OLD}" ]; then
info "Creating local manifest for workon packages.."
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" >> "${local_manifest}"
echo "<manifest>" >> "${local_manifest}"
echo -e "${MANIFEST_ENTRIES}\n${MANIFEST_ENTRIES_OLD}" \
| sort | uniq >> "${local_manifest}"
echo "</manifest>" >> "${local_manifest}"
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=""
for atom in ${atoms}; do
if ! grep -qx "[~=]${atom}-9999" "${WORKON_FILE}" ; then
if sudo bash -c "echo \"=${atom}-9999\" >> \"${WORKON_FILE}\""; then
atoms_success="${atoms_success} ${atom}"
fi
else
warn "Already working on ${atom}"
fi
done
[ -n "${atoms_success}" ] && regen_manifest_and_sync && \
info "Started working on '${atoms_success/ /}' for '${BOARD_STR}'"
}
# Move a live development ebuild back to stable.
ebuild_to_stable () {
local atoms=$1
local atoms_success=""
for atom in ${atoms}; do
if grep -qx "[~=]${atom}-9999" "${WORKON_FILE}" ; then
if sudo sed -e "/^[~=]${atom/\//\\/}-9999\$/d" -i "${WORKON_FILE}"; then
atoms_success="${atoms_success} ${atom}"
fi
else
warn "Not working on ${atom}"
fi
done
[ -n "${atoms_success}" ] && \
info "Stopped working on '${atoms_success/ /}' for '${BOARD_STR}'"
}
# 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 "$(basename $0): command '${WORKON_CMD}' not recognized" ;;
esac