info-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: preventing commits on branches


From: Don J. Norton
Subject: RE: preventing commits on branches
Date: Fri, 2 May 2003 09:28:43 -0700

|-----Original Message-----
|From: address@hidden [mailto:address@hidden
|Sent: Friday, May 02, 2003 5:26 AM
|To: address@hidden
|Subject: preventing commits on branches
|
|
|Does anyone have any example scripts (preferably perl) which can be
|activated via the commitinfo hook and which can prevent 
|commits to specific
|branches / by specific people / a combination of both.  If no scripts
|available, any advice on this topic would be appreciated.
|
|Jason Gibbons

Hi Jason,

I had a similar need, and with the help of a generous person on
this list, was able to develop just such a beast.  It isn't 
written in perl (shell script), and it is somewhat rudimentary,
but it may serve your needs anyway.

I believe it would be quite useful if this model, or one similar
to it, were built-in to the cvs distribution.

The precommit_check utility uses three control files to...
        1) Not ever allow check-ins from specific users 
                (I use this to prevent check-ins from anonymous
                 internal accounts).
        2) Specify a list of people who are allowed to check
                in changes to a specific branch or the HEAD.
        3) Specify a list of branches to lock completely
                (this is useful as a "breaker" switch, to 
                 temporarily turn on/off access all the "approved" 
                 people without having to reconstruct list #2
                 each time).

Finally, the precommit_check script itself uses all three
control files to perform commit-time validation and prevents
check-in if all the necessary criteria are not met.

What I have not done in this is leverage module definitions
in any way.  If anyone finds this useful enough to do so, I
would appreciate a return of the improvements.

Hope you find this useful.

-Don Norton

PS:  The "PS" prefixes are an abbreviation of my company
name (PolyServe).  I'm sure you'll want to remove/modify
those.

======================================== cut here ===========================
# ================= PS_restricted_accounts
# 
# List all accounts which are prohibited from performing commit operations
#

build
qa

======================================== cut here ===========================
# ================= PS_branch_access
#
# The format of this file is as follows:
#
# branchname:   user1 user1
#
# For an entry to be effective, the first character must be the beginning
# of the branch name.  Everything following the colon should be a 
# space-separated list of valid users.  All users authorized to change
# the branch in question must be on one line.  The absence of a branch
# name here results in no per-user restrictions.
#
# Comment lines should start with '#' for consistency and namespace
# protection from cvs branch tag names.
#

project_HEAD:    joe bob frank 
project-branch1:     mike tim nancy cheryl

======================================== cut here ===========================
# ================= PS_branch_locks 
#
# This file should include a list of all branches in which commit
# operations are currently restricted.  Commenting out (prefixing 
# with a "#" removes the branch lock.
#
# Artificial branch names consisting of the top-level CVS directory
# appended with "_HEAD" are supported.
# For example, /CVS/klondike maps to a branch name of klondike_HEAD.
#

#project-branch1
project_HEAD


======================================== cut here ===========================

#!/bin/bash
#
# Exits non-zero if the requested check-in shouldn't be allowed,
# for whatever reasons deemed appropriate by this script.
#
# Checks for the following are currently implemented:
#
#       Invalid anonymous id
#       Branches being locked 
#       Valid developer on a per-branch basis

CVSSUPPORT=`dirname $0`
RESTRICTED=${CVSSUPPORT}/PS_restricted_accounts
BRANCHACCESS=${CVSSUPPORT}/PS_branch_access
BRANCHLOCKS=${CVSSUPPORT}/PS_branch_locks

# List of people to bug if the check-in fails
bug_people="cvsadmin"

# List of branches for which check-ins are not currently allowed
locked_branches=`cat ${BRANCHLOCKS} | grep -v "^#"`

control_file_check()
{
        if [[ ! -f ${BRANCHACCESS} ]]; then
                echo Fatal error: ${BRANCHACCESS} file not found
                echo Contact ${bug_people} for assistance
                exit 1
        fi
}

no_anonymous_id ()
{
        # Confirm the user is not one of the various anonymous accounts
        # to help ensure tracability of the change being made.

        account="$(id -un)"

        grep -n "^${account}" ${RESTRICTED}
        if [[ $? -eq 0 ]]; then
                # Account name found in restricted list
                echo " "
                echo " ********** Warning ********** "
                echo " ******* Commit Failed ******* "
                echo " "
                echo "CVS commit not allowed by anonymous account $account"
                echo " "
                echo " ******* Commit Failed ******* "
                echo " ********** Warning ********** "
                echo " "
                return 1
        fi
        return 0
}

validate_user_on_branch()
{
        local branch=$1

        # Confirm this user is allowed to make changes to this branch
        account="$(id -un)"

        grep -n "^${branch}" ${BRANCHACCESS}
        if [[ $? -eq 1 ]]; then
                # No controlled branch found
                echo Branch \"${branch}\" is not under per-user access control
                return 0
        fi

        userlist=`grep "^${branch}" ${BRANCHACCESS} | sed 's/^.*://'`

        for user in ${userlist}
        do
                if [[ ${account} = ${user} ]]; then
                        echo User \"${account}\" authorized to modify branch 
\"${branch}\"
                        return 0
                fi
        done

        # Valid user not found - return error
        echo User \"${account}\" is not authorized to modify branch 
\"${branch}\"
        return 1
}

validate_branch ()
{
        # Process each file to be checked into cvs
        for file in $@
        do
                # Get branch info from CVS/Entries file 
                #
                # Note for the faint of heart:  the relevant lines in the
                # CVS/Entries file are transferred from the user's working
                # repository to the server where this script is executed
                # during a commit.  This allows the following action to 
                # succeed.

                branch=`grep "^/${file}/" CVS/Entries | awk -F/ '{print $NF}' | 
cut -c2-`
                if [[ ${branch} = "" ]]; then
                        branch=HEAD
                        repository=`cat CVS/Repository | awk -F/ '{print $3}'`
                        branch=${repository}_HEAD
                        echo file \"${file}\" is implicitly on ${branch}
                else
                        echo file \"${file}\" is on branch \"${branch}\"
                fi
                validate_user_on_branch ${branch} || exit 1

                for br in ${locked_branches}
                do
                        if [[ ${branch} = $br ]]; then
                                # Branch locked - notify user and return failure
                                echo " "
                                echo " ********** Warning ********** "
                                echo " ******* Commit Failed ******* "
                                echo " "
                                echo "Branch ${branch} is closed for commits "
                                echo "Please contact one of the following 
before proceeding: ${bug_people}"
                                echo " "
                                echo " ******* Commit Failed ******* "
                                echo " ********** Warning ********** "
                                return 1
                        fi
                done
        done
        # No matching locked branches - return success
        return 0
}

#
#===============================================================================
#

#echo $0 args: \"address@hidden"

# Confirm control files exist
control_file_check

# Confirm user is not an anonmous id
no_anonymous_id || exit 1

# Shift off directory name (first argument), leaving only file names to process
shift

# Confirm the target branch is not locked
validate_branch $@ || exit 1

exit 0





reply via email to

[Prev in Thread] Current Thread [Next in Thread]