#!/bin/bash # # Check/enforce the validity of tags we apply # WARNING: # This file is maintained under $CVSROOT/CVSROOT/admin via CVS. # All changes to the plaintext copy on the CVS server will be lost. # $Id: tag-check,v 1.23 2008/04/14 16:37:37 ausil Exp $ # The root of the rpms directory on the filesystem RPMSROOT="${CVSROOT}/rpms" DEVELROOT="${CVSROOT}/devel" REPOROOT="/repo/extras" # $1 -- tagname # $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d # $3 -- repository # $4-> file revision [file revision ...] # parse arguments TAGNAME=$1 shift OPERATION=$1 shift REPOSITORY=$1 shift FILEREVS="$@" # XXX: debug #echo $@ # The repository must start with the $RPMSROOT or $DEVELROOT if [ "${REPOSITORY##${RPMSROOT}}" = "${REPOSITORY}" ] ; then # not $RPMSROOT if [ "${REPOSITORY##${DEVELROOT}}" = "${REPOSITORY}" ] ; then # not $DEVELROOT either echo "ERROR: This script can only deal with modules from ${RPMSROOT} and ${DEVELROOT}" >&2 exit -1 fi ON_DEVEL="yes" # else, we are in the $DEVELROOT BRANCH="devel" MODDIR=$(echo "${REPOSITORY##${DEVELROOT}}" | sed -e 's,/, ,g') # extract the module name and the branch MODULE=$(echo ${MODDIR} | awk '{print $1}') SUBDIR=$(echo ${MODDIR} | awk '{print $2}') else ON_RPMS="yes" # We expect the repositories to be (at least) 2 levels deep under $RPMSROOT # in the form of module_name/branch MODDIR=$(echo "${REPOSITORY##${RPMSROOT}}" | sed -e 's,/, ,g') # extract the module name and the branch MODULE=$(echo ${MODDIR} | awk '{print $1}') BRANCH=$(echo ${MODDIR} | awk '{print $2}') SUBDIR=$(echo ${MODDIR} | awk '{print $3}') fi # if we operate on a subdirectory of a particular branch these tag # checks and operations do not apply if [ -n "${BRANCH}" -a -n "${SUBDIR}" ] ; then exit 0 fi # we better hope the CVSROOT is saved in the environment TAGFILE="${CVSROOT}/tags/${MODULE}" # check if we are operating in a branch CheckBranch() { # we can not accept an empty branch for tagging # (ie, don't tag in the root of the module) if [ -z "${BRANCH}" ] ; then echo "ERROR: creating module-wide tags is prohibited" >&2 exit 2 fi } # check the tag validity VALID=0 # avoid getting into the 4Suite trap CHECK_NAME="$(echo ${MODULE} | sed -e 's/\./_/g' -e 's/^[0-9]\+//g')" case ${TAGNAME} in # show a list of all the tags show ) if [ -f ${TAGFILE} ] ; then echo "The following tags have been created for the module ${MODULE}" cat ${TAGFILE} echo else echo "No tags have been found for the module ${MODULE}" echo fi #echo "(the following error is caused intentionally to avoid creating a 'show' tag)">&2 #exit 1 exit 0 ;; setup-new-module ) echo "WARNING: Your cvs-import.sh script is OUT OF DATE" >&2 exit 0 ;; # we allow all operations on the private-* tags. Exit OK private-* ) CheckBranch exit 0 ;; ${CHECK_NAME}-*-* ) CheckBranch # check n-v-r format if echo "${TAGNAME}" | egrep '(.*)-([^-]+)-([^-]+)' >/dev/null 2>/dev/null ; then VALID=1 else echo "ERROR: Tag ${TAGNAME} is not in name-version-release format" >&2 exit -1 fi # check that the "n" matches the rpm name from the repository # It fucking blows that I have to write the same goddamn regex differently for egrep and sed TEST_NAME="$(echo ${TAGNAME} | sed -e 's/\(.*\)-\([^-]\+\)-\([^-]\+\)/\1/')" if [ "${TEST_NAME}" = "${CHECK_NAME}" ] ; then VALID=1 else echo "ERROR: Tag ${TAGNAME} has not been created from package name ${MODULE}" >&2 exit -1 fi ;; # branch starting tags RHL-8-start | RHL-9-start | \ OLPC-2-start | OLPC-3-start | \ EL-4-start | EL-5-start | \ FC-1-start | FC-2-start | FC-3-start | FC-4-start | FC-5-start | \ FC-6-start | F-7-start | F-8-start | F-9-start ) # Adding these tags is allowed without any further checks. # Moving and deleting are prohibited CheckBranch if [ "${OPERATION}" = "add" ] ; then exit 0 else echo "ERROR: Tag operation '${OPERATION}' is not allowed on tag ${TAGNAME}" >&2 exit -2 fi # noop VALID=1 ;; # branch spliting tags - these ones sit on the devel branch to tell # us where various releases have split away from the trunk RHL-8-split | RHL-9-split | \ OLPC-2-split | OLPC-3-split | \ EL-4-split | EL-5-split | \ FC-1-split | FC-2-split | FC-3-split | FC-4-split | FC-5-split | \ FC-6-split | F-7-split | F-8-split | F-9-split ) # Adding these tags is allowed without any further checks. # Moving and deleting are prohibited CheckBranch if [ "${OPERATION}" = "add" ] ; then exit 0 else echo "ERROR: Tag operation '${OPERATION}' is not allowed on tag ${TAGNAME}" >&2 exit -2 fi # noop VALID=1 ;; * ) VALID=0 ;; esac # in theory this should be a noop, but who knows how the above case # statement will grow... if [ ${VALID} -eq 0 ] ; then echo "ERROR: Tag ${TAGNAME} is not in a valid tag format" >&2 exit -1 fi # we better hope the CVSROOT is saved in the environment TAGFILE="${CVSROOT}/tags/${MODULE}" AddTag() { # add this tag echo "${TAGNAME}:${BRANCH}:${USER}:$(date '+%s')" >> ${TAGFILE} } case ${OPERATION} in del ) # first, we don't allow removal of regular tags. The special cases # should have been handled in the case statement above if [ "${OPERATION}" = "del" ] ; then echo "ERROR: Tag removal not allowed for tag ${TAGNAME}" exit -3 fi ;; add ) # check that this is indeed a new tag. if [ ! -f ${TAGFILE} ] ; then touch ${TAGFILE} chmod 664 ${TAGFILE} AddTag exit 0 fi # extract what we have already in the tags file OLDTAG=$(egrep "^${TAGNAME}:" ${TAGFILE} 2>/dev/null | cut -d':' -f1-2 | sort | uniq) if [ -z "${OLDTAG}" ] ; then # nothing there, we don't have the tag AddTag exit 0 fi # for the cvs import we hardcode this to allow everything we need if [ "${USER}" = "cvsdist" ] ; then echo "WARNING: allowing illegal tagging for import's sake" exit 0 fi # try to be hepful in the error messages if egrep "^${TAGNAME}:${BRANCH}:" ${TAGFILE} >/dev/null 2>/dev/null ; then # tag exists, operation DENIED echo "ERROR: Tag ${TAGNAME} has been already created." >&2 echo "The following tags have been created so far" >&2 else echo "ERROR: The tag ${TAGNAME} is already applied on a different branch" >&2 echo "ERROR: You can not forcibly move tags between branches" >&2 fi cat ${TAGFILE} >&2 exit -4 ;; mov ) # check that we have this tag first. We are stricter than regular CVS, # because we do not allow to forcibly create a new tag through a mov # operation. In this case 'mov' will only move an actual tag, not # create a new one. if it does not exist if [ ! -f ${TAGFILE} ] ; then echo "ERROR: No tags are available for module ${MODULE}" >&2 exit -4 fi # check that this tagname is available for the same branch if egrep "^${TAGNAME}:${BRANCH}:" ${TAGFILE} >/dev/null 2>/dev/null ; then # tag exists, for now we record every time it gets re-applied echo "${TAGNAME}:${BRANCH}:${USER}:$(date '+%s')" >> ${TAGFILE} else # try to be helpful in the error message if egrep "^${TAGNAME}:" ${TAGFILE} >/dev/null 2>/dev/null ; then # does it exist at all? echo "ERROR: The tag ${TAGNAME} is already applied on a different branch" >&2 echo "ERROR: You can not forcibly move tags between branches" >&2 exit -4 fi # else, the tag does not exist at all echo "ERROR: Tag ${TAGNAME} does not exist for module ${MODULE}" >&2 echo "ERROR: You can not move it around unless you create it first" >&2 exit -4 fi ;; * ) echo "ERROR: Unknown operation ${OPERATION} for tag ${TAGNAME}" >&2 exit -5 ;; esac exit 0