Annotation of CVSROOT/commit-prep, revision 1.1
1.1 ! cvs 1: #!/usr/bin/perl
! 2: # -*-Perl-*-
! 3: #
! 4: #ident "@(#)cvs/contrib:$Name: $:$Id: commit-prep,v 1.1 2000/11/20 14:39:43 count Exp $"
! 5: #
! 6: #
! 7: # Perl filter to handle pre-commit checking of files. This program
! 8: # records the last directory where commits will be taking place for
! 9: # use by the log_accum.pl script. For new files, it forces the
! 10: # existence of a RCS "Id" keyword in the first ten lines of the file.
! 11: # For existing files, it checks version number in the "Id" line to
! 12: # prevent losing changes because an old version of a file was copied
! 13: # into the direcory.
! 14: #
! 15: #
! 16: # Possible future enhancements:
! 17: #
! 18: # Check for cruft left by unresolved conflicts. Search for
! 19: # "^<<<<<<<$", "^-------$", and "^>>>>>>>$".
! 20: #
! 21: # Look for a copyright and automagically update it to the
! 22: # current year. [[ bad idea! -- woods ]]
! 23: #
! 24: #
! 25: # Contributed by David Hampton <hampton@cisco.com>
! 26: #
! 27: # Hacked on lots by Greg A. Woods <woods@web.net>
! 28:
! 29: #
! 30: # Configurable options
! 31: #
! 32:
! 33: # Constants (remember to protect strings from RCS keyword substitution)
! 34: #
! 35: $LAST_FILE = "/tmp/#cvs.lastdir"; # must match name in log_accum.pl
! 36: $ENTRIES = "CVS/Entries";
! 37:
! 38: # Patterns to find $Log keywords in files
! 39: #
! 40: $LogString1 = "\\\$\\Log: .* \\\$";
! 41: $LogString2 = "\\\$\\Log\\\$";
! 42: $NoLog = "%s - contains an RCS \$Log keyword. It must not!\n";
! 43:
! 44: # pattern to match an RCS Id keyword line with an existing ID
! 45: #
! 46: $IDstring = "\"@\\(#\\)[^:]*:.*\\\$\Id: .*\\\$\"";
! 47: $NoId = "
! 48: %s - Does not contain a properly formatted line with the keyword \"Id:\".
! 49: I.e. no lines match \"" . $IDstring . "\".
! 50: Please see the template files for an example.\n";
! 51:
! 52: # pattern to match an RCS Id keyword line for a new file (i.e. un-expanded)
! 53: #
! 54: $NewId = "\"@(#)[^:]*:.*\\$\Id\\$\"";
! 55:
! 56: $NoName = "
! 57: %s - The ID line should contain only \"@(#)module/path:\$Name\$:\$\Id\$\"
! 58: for a newly created file.\n";
! 59:
! 60: $BadName = "
! 61: %s - The file name '%s' in the ID line does not match
! 62: the actual filename.\n";
! 63:
! 64: $BadVersion = "
! 65: %s - How dare you!!! You replaced your copy of the file '%s',
! 66: which was based upon version %s, with an %s version based
! 67: upon %s. Please move your '%s' out of the way, perform an
! 68: update to get the current version, and them merge your changes
! 69: into that file, then try the commit again.\n";
! 70:
! 71: #
! 72: # Subroutines
! 73: #
! 74:
! 75: sub write_line {
! 76: local($filename, $line) = @_;
! 77: open(FILE, ">$filename") || die("Cannot open $filename, stopped");
! 78: print(FILE $line, "\n");
! 79: close(FILE);
! 80: }
! 81:
! 82: sub check_version {
! 83: local($i, $id, $rname, $version);
! 84: local($filename, $cvsversion) = @_;
! 85:
! 86: open(FILE, "<$filename") || return(0);
! 87:
! 88: @all_lines = ();
! 89: $idpos = -1;
! 90: $newidpos = -1;
! 91: for ($i = 0; <FILE>; $i++) {
! 92: chop;
! 93: push(@all_lines, $_);
! 94: if ($_ =~ /$IDstring/) {
! 95: $idpos = $i;
! 96: }
! 97: if ($_ =~ /$NewId/) {
! 98: $newidpos = $i;
! 99: }
! 100: }
! 101:
! 102: if (grep(/$LogString1/, @all_lines) || grep(/$LogString2/, @all_lines)) {
! 103: print STDERR sprintf($NoLog, $filename);
! 104: return(1);
! 105: }
! 106:
! 107: if ($debug != 0) {
! 108: print STDERR sprintf("file = %s, version = %d.\n", $filename, $cvsversion{$filename});
! 109: }
! 110:
! 111: if ($cvsversion{$filename} == 0) {
! 112: if ($newidpos != -1 && $all_lines[$newidpos] !~ /$NewId/) {
! 113: print STDERR sprintf($NoName, $filename);
! 114: return(1);
! 115: }
! 116: return(0);
! 117: }
! 118:
! 119: if ($idpos == -1) {
! 120: print STDERR sprintf($NoId, $filename);
! 121: return(1);
! 122: }
! 123:
! 124: $line = $all_lines[$idpos];
! 125: $pos = index($line, "Id: ");
! 126: if ($debug != 0) {
! 127: print STDERR sprintf("%d in '%s'.\n", $pos, $line);
! 128: }
! 129: ($id, $rname, $version) = split(' ', substr($line, $pos));
! 130: if ($rname ne "$filename,v") {
! 131: print STDERR sprintf($BadName, $filename, substr($rname, 0, length($rname)-2));
! 132: return(1);
! 133: }
! 134: if ($cvsversion{$filename} < $version) {
! 135: print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
! 136: "newer", $version, $filename);
! 137: return(1);
! 138: }
! 139: if ($cvsversion{$filename} > $version) {
! 140: print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
! 141: "older", $version, $filename);
! 142: return(1);
! 143: }
! 144: return(0);
! 145: }
! 146:
! 147: #
! 148: # Main Body
! 149: #
! 150:
! 151: $id = getpgrp(); # You *must* use a shell that does setpgrp()!
! 152:
! 153: # Check each file (except dot files) for an RCS "Id" keyword.
! 154: #
! 155: $check_id = 0;
! 156:
! 157: # Record the directory for later use by the log_accumulate stript.
! 158: #
! 159: $record_directory = 0;
! 160:
! 161: # parse command line arguments
! 162: #
! 163: while (@ARGV) {
! 164: $arg = shift @ARGV;
! 165:
! 166: if ($arg eq '-d') {
! 167: $debug = 1;
! 168: print STDERR "Debug turned on...\n";
! 169: } elsif ($arg eq '-c') {
! 170: $check_id = 1;
! 171: } elsif ($arg eq '-r') {
! 172: $record_directory = 1;
! 173: } else {
! 174: push(@files, $arg);
! 175: }
! 176: }
! 177:
! 178: $directory = shift @files;
! 179:
! 180: if ($debug != 0) {
! 181: print STDERR "dir - ", $directory, "\n";
! 182: print STDERR "files - ", join(":", @files), "\n";
! 183: print STDERR "id - ", $id, "\n";
! 184: }
! 185:
! 186: # Suck in the CVS/Entries file
! 187: #
! 188: open(ENTRIES, $ENTRIES) || die("Cannot open $ENTRIES.\n");
! 189: while (<ENTRIES>) {
! 190: local($filename, $version) = split('/', substr($_, 1));
! 191: $cvsversion{$filename} = $version;
! 192: }
! 193:
! 194: # Now check each file name passed in, except for dot files. Dot files
! 195: # are considered to be administrative files by this script.
! 196: #
! 197: if ($check_id != 0) {
! 198: $failed = 0;
! 199: foreach $arg (@files) {
! 200: if (index($arg, ".") == 0) {
! 201: next;
! 202: }
! 203: $failed += &check_version($arg);
! 204: }
! 205: if ($failed) {
! 206: print STDERR "\n";
! 207: exit(1);
! 208: }
! 209: }
! 210:
! 211: # Record this directory as the last one checked. This will be used
! 212: # by the log_accumulate script to determine when it is processing
! 213: # the final directory of a multi-directory commit.
! 214: #
! 215: if ($record_directory != 0) {
! 216: &write_line("$LAST_FILE.$id", $directory);
! 217: }
! 218: exit(0);
LinuxTV legacy CVS <linuxtv.org/cvs>