summaryrefslogtreecommitdiffstats
path: root/bin/release
blob: ef79fafe0f9977d09a498d236c8f015030bcf3c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#! /usr/local/bin/perl -w
require 5.003;
use Cwd;

# Builds a release.  Arguments are zero or more of the words.
#
#	tar		-- build a tar file			*.tar
#	compress	-- build a compressed tar file		*.tar.Z
#	gzip		-- build a compressed tar file		*.tar.gz
#	bzip2		-- build a compressed tar file		*.tar.bz2
#
# If no arguments are given then `gzip' is assumed.  If the only argument
# is the word `all' then all forms are used.

$releases = "./releases";	# Directory for release tarballs

##############################################################################
# Read version info, return an array (MAJOR,MINOR,RELEASE,PATCHLEVEL) or
# a string "MAJOR.MINOR.RELEASE PATCHLEVEL"
#
sub getver () {
   my @ver;

   open SRC, "./src/H5public.h" or die "cannot read HDF5 version";
   while (<SRC>) {
      $ver[0] = $1 if /define\s+H5_VERS_MAJOR\s+(\d+)/;
      $ver[1] = $1 if /define\s+H5_VERS_MINOR\s+(\d+)/;
      $ver[2] = $1 if /define\s+H5_VERS_RELEASE\s+(\d+)/;
      $ver[3] = $1 if /define\s+H5_VERS_PATCH\s+(\d+)/;
   }
   close SRC;
   wantarray ? @ver : "$ver[0].$ver[1].$ver[2]".chr(ord('a')+$ver[3]);
}

##############################################################################
# Set version information.  Input is a string or an array.
#
sub setver ($;$$$) {
   my @ver = @_;
   local $_;

   if ($ver[0]=~/\D/) {
      @ver = $ver[0] =~ /^(\d+)\.(\d+)\.(\d+)([a-z])$/ or return "";
      $ver[3] = ord($ver[3])-ord('a');
   }

   $_ = `cat ./src/H5public.h`;
   s/(define\s+H5_VERS_MAJOR\s+)(\d+)/$1$ver[0]/;
   s/(define\s+H5_VERS_MINOR\s+)(\d+)/$1$ver[1]/;
   s/(define\s+H5_VERS_RELEASE\s+)(\d+)/$1$ver[2]/;
   s/(define\s+H5_VERS_PATCH\s+)(\d+)/$1$ver[3]/;
   open SRC, "> ./src/H5public.h" or return "";
   print SRC $_;
   close SRC;

   return 1;
}

##############################################################################
# Make sure MANIFEST contains all the necessary files.  If we are running
# under CVS then look at the CVS/Entries files to get the names that should
# be in the manifest.  Otherwise we really can't do anything.
#
sub manifest () {
    my ($fname, %manifest);
    my $nprobs=0;

    # We can't do anything if we're not running under cvs.
    return "" unless -d "CVS";

    # Read the files from the manifest.
    open MANIFEST, "MANIFEST" or die "unable to read manifest";
    while (<MANIFEST>) {
	chomp;
	$manifest{$_} = 1;
    }
    close MANIFEST;

    # Read files from CVS/Entries
    open FIND, "find . -name Entries -print | sort |" or
	die "unable to find CVS entries";
    while (defined($fname=<FIND>)) {
	chomp $fname;
	my ($dir) = $fname =~ m%(.*)/CVS/Entries%;
	open ENTRIES, $fname or die "unable to open $fname";
	while (<ENTRIES>) {
	    my ($ename);
	    next unless ($ename) = m%^/([^/]+)/[^-]%;
	    $ename = "$dir/" . $ename;
	    if (exists $manifest{$ename}) {
		delete $manifest{$ename};
	    } else {
		print "NEW: $ename\n";
		$nprobs++;
	    }
	}
	close ENTRIES;
    }
    close FIND;

    for (sort keys %manifest) {
	print "OLD: $_\n";
	$nprobs++;
    }

    if ($nprobs) {
	print "Please add the new files to MANIFEST and remove the old\n";
	print "files and try again.  The MANIFEST should contain all files\n";
	print "that are to be distributed for a release.\n";
	exit 1;
    }
}


