update i18n
[clawsker.git] / ucl
1 #!/usr/bin/perl -w
2
3 # ucl - update changelog for subversion projects (perl version)
4
5 # Copyright (c) 2005-2010 by Ricardo Mones <ricardo@mones.org>
6 #
7 # Permission  is hereby granted, free of  charge, to any  person obtaining a
8 # copy of this software and associated documentation files (the "Software"),
9 # to deal in the Software without  restriction, including without limitation
10 # the  rights to use, copy, modify, merge, publish,  distribute, sublicense,
11 # and/or sell  copies of the  Software, and to  permit  persons to  whom the
12 # Software is furnished to do so, subject to the following conditions:
13 #
14 # The above  copyright  notice and this  permission notice shall be included
15 # in all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED,  INCLUDING BUT NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A  PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO  EVENT SHALL
20 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY,  WHETHER IN AN  ACTION OF CONTRACT, TORT OR  OTHERWISE, ARISING
22 # FROM,  OUT OF OR  IN  CONNECTION  WITH  THE SOFTWARE OR  THE USE OR  OTHER
23 # DEALINGS IN THE SOFTWARE.
24 #
25
26 use strict;
27
28 my $PROJECT = "clawsker"; # project name under trunk
29 my $REPO = "https://svn.mones.org/svn"; # repository base URL
30 my $CL = './ChangeLog'; # changelog file
31 my $VF = './VERSION'; # version file
32 my $SF = '.ucl.status'; # status file
33 my $PCL = '.ucl.prev'; # previous changelog
34 my @NOTFORRELEASE = ( "ucl" ); 
35 my $release = undef;
36
37 sub tag_new_release {
38   my $relnum = shift;
39   $_ = $relnum;
40   die "Invalid release version\n" unless (/^\d+\.\d+\.\d+$/);
41   my $namevers = "$PROJECT-$relnum";
42   my $sourceurl = "$REPO/trunk/$PROJECT";
43   my $targeturl = "$REPO/tags/$PROJECT/$namevers";
44   my $commitmsg = "'tag release $relnum'";
45   qx/svn cp $sourceurl $targeturl -m $commitmsg/;
46 }
47
48 sub tarball_from_release_tag {
49   my $relnum = shift;
50   $_ = $relnum;
51   die "Invalid release version\n" unless (/^\d+\.\d+\.\d+$/);
52   my $namevers = "$PROJECT-$relnum";
53   my $targeturl = "$REPO/tags/$PROJECT/$namevers";
54   qx/svn export $targeturl/;
55   foreach my $file (@NOTFORRELEASE) {
56     if (-f "$namevers/$file") {
57       unlink("$namevers/$file");
58     }
59   }
60   qx/tar czf $namevers.tar.gz $namevers/;
61 }
62
63 sub parse_options {
64   if (defined($ARGV[0])) {
65     $_ = $ARGV[0];
66     if (/-r/) {
67       die "Undefined release version\n" unless defined ($ARGV[1]);
68       $_ = $ARGV[1];
69       die "Invalid release version\n" unless (/^\d+\.\d+\.\d+$/);
70       $release = $_;
71     }
72     elsif (/-t/) {
73       die "Undefined release version\n" unless defined ($ARGV[1]);
74       &tag_new_release ($ARGV[1]);
75       exit 0;
76     }
77     elsif (/-T/) {
78       die "Undefined release version\n" unless defined ($ARGV[1]);
79       &tarball_from_release_tag ($ARGV[1]);
80       exit 0;
81     }
82     elsif (/-\?/) {
83       my $help = <<'ENDOFHELP'
84 Description:
85     ucl          Update changelog for Subversion repository
86 Syntax:
87     ucl [options]
88 Where options are:
89     -r x.y.z     Update is for release version x.y.z
90     -t x.y.z     Tags current trunk as release x.y.z on repository
91     -T x.y.z     Makes x.y.z release tarball
92 ENDOFHELP
93       ;
94       print $help;
95       exit 0;
96     }
97     else {
98       die "Unknown option. Try -? for help\n";
99     }
100   }
101 }
102
103 sub get_changelog_date {
104   my ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime();
105   $year += 1900;
106   $mon += 1;
107   $hour = ($hour < 10)? "0$hour": "$hour";
108   $min = ($min < 10)? "0$min": "$min";
109   $mon = ($mon < 10)? "0$mon": "$mon";
110   $mday = ($mday < 10)? "0$mday": "$mday";
111   return "$year-$mon-$mday $hour:$min";
112 }
113
114 sub main {
115   # check we're in the right place
116   -e "$CL" or die "Oops, no ChangeLog here\n";
117   -e "$VF" or die "Oops, no VERSION here\n";
118   &parse_options;
119   # parser VERSION file or $release argument
120   my ($major, $minor, $micro, $extra) = (undef, undef, undef, undef);
121   if (not defined ($release)) { # got number it from version file
122     open (VTF, "<$VF");
123     $_ = <VTF>;
124     chomp;
125     close (VTF);
126   }
127   else {
128     $_ = $release;
129   }
130   if (/^(\d+)\.(\d+)\.(\d+)$/) {
131     ($major, $minor, $micro, $extra) = ($1, $2, $3, "");
132   }
133   if (/^(\d+)\.(\d+)\.(\d+)svn(\d+)$/) {
134     ($major, $minor, $micro, $extra) = ($1, $2, $3, $4);
135   }
136   # update directory to be sure we're at the last rev
137   $_ = qx/LANGUAGE=C svn up/;
138   my @updateout = split /\\n/;
139   # get last revision from repository
140   $_ = qx/LANGUAGE=C svn info | grep "Revision"/;
141   @_ = split (':');
142   my $lastrev = $_[1];
143   $lastrev =~ s/\s+//;
144   # calculate modifications
145   qx/svn status > $SF/;
146   my @modifs = ();
147   open (STF, "<$SF");
148   while (<STF>) {
149     chomp;
150     if (/^MM?\s+(.*)$/) {
151       push (@modifs, "\t* $1");
152     }
153     if (/^AM?\s+(.*)$/) {
154       push (@modifs, "\t* $1\t\t**NEW**");
155     }
156     if (/^D\s+(.*)$/) {
157       push (@modifs, "\t* $1\t\t**REMOVED**");
158     }
159     if (/^\?\s+(.*)$/) {
160       print "Info: not versioned: $1\n";
161     }
162   }
163   close (STF);
164   unlink ($SF); # remove the status file
165   # save previous changelog
166   rename ($CL, $PCL);
167   # write new entry header
168   open (NCL, ">$CL");
169   my $cldate = &get_changelog_date;
170   my $cluser = $ENV{USER};
171   my $clvers = "$major.$minor.$micro";
172   if ($release eq "") {
173     if ($extra ne "") {
174       $clvers = ($clvers . "svn" . (1 + $lastrev));
175     }
176   }
177   # write new entry modifications
178   print NCL "$cldate  $cluser   $clvers\n\n";
179   foreach my $modif (@modifs) {
180     print NCL "$modif\n";
181   }
182   print NCL "\n";
183   # and previous entries
184   open (PCL, "<$PCL");
185   while (<PCL>) { print NCL $_; }
186   close (PCL);
187   close (NCL);
188   # and keep a digest for checking
189   my $oldmd5 = qx/md5sum $CL | cut -f1 -d" "/;
190   # edit changelog
191   my $editor = 'vim'; # (defined($ENV{DISPLAY}))? 'gvim -f': 'vim';
192   if (defined($ENV{EDITOR})) {
193     $editor = $ENV{EDITOR};
194   }
195   my @editor = ($editor, $CL);
196   system (@editor);
197   # check for changes
198   my $newmd5 = qx/md5sum $CL | cut -f1 -d" "/;
199   if ($oldmd5 eq $newmd5) {
200     print "Unmodified ChangeLog, discarding changes.\n";
201     unlink ($CL);
202     rename ($PCL, $CL);
203   }
204   else {
205     unlink ($PCL);
206     # update new version after changes
207     qx/echo $clvers > $VF/;
208   }
209 }
210
211 main;
212
213 exit 0;
214