tags:

views:

160

answers:

6

a question following making-the-subversion-revision-number-visible-in-my-r-scripts

R CMD build PKG creates a file named as Package_Version.tar.gz according to the fields in DESCRIPTION.

not only isn't the strictly sequential numbering coming from svn very practical here, but its $REV: number $ format does not respect the number.number-number structure expected after Version:.

I think I would want to use the subversion revision number as the third "coordinate" of the package version. the first and second coordinates would be raised by hand at major changes.

but how do you "normally" do?


One could write a bash/grep/awk script that gets the highest Rev out of the sources, that wouldn't a problem. But, is configure run before R CMD build? In this case one could build the DESCRIPTION file (kept out of source control) from a template file and this highest Rev number.

My question is about common practice.


the "optimal" answer would allow me to place a package on r-forge and have the automated scripts run there update the third coordinate of the Version: field from the latest files committed in the R subdir.

a "good enough" answer would work locally and I have it already, but am not using it any more because I otherwise get used to things that are generally unavailable.

since it's about practices, I'll add my current practice as possible answer. it is not automated but I find it clear and (almost) acceptable.

A: 

I use a build script which checks out a certain revision from svn, updates the DESCRIPTION with the version number, and builds it into a tar.gz.

I manage the process a little more by using the roadmap feature in Jira to bundle issues/svn commits as versions (the Apache foundation uses the same basic approach as in the this example).

Shane
Care to share your build script?
Steve Lianoglou
Shane, if you add a line like 'SVN-Revision: $Rev$' to DESCRIPTION and set the 'svn propset' then the revision gets automatically updated by subversion. I do that that e.g. with the Date: field.
Dirk Eddelbuettel
Nice! I'll give that a try now.
Shane
A: 

Would it be easier to use the timestamp Dec 11, 2009 12:01:03 turns into 20091211120103. Then you could put a tag in subversion for the build as well and know which source corresponds to which build.

harmanjd
:) no, please no :) ... this way my package file would be called PKG_1.20091211120103-0.tar.gz! it's not difficult to ask svn the date of a revision. Moreover, you would produce different distributions even if nothing changed.
mariotomo
+1  A: 

Calling 'svnversion <working-copy>' should give you the information you need.

If your working copy is modified, or has files from more than one version you get more than just a version number. Either a range (multiple revisions) or suffixed letters (Modified, Switched or Sparse working copies).

$ svnversion --help
usage: svnversion [OPTIONS] [WC_PATH [TRAIL_URL]]

  Produce a compact 'version number' for the working copy path
  WC_PATH.  TRAIL_URL is the trailing portion of the URL used to
  determine if WC_PATH itself is switched (detection of switches
  within WC_PATH does not rely on TRAIL_URL).  The version number
  is written to standard output.  For example:

    $ svnversion . /repos/svn/trunk
    4168

  The version number will be a single number if the working
  copy is single revision, unmodified, not switched and with
  an URL that matches the TRAIL_URL argument.  If the working
  copy is unusual the version number will be more complex:

   4123:4168     mixed revision working copy
   4168M         modified working copy
   4123S         switched working copy
   4123P         partial working copy, from a sparse checkout
   4123:4168MS   mixed revision, modified, switched working copy

  If invoked on a directory that is not a working copy, an
  exported directory say, the program will output 'exported'.

  If invoked without arguments WC_PATH will be the current directory.

Valid options:
  -n [--no-newline]        : do not output the trailing newline
  -c [--committed]         : last changed rather than current revisions
  -h [--help]              : display this help
  --version                : show program version information
Bert Huijben
+2  A: 

I also use svnversion to automate this. E.g. for littler, which is of course compiled, I do this:

#!/bin/sh -e

svnversion() {
    svnrevision=`LC_ALL=C svn info | awk '/^Revision:/ {print $2}'`
    svndate=`LC_ALL=C svn info | awk '/^Last Changed Date:/ {print $4,$5}'`

    now=`date`

    cat <<EOF > svnversion.h

// Do not edit!  This file was autogenerated
//      by $0
//      on $now
//
// svnrevision and svndate are as reported by svn at that point in time,
// compiledate and compiletime are being filled gcc at compilation

#include <stdlib.h>

static const char* svnrevision = "$svnrevision";
static const char* svndate = "$svndate";
static const char* compiletime = __TIME__;
static const char* compiledate = __DATE__;

EOF
}