##############################################################################
# Build a release
#
sub release (@) {
   my @types = @_;
   my ($ver, $status, $created_symlink);
   my ($batch) = 0;
   local $_;

   if (@types>0 && $types[0] =~ /^-?-batch$/) {
     $batch = 1;
     shift @types;
   }

   # Make sure no one forgot to update MANIFEST
   manifest;

   # Make sure the version number is correct.
   $ver = getver;
   if ($batch) {
     print "Releasing version $ver\n";
   } else {
     print "HDF version to release [$ver] ";
     return "" unless defined ($_=<STDIN>);
     chomp;
     (setver ($ver=$_) or die "cannot set version") if /\S/;
   }

   # Move default top-level makefile into place.
   $status = system "cp Makefile.dist Makefile";
   die "cannot install default Makefile" if $status >> 8;

   # Make sure release directory exists
   (mkdir $releases, 0777 or die "cannot create $releases")
       unless -d $releases;
   die "no manifest" unless -r "MANIFEST";

   # We build the release from above the root of the source tree so the
   # hdf5 directory appears as part of the name in the tar file. We create
   # a temporary symlink called something like `hdf5-1.0.0a' that points to
   # our current working directory.
   $_ = cwd;
   my ($parent,$root) = m%(.*)/(.*)$% or die "cannot split directory";
   if ($root ne "hdf5-$ver" && ! -e "../hdf5-$ver") {
      symlink $root, "../hdf5-$ver" or die "cannot create link";
      $created_symlink = 1;
   }
   my $name = "$root/$releases/hdf5-$ver";

   # Build the releases.
   @types = ("gzip") unless @types;
   @types = qw/tar gzip compress bzip2/ if 1==@types && "all" eq $types[0];
   $_ = `cat MANIFEST`;
   s/^\.\///mg;
   @filelist = ("Makefile", split /\s*\n/, $_);
   $filelist = join " ", map {"hdf5-$ver/$_"} @filelist;

   chdir ".." or die;
   for (@types) {
      print "Compressing with $_...\n";

      /^tar$/ && do {
	 $status = system "tar cf $name.tar $filelist";
	 next;
      };

      /^gzip$/ && do {
	 $status = system "tar cf - $filelist |gzip -9 >$name.tar.gz";
	 next;
      };

      /^compress$/ && do {
	 $status = system "tar cf - $filelist |compress -c >$name.tar.Z";
	 next;
      };

      /^bzip2$/ && do {
	 $status = system "tar cf - $filelist |bzip2 -9 >$name.tar.bz2";
	 next;
      };
   } continue {
      print STDERR "$_ failed\n" if $status >> 8;
   }
   chdir $root or die;

   # Remove the temporary symlink we created above.
   unlink "../hdf5-$ver" if $created_symlink;
   

   # Update version info
   if ($batch) {
     my ($v1,$v2,$v3,$v4) = $ver =~ /^(\d+)\.(\d+)\.(\d+)([a-z])$/;
     $v3 += 1;
     setver ($ver = "$v1.$v2.${v3}a") or die "cannot set version";
     print "Development version set to $ver\n";
   } else {
     print <<EOF;

If this is a real release then the version number for continued development
should be incremented.  Otherwise just press return.

EOF
     print "Set development version to [", ($ver=getver), "] ";
     return "" unless defined ($_ = <STDIN>);
     chomp;
     (setver ($ver=$_) or die "cannot set version") if /\S/;

     if (-d "CVS") {
       my $tag = $ver;
       $tag =~ s/\./-/g;
       print "Tag CVS sources with \"$tag\"? [n] ";
       chomp ($_ = <STDIN>);
       if ($_ eq 'y') {
	 print "Tagging CVS sources...\n";
	 my $status = system "cvs tag -R $tag";
	 die "cvs tag failed" if $status >> 8;
       }
     }
   }

   return 1;
}

release @ARGV;