home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / contrib / commit_prep.pl < prev    next >
Perl Script  |  1996-09-28  |  6KB  |  217 lines

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