#!/bin/bash -e #Assists sparse checkouts of an ICEDUST package / project #set -x ############################################################################## # Pre-setup ############################################################################## case `uname` in Darwin) ECHO=echo ;; *) ECHO="echo -e" ;; esac usage () { $ECHO "git icedust-add [options] SubSystem/Package" $ECHO "git icedust-add [options] -f FILE" $ECHO $ECHO "Options:" $ECHO "-h, --help \tthis help message" $ECHO $ECHO "-t, --thorough \tSwitch off speed-increasing measures that may cause packages to be improperly checked out" $ECHO "-D, --depend \tcheck for dependencies and check them out too" $ECHO "-d, --debug \tenable debug output" $ECHO "-f, --file FILE \tread the list of packages to be checkoed out from FILE" $ECHO "-q, --quiet, -z \tdo not print out progress" $ECHO "--skip-setup \tdon't run git icedust-setup, useful when used in other scripts" exit $1 } VERBOSE=1 VERBOSE_STREAM=/dev/stderr DEBUG_STREAM=/dev/null RED='\033[31m' NORMAL='\033[0m' verbose () { if [ "X$VERBOSE" = X1 ]; then $ECHO "$@" fi } case `git --version` in git\ version\ 1.7*) # git 1.7.x does not support a leading slash in .gitignore and .git/info/sparse-checkout LEADING_SLASH= ;; *) LEADING_SLASH=/ ;; esac ############################################################################## # Parse options ############################################################################## ReadFile(){ InFile="$1" PACKAGES=( `grep -ve '^\s*#' "$InFile" | tr '\r\n' ' ' ` "${PACKAGES[@]}" ) } INITOPTIONS="" PACKAGES=( ) CHECK_DEPS=false BeThorough=false while [ "$#" != 0 ]; do case "$1" in -h | --help ) usage 0;; -t | --thorough ) INITOPTIONS="$INITOPTIONS $1" shift; BeThorough=true;; -d | --debug ) INITOPTIONS="$INITOPTIONS $1" shift; set -x; DEBUG_STREAM=/dev/stderr ;; -D | --depend ) CHECK_DEPS=true; shift;; -f | --file ) OPTION=$1; shift INPUT_FILE="$1"; shift if [ ! "$INPUT_FILE" ]; then $ECHO "git icedust-add: option $OPTION requires an argument" $ECHO usage 1 elif [ ! -r "$INPUT_FILE" ]; then $ECHO "git : file $INPUT_FILE does not exist or is not readable" $ECHO usage 1 fi ReadFile "$INPUT_FILE" unset OPTION ;; -q | --quiet | -z ) INITOPTIONS="$INITOPTIONS $1" shift; set +x; VERBOSE=0; VERBOSE_STREAM=/dev/null ;; --skip-init) SKIP_INIT=true; shift;; -*) $ECHO Unknown option $1 ; usage 1 ;; *) PACKAGES=( "$1" "${PACKAGES[@]}" ) shift ;; esac done if [ "${#PACKAGES[@]}" -lt 1 ] ; then $ECHO "Error: You need to specify at least one package or input file." usage 1 fi ############################################################################## # Check we're setup properly ############################################################################## export ICEDUST_HOME export ICEDUST_PROJECT if [ -z "$INTERNAL_CALL_CHECKDEPS" ];then tmp="`git icedust-home "$ICEDUST_HOME" "$ICEDUST_PROJECT"||true`" # Check if there was an issue getting the variables if grep 'Error' <<< "$tmp" &> "$DEBUG_STREAM" ;then $ECHO $tmp $ECHO "icedust-add: Error: Problem with ICEDUST_HOME and ICEDUST_PROJECT variables (see above messge)." $ECHO "Current values: " $ECHO " ICEDUST_HOME=$ICEDUST_HOME" $ECHO " ICEDUST_PROJECT=$ICEDUST_PROJECT" exit 1 fi ICEDUST_HOME=`sed 's!^.*ICEDUST_HOME=\([^;]\+\);.*!\1!' <<<$tmp` ICEDUST_PROJECT=`sed 's!^.*ICEDUST_PROJECT=\([^;]\+\);.*!\1!' <<<$tmp` unset tmp fi PackageDirectory="$ICEDUST_HOME/$ICEDUST_PROJECT/packages" ExternalDirectory="$PackageDirectory/EXTERNALS" if [ -z "$INTERNAL_CALL_CHECKDEPS" ];then ProjectCmtDirectory="$ICEDUST_HOME/$ICEDUST_PROJECT/cmt" for dir in "$PackageDirectory"/.git "$ExternalDirectory"/.git "$ProjectCmtDirectory";do if ! [ -d "$dir" ]; then $ECHO "Error: Please run git icedust-setup first" exit 1 fi done fi echo ICEDUST_HOME=$ICEDUST_HOME >$DEBUG_STREAM echo ICEDUST_PROJECT=$ICEDUST_PROJECT >$DEBUG_STREAM cd "$PackageDirectory" ############################################################################## # Are the local, staged changes ############################################################################## if [ -z "$INTERNAL_CALL_CHECKDEPS" ];then if [ "$(git status --porcelain --untracked=no | grep '^[ACDMRU]')" ]; then $ECHO "${RED}Error:${NORMAL} there are staged but not committed changes on your working tree, please commit or stash them." exit 1 fi fi ############################################################################## # Check out the packages ############################################################################## verbose "Checking out package(s) ${PACKAGES[@]}" # copy the file so we can prepare the new version based on the original cp -f "$PackageDirectory/.git/info/sparse-checkout" "$PackageDirectory/.git/info/sparse-checkout-new" cp -f "$ExternalDirectory/.git/info/sparse-checkout" "$ExternalDirectory/.git/info/sparse-checkout-new" RequirementsFile="$ICEDUST_HOME/$ICEDUST_PROJECT/cmt/requirements" for Package in "${PACKAGES[@]}";do # Do we already have this package? if ! $BeThorough && ( [ -d "$PackageDirectory/$Package" ] || [ -d "$ExternalDirectory/$Package" ] ) ; then continue ;fi # prepare the line to go into the file Line="`$ECHO "$Package" | sed -e "s|[/]*$|/|;s|^/*|${LEADING_SLASH}|"`" IsGood=true if [ -n "`cd "$PackageDirectory" && git ls-files "$Package" `" ];then $ECHO $Line>> "$PackageDirectory/.git/info/sparse-checkout-new" elif [ -n "`cd "$ExternalDirectory" && git ls-files "$Package" `" ];then $ECHO $Line>> "$ExternalDirectory/.git/info/sparse-checkout-new" else $ECHO "icedust-add: Error: Unknown package: $Package" IsGood=false fi #If this script was invoked by the user, prepare the Project's requirements file if [ -z "$INTERNAL_CALL_CHECKDEPS" ] && $IsGood && \ ! grep '^\s*use\s*'$Package "$RequirementsFile" > $DEBUG_STREAM ;then $ECHO "use $Package" >> "$RequirementsFile" fi done # Remove duplicate entries as we update the old spare-checkout file for dir in "$PackageDirectory" "$ExternalDirectory";do ( cd "$dir" cat .git/info/sparse-checkout-new | sort -u > .git/info/sparse-checkout # Tidy up rm -f .git/info/sparse-checkout-new # Actually tidy up the working index git read-tree -m -u HEAD ) done CURRENT_BRANCH=`basename $(git symbolic-ref -q HEAD)` cd "$PackageDirectory" # Check that we really got all packages for Package in "${PACKAGES[@]}";do if [ ! -d "$PackageDirectory/$Package" ]; then if [ ! -d "$ExternalDirectory/$Package" ]; then $ECHO "package $Package does not exist in branch $CURRENT_BRANCH" fi fi done ############################################################################## # Check all dependencies ############################################################################## if $CHECK_DEPS;then export INTERNAL_CALL_CHECKDEPS="YES" git icedust-check $INITOPTIONS --skip-init -H "$ICEDUST_HOME" fi