if [ "$#" -ge 0 ]; then
    if [ "$1" = "--svnversion" ]; then
        svnversion
        exit
    fi
fi

test -f svnversion.h || svnversion

from the Makefile and then use that as in

void showVersionAndExit() {
    printf("%s ('%s') version %s\n\tsvn revision %s as of %s\n\t"
           "built at %s on %s\n",
           binaryName, programName, VERSION,
           svnrevision, svndate, compiletime, compiledate);
    /* more code below ... */

The same could be done for R, easiest by accessing the DESCRIPTION file as I suggested to Mario in answering his earlier question.

Then, and to finally answer your question :), you could massage that number you get from svnversion for the repository itself (or its top-level entry) in any may you like to mod the DESCRIPTION file. But then you modify the file and are out of sync, so you resubmit, get a new revision, ... so you need to agree with yourself on some way to break this loop.

Dirk Eddelbuettel
yes: what you do with your C project is exactly what I would like to do in my R library, namely extract the highest svn version from the directory tree, put it in a file which is not under version control, use that file in my code. only: I also want to find it back in DESCRIPTION and I need DESCRIPTION under version control. see my own answer...
mariotomo
A: 

I see that ./cleanup is called during the R CMD build ... command.

I think I am going to...

  • keep DESCRIPTION.template in the repository.
  • instruct subversion to ignore DESCRIPTION.
  • use the cleanup script.
  • accept I must run R CMD build twice (meta-information in DESCRIPTION is checked by R CMD build before it is computed by cleanup).

cleanup:

#!/bin/bash
FLAGS=$(svnversion . | tr -cd A-Z)

VERSIONS=$(svnversion . | tr -d A-Z)
VERSIONS=$(echo $VERSIONS:$VERSIONS | cut -d: -f1,2)
LOW=${VERSIONS%:*}
HIGH=${VERSIONS#*:}

[ $LOW -ne $HIGH ] && echo "- mixed revisions in local copy ($LOW:$HIGH)"
[ "$FLAGS" != "" ] && echo "- local copy has flags: $FLAGS"
echo "- highest revision in local copy: $HIGH"

sed -re "s/(^Version:[^-]*).+$/\1-$HIGH/" DESCRIPTION.template > DESCRIPTION

DATE=`LC_ALL=C svn info | awk '/^Last Changed Date:/ {print $4,$5}'`

now=$(date)
cat <<EOF > R/version.R
# Do not edit!  This file was autogenerated
#      by $0
#      on $now
#
# DO NOT put this file under version control!
#
# SVNVERSION as the highest revision reported by svnversion.
# DATE as the Last Changed Date reported by svn info.

SVNVERSION <- "$HIGH"
SVNDATE <- "$DATE"
EOF

obviously I have to copy DESCRIPTION.template > DESCRIPTION in order to bootstrap the process.


thanks everybody for the useful comments and I'm interested in reading if you think I could achieve the same result in a cleaner way.

mario@lt41:~/Local/.../Trunk/Rnens$ R CMD build src
* checking for file 'src/DESCRIPTION' ... OK
* preparing 'src':
* checking DESCRIPTION meta-information ... OK
* running cleanup
- highest revision in local copy: 8762
* removing junk files
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* building 'NenS_0.1-8762.tar.gz'

but I must also say, I am satisfied with the current solution and I hope it will be useful to others.

mariotomo
I would like to hear your opinions before I accept my own answer... it seems more polite :)
mariotomo
this solution is not satisfactory if you place the package on CRAN, because there `R CMD build pkg` is called just once!
mariotomo
A: 

my current practice is not automated at all: I give the three coordinates of the Version: field the meaning as in the question, but the third coordinate (the svn revision number), I update it by hand (incrementing it by one) before each commit.

working from Emacs (using psvn), I don't see this as a major limitation, but it is more work than I would like to perform by hand and it is definitely not satisfactory on larger repositories where the revision number is incremented by unrelated commits.

mariotomo