Initial commit
[clearscm.git] / cvsbin / cvsims
1 #!/usr/local/bin/perl5.8.4
2 ################################################################################
3 #
4 # File:         cvsims,v
5 # Revision:     1.1.1.1
6 # Author:       Andrew@DeFaria.com
7 # Description:  This script will read CVS commit information searching for Issue
8 #               IDs and formulate a "change set" including the files committed
9 #               and update IMS.
10 # Created:      Fri Dec  9 15:10:56 PST 2005
11 # Modified:     2007/05/17 07:45:48
12 # Language:     perl
13 #
14 # (c) Copyright 2005, Andrew@DeFaria.com, all rights reserved
15 #
16 ################################################################################
17 use strict;
18 use warnings;
19 use File::Spec;
20
21 my $me;
22 my $version = "1.0";
23
24 BEGIN {
25   # Set $lib_path
26   my $lib_path = $^O =~ /MSWin/ ? "\\\\brcm-irv\\dfs\\projects\\ccase\\SCM\\lib"
27                                 : "/projects/ccase/SCM/lib";
28
29   # Extract relative path and basename from script name.
30   $0 =~ /(.*)[\/\\](.*)/;
31
32   my $abs_path  = (!defined $1) ? "." : File::Spec->rel2abs ($1);
33   $me           = (!defined $2) ? $0  : $2;
34   $me           =~ s/\.pl$//;
35
36   # Add the appropriate path to our modules to @INC array.
37   unshift @INC, $ENV {SITE_PERL_LIBPATH} if defined $ENV {SITE_PERL_LIBPATH};
38   unshift @INC, "$lib_path";
39   unshift @INC, "$abs_path";
40 } # BEGIN
41
42 use IMS;
43 use Display;
44
45 sub Usage {
46   my $msg = shift;
47
48   display "ERROR: $msg\n" if defined $msg;
49
50   display "Usage: $me\t[-u] [-v] [-d] [-passthru] 
51 \t\t[{-pre -logfile <filename>} |
52 \t\t {-post -repository <repository> -path <path>
53 \t\t  <file> <rev> {<file> <rev>...}}]
54
55 Where:
56
57   -u:            Display usage
58   -v:            Turn on verbose mode
59   -d:            Turn on debug mode
60   -passthru:     Passthru stdin to stdout
61
62 Pre options:
63   -pre:          Perform pre commit checking.
64   -logfile       Path to logfile containing commit message
65
66 Post options:
67   -post:         Perform post commit updating
68   -repository:   Repository (path portion of \$CVSROOT)
69   -path:         Path relative to repository
70   <file> <rev>:  Files and revisions commited (Format: \"file rev file rev ...\")
71 ";
72   exit 1;
73 } # Usage
74
75 sub UpdateIMS {
76   my $issueid           = shift;
77   my $repository        = shift;
78   my $path              = shift;
79   my %filerevs          = @_;
80
81   my $change_set;
82
83   foreach (sort (keys (%filerevs))) {
84     $change_set .= "${filerevs {$_}}\t$repository/$path/$_\n";
85   } # foreach
86
87   my $error = AddToChangeSet ($issueid, $change_set);
88
89   return $error;
90 } # UpdateIMS
91
92 sub ParseInput {
93   my @input = @_;
94
95   my $sentinal = "csp: ";
96   my %issue_ids;
97   my @issue_ids;
98   # Issue id information in the input must have the following format:
99   #
100   # $sentinal <n>, {n}
101   foreach my $line (@input) {
102     if ($line =~ /^$sentinal/i) {
103       # Remove $sentinal
104       $line = substr $line, length ($sentinal);
105       # Remove and commas
106       $line =~ tr /,/ /;
107       @issue_ids = split /\s+/, $line;
108       last;
109     } # if
110   } # foreach
111
112   # Eliminate duplicates on return
113   return grep (!$issue_ids {$_}++, @issue_ids);
114 } # ParseInput
115
116 sub ReadFile {
117   my $file      = shift;
118   my $passthru  = shift;
119
120   my @lines = <$file>;
121
122   my @cleansed_lines;
123
124   foreach (@lines) {
125     print $_ if $passthru;
126     chomp;
127     chop if /\r/;
128     push @cleansed_lines, $_ if !/^#/; # Discard comment lines
129   } # foreach
130
131   return @cleansed_lines;
132 } # ReadFile
133
134 my $optkind;
135 my $repository;
136 my $path;
137 my $passthru = 0;
138 my $logfile;
139 my %filerevs;
140
141 while ($ARGV [0]) {
142   if ($ARGV [0] eq "-v") {
143     Display::set_verbose;
144   } elsif ($ARGV [0] eq "-d") {
145     set_debug;
146   } elsif ($ARGV [0] eq "-passthru") {
147     $passthru = 1;
148   } elsif ($ARGV [0] eq "-repository") {
149     shift @ARGV;
150     if (!$ARGV [0]) {
151       Usage "Must specify repository after -repository";
152     } else {
153       $repository = $ARGV [0];
154     } # if
155   } elsif ($ARGV [0] eq "-path") {
156     shift @ARGV;
157     if (!$ARGV [0]) {
158       Usage "Must specify path after -path";
159     } else {
160       $path = $ARGV [0];
161     } # if
162   } elsif ($ARGV [0] eq "-pre") {
163     $optkind = "pre";
164   } elsif ($ARGV [0] eq "-logfile") {
165     shift @ARGV;
166     if (!$ARGV [0]) {
167       Usage "Must specify log filename after -logfile";
168     } else {
169       $logfile = $ARGV [0];
170     } # if
171   } elsif ($ARGV [0] eq "-post") {
172     $optkind = "post";
173   } elsif ($ARGV [0] eq "-u") {
174     Usage;
175   } else {
176     %filerevs = @ARGV;
177     last;
178   } # if
179
180   shift (@ARGV);
181 } # while
182
183 Usage "Must specify -pre or -post" if !defined $optkind;
184
185 if ($optkind eq "pre") {
186   Usage "No logfile to parse" if !defined $logfile;
187 } elsif ($optkind eq "post") {
188   Usage "No files committed" if !%filerevs;
189 } # if
190
191 my @issue_ids;
192
193 if ($optkind eq "pre") {
194   verbose "$me v$version: Checking for Issue ID(s)...";
195   open LOGFILE, $logfile
196     or error "Unable to open logfile $logfile - $!", 4;
197
198   @issue_ids = ParseInput ReadFile (*LOGFILE);
199
200   close LOGFILE;
201 } else {
202   # Special case here. Seems cvs will call this script through loginfo
203   # even though directories are not versioned in cvs. If so then
204   # %filerevs will contain "- New directory" and "NONE". In this case
205   # we simply exit 0.
206   if (defined $filerevs {"- New directory"}) {
207     exit 0;
208   } # if
209
210   verbose "$me v$version: Updating Issue ID(s)...";
211   @issue_ids = ParseInput ReadFile (*STDIN, $passthru);
212 } # if
213
214 if (scalar (@issue_ids) eq 0) {
215   error "No issue ID(s) found", 1;
216 } # if
217
218 verbose "Verifying Issue IDs";
219
220 foreach (@issue_ids) {
221   my %issue_info = GetIssue $_;
222
223   if (%issue_info) {
224     verbose "Issue $_ exists in IMS";
225   } else {
226     error "Issue ID $_ does not exist in IMS", 2 if !%issue_info;
227   } # if
228 } # foreach
229
230 if ($optkind eq "post") {
231   foreach my $issue_id (@issue_ids) {
232     verbose "Updating Issue ID ${issue_id}'s Change Set";
233
234     my $error = UpdateIMS $issue_id, $repository, $path, %filerevs;
235
236     if ($error ne "") {
237       error $error, 3;
238     } else {
239       verbose "Issue ID ${issue_id}'s Change Set updated";
240     } # if
241   } # foreach
242 } # if
243
244 exit 0;