Use the commit message in a CVS pre-commit hook
Asked Answered
A

4

5

Is it possible to use the commit message in a pre-commit hook in CVS? The CVS server is running remotely, and I access it using pserver.

Ideally, I want to allow the commit if the files pass the filter or the commit message contains certain text.

I don't have a choice to use another versioning system.

Ayres answered 7/12, 2009 at 0:7 Comment(0)
G
4

Here are some useful tutorials to read more:

http://durak.org/sean/pubs/software/cvsbook/The-commitinfo-And-loginfo-And-rcsinfo-Files.html
http://durak.org/sean/pubs/software/cvsbook/The-verifymsg-And-rcsinfo-Files.html#The-verifymsg-And-rcsinfo-Files

You can't do what you want with just one hook but you can use two hooks, commitinfo will let you verify the files themselves and verifymsg will let you verify the message. Both can be used to cancel the commit (the programs just need to exit with status 1). In case you weren't aware, checkoutlist, commitinfo and 'verifymsg' can all be found in the CVSROOT directory of your repository. I would recommend putting any scripts you write as hooks in that directory as well, but it doesn't really matter as you get to specify the full path. Also, perl is not necessary or required, just simple for me to write some (silly) examples in:

checkoutlist

# these files will be automatically checked out for you
acceptable

verifymsg

# specifies which file to run as hook, %l is filename of log message
# bar$     /path/to/repo/CVSROOT/verify_ends_in_bar %l
DEFAULT    /path/to/repo/CVSROOT/acceptable %l %s

acceptable

#/usr/bin/perl -w

use strict;
use warnings;

# this would be simpler if cvs passed sane arguments
my ($logfile, $dir, @files) = @ARGV;
my $grep = `grep -i 'accept liability' $logfile`;
exit 0 if $grep;

my $found = 0;
foreach my $file (@files) {
    my $path = join '/', $dir, $file;
    die "Can't find file $path" if ! -e $path;
    my $grep = `grep -i 'evidence of any deliberation' $path`;
    $found++ if $grep;
}
die "You must accept liability or show evidence of deliberation" if $found < @files;

Caveat emptor: I wrote most of this off the top of my head with no testing so I can't guarantee it works but it should get you at least close.

Edit again, I just realized that I was originally wrong and you can pass both the logfile and the committed filenames to verifymsg making the answer quite a bit simpler.

Garbanzo answered 16/1, 2010 at 6:7 Comment(5)
What version of CVS have you tried this with? With my version, when I specify %s in the verifymsg file I don't get the committed files, I still only get the log file.Ayres
@Ayres I haven't ever had a need to use verifymsg like you have, I've only used loginfo and commitinfo but I thought I had found some examples online that showed verifymsg accepting both the log file and %s. If that doesn't work for you, you may have to fall back to some kind of communication between a commitinfo script and the verifymsg script.Garbanzo
@Ayres Also, could you make do with requiring both criteria? Then a earlier version of my answer which used commitinfo and verifymsg would work for. I guess it depends on whether you meant logical or or more typically english or.Garbanzo
I think I'll have to make do for the time being. I can always check the commit messages manually for a while. Perhaps I should move away from CVS altogether, even though it has been rather suited to my needs up until now.Ayres
@Ayres Yeah, the commit hooks are really useful for simple things but they get pretty tedious to deal with as your requirements get more complex.Garbanzo
R
3

The CVS::Trigger Perl module seems to have an experimental feature that allows for caching values between the call of different triggers. The page explicitly mentions passing the filenames from commitinfo to verifymsg, so maybe it helps you to achieve what you want.

Rebeca answered 15/1, 2010 at 21:51 Comment(1)
Thanks for that. I would go for this answer except that as you stated it is experimental, and I need something a little more concrete.Ayres
D
1

You can use the verifymsg file in the CVSROOT directory. You can configure it to call a script which can verify the contents of the checkin comment. You can reject the commit by returning non-zero.

The default verifymsg file contains more details.

Diploma answered 7/12, 2009 at 2:48 Comment(4)
I want to reject the commit if the pre-commit hook fails and the log message does not contain "I accept liability" or whatever. The pre-commit hook ensures that the files are valid, but in the event that committing files that break the rules is necessary I want to ensure that the log mentions it. I want to be able to check both the committed message and the committed files before allowing the commit.Ayres
The problem is, the pre-commit hook doesn't seem to be able to access the commit message to ensure that the failed verification is logged as deliberate, and the verifymsg hook can't access the changed files to verify that the changes comply with the rules.Ayres
You're right, the verifymsg can't get at the files being commited. You'd have to implement them separately. So if one fails the whole commit will fail. Does that do what you want? Also, to clarify, as far as I recall, you can't get at the actual files in the pre-commit hook you're simply told the paths/names.Diploma
I can get the actual files being committed in the pre-commit hook (with the changes that were made). I think I'll have to implement them separately, but I only want it to fail if the files failed validation and there is no evidence of any deliberation.Ayres
O
0

I have been dealing with the same issue. So far my best solution has been to get the parent process Id (getppid()) and use it ina temp file that I can put the list of files into from commitinfo. This parent ID seems to be the same for the verifymsg process (on AIX at least). Good luck.

Odorous answered 22/2, 2010 at 19:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.