Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2003:
[Freeciv-Dev] commit numbering on the CVS tree (was: (PR#4131) 'make dis
Home

[Freeciv-Dev] commit numbering on the CVS tree (was: (PR#4131) 'make dis

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] commit numbering on the CVS tree (was: (PR#4131) 'make dist' for the daily snapshot)
From: "Reinier Post" <rp@xxxxxxxxxx>
Date: Thu, 15 May 2003 11:39:10 -0700
Reply-to: rt@xxxxxxxxxxxxxx

On Mon, May 05, 2003 at 07:15:15AM -0700, Jason Short wrote:

[...]

> One problem is that the tarball does not have a constant name.  This may 
> make it difficult to just copy the tarball over and use it.  In fact, 
> when you untar the tarball it will give you a directory 
> freeciv-<version>, which is not exactly what we want (but might be 
> okay).  If the CVS had consistent versioning (as discussed on RT), this 
> would be solved.

[...]

I'm sorry, I got stuck on this.  My idea was to let every checkin
generate a version number automatically by making it perform a checkin
itself.  I've been running this for a while, using the attached script,
but it isn't completely robust, there are possible locking problems,
which can largely be avoided by making sure the version number file
is in a separate directory that never gets used for anything else.
Perhaps the CVSROOT/modules file can be used to solve the problem that
the version file must be part of the module that is normally checked out,
but must not be explicitly committable by the user.

The comment in the script makes clear that I'm not sure on whether to
run it from CVS/commitinfo (which is called at the start of the commit)
or CVS/loginfo (which is called at the end).  To work perfectly the
commit should lock out all other operations (including reads) which I
don't think is something that CVS guarantees by itself.  Perhaps a good
workaround is to call the script twice: in commitinfo, to write 
a version number indicating that commit number x has been started,
and in loginfo, writing a version number to indicate that the commit
has been finished.

In short, this just took longer than I thought and I can't promise
to finish it any time soon.  So I'm just posting what I have so far.

-- 
Reinier

#!/bin/sh
#
# cvs-ci-from-cvs - CVS commits the given file to the given local repository
#
# to be used in CVSROOT/loginfo as a means of providing a unique
# version number that representing the state of the whole module

# it turns out that (at least with cvs server 1.11.5) a script
# invoked by loginfo that is called with %s (unquoted!) as its only argument
# obtains the following information:
#
# its first argument is the directory path (starting with the module name)
# its remaining arguments are the names of the files committed
# the $CVSROOT env var contains what you'd expect: the repository address
# the $TMPDIR var is also set (to /tmp)
#
# this is in fact all we need;
# for local commits nothing else is provided; for ssh commits you get
# the additional env vars set by ssh (but the $CVSROOT is still the local
# directory name); for pserver commits I haven't checked yet

# how to use this?
# on your CVS server, in CVSROOT/commitinfo put a line like this:
#
#   ALL     /home/rp/bin/cvs-ci-from-cvs %s
#
# (where the path to this script is modified as appropriate)
#
# this will add or update the file $id_file to the repository
#
# by calling this script in CVSROOT/commitinfo you will get a commit
# of this file for every commit action.  this gives all commits
# a version number.
#
# caveats: in order to avoid locking problems, all incoming commits
# in the $commitinfo's directory are made to fail.  so make sure
# it doesn't point to a directory with any other contents!

#--- config ---#
#

id_file=commitinfo/id
  # a path relative to the module - must not be an absolute path!
  # at this moment, must be a parent of the module dir - cannot be lower!

#
#-- end of config ---#


me=`basename "$0"`

Die() { echo "$me: error: $@" 1>&2; exit 1; }
Tmpnam() { echo $me-$$; }  # not very robust ...

exec > /tmp/$me

case "$1" in "") Die missing second argument ;; esac
dir="$1"
shift

cwd=`/bin/pwd`

echo id_file: $id_file
echo dir: $dir
echo cifiles: $@
echo cwd: $cwd
echo CVSROOT: "$CVSROOT"

exit 0  # tmp kludge against the cvs co bug described below

[ -d "$dir" ] || Die second argument "$dir" is not a directory
[ -d "$CVSROOT" ] || Die \$CVSROOT not set or no directory
case "$dir" in
"$CVSROOT"/*)
  ;;
*)
  Die second argument is no subdir of \$CVSROOT
  ;;
esac

case "$id_file" in
/*)
  Die path to commit id file, '$id_file', must be relative
  ;;
*/*/*)
  Die commit id file, '$id_file', must be in a first-level directory
  ;;
esac

reldir=`echo "$dir" "$CVSROOT" | awk '{print substr($1,2+length($2))}'
`
module=`echo $reldir | sed 's#/.*##'`
echo reldir: $reldir
echo module: $module

id_dir=`dirname $id_file`

if [ X$reldir = X$module/$id_dir ]
then
  # yes, we *will* get called on $id_dir - we call ourselves on it!
  # and all we need to do is to ignore it
  exit 0
fi

tmpcodir=$TMPDIR/`Tmpnam`

mkdir $tmpcodir || Die "cannot create temporary checkout directory '$tmpcodir'"
echo tmpcodir: $tmpcodir
cd $tmpcodir || Die "cannot cd to temporary checkout directory '$tmpcodir'"

if [ ! -d $CVSROOT/$module/$id_dir ]
then
  cvs co -l $module  # BUG: we can't do this when checking in at top level
  cd $module
  mkdir $id_dir
  cvs add $id_dir
  cvs up $id_dir
  cd $id_dir
else
  cvs co -l $module/$id_dir  # BUG: we can't do this when checking in top level
  cd $module/$id_dir
fi

id_file=`basename $id_file`

if [ ! -f $id_file ]
then
  touch $id_file
  cvs add $id_file
fi

echo 'commit id $''Id$' > $id_file
cvs ci -m '' $id_file

cd $cwd
rm -rf $tmpcodir

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