Trying to create a pre-commit hook that verify ext

2019-08-30 07:29发布

问题:

I am currently trying to create a pre-commit hook that prevent user to tag a version of code with external that are not tags.

I am just trying to figure out a way to get the external that are specify in a transaction but cant figure out how. The command svnlook dont seem to be able to return anything that remotely look like externals modification. And with the svn command it seem to be the transaction that I am unable to specify. I have no idea what command to use in my pre-commit hook. I am currently in windows but making a python script to be able to test this on our linux server.

What I tested so far is the following :

svnlook propget C:\TestReposLocal svn:externals <== Give me error something is missing

svn propget svn:externals C:\Test    <== Give me externals but I cant figure out how to get this from a transaction to place in a pre-commit hook.

In my repository (C:\TestReposLocal) I have one external that is the trunk of another repository. This repository is displayed with the svn propget command but I need to know with the current transaction in a pre-commit if this external is something else than a Tag.

Any help would be gladly receive.

Tnx

回答1:

Well, I can't see really your trouble-point here

  • Any (almost any) operation in pre-commit hook with transaction (and local repo) can be performed with svnlook
  • svnlook have subcommand propget, with can operate on transaction level and extract any property from any path inside repo (transaction in this case), and you must already know, there you can meet externals inside repo-tree
  • you can identify correct|needed format of externals from any previous revision inside repo

Edit

OK, I see: additional details is needed here. For tests and experimenting I used open repository Proving Ground for externals on Assembla, which have PEG-ed revision in tags and not PEG-ed in trunk. In order to use svnlook locally I just svnrdump'ed it into local repository.

  • Nearest equivalent to getting property from transaction is getting it from committed revision.

Tag 1.0.1 was created with r7

>svnlook pg rep svn:externals tags/1.0.1/ -r 7
-r 2 https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib@2 lib

where:

  1. rep is relative path to repository on local filesystem
  2. tags/1.0.1/ is path inside repository, for which I previously know, that it should have definition
  3. -r 7 is revision, which I want to test

Tag was created from trunk, in which external is not binded to specific revision

>svnlook pg rep svn:externals trunk/ -r 6
https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib lib

You'll have to see difference in specification now

WARNING: format of externals-definition will be different in case of using ancient (pre 1.4) SVN-clients and can be slightly different (can't recall exact details) in case of using CLI-version of SVN or SVN-integration from IDE (definitions above I created with TortoiseSVN), but it will be your part of job

  • I order to apply business logic of hook only when it needed (for commits in /tags only) and finish commits faster, you have also check in hook (at early stages) additional condition - is this commit tag-related or not. It's again svnlook and dirs-changed subcommand

dirs-changed for commit into tags

>svnlook dirs-changed rep -r 7
tags/
tags/1.0.1/

dirs-changed for commit into other location

>svnlook dirs-changed rep -r 6
trunk/

you can |grep tags in good OS, do some tricks in Windows, operate according to results

PS: Don't forget replace -r with -t on production and store transaction-id+repo-path, which you'll get as parameters for hook



回答2:

This just work for me

REPOS="$1"
TXN="$2"

SVNLOOK=svnlook

Grep_In_List()
{
    EX_STATUS=1

    while read line
    do
        echo "$line" | grep "$1" > /dev/null
        if [[ $? == 0 ]]
        then
            echo "$line"
            EX_STATUS=0
        fi
    done

    exit $EX_STATUS
}


CHANGED_PATHS=$($SVNLOOK dirs-changed -t "$TXN" "$REPOS" | Grep_In_List "^tags")

if [[ $? != 0 ]]
then
# no tags
    exit 0
fi

CHANGED_SUB_PATHS=$(echo $CHANGED_PATHS | xargs -I {} $SVNLOOK tree "$REPOS" "{}" --full-paths -t "$TXN" | sort | uniq | xargs -I {} echo "{}\n")
CHANGED_EXTERNALS=$(echo $CHANGED_SUB_PATHS | xargs -I {} $SVNLOOK pg "$REPOS" svn:externals "{}" -t "$TXN" 2>/dev/null | xargs -I {} echo "{}")

while read external
do
    echo "$external" | grep ' -r' > /dev/null
    if [[ $? != 0 ]]
    then
        echo "$external does not have an explicit revision number" 1>&2
        exit 1
    fi
done <<<"$CHANGED_EXTERNALS"

# all tags correct
exit 0