source: box/trunk/infrastructure/makedistribution.pl.in @ 2596

Revision 2596, 7.9 KB checked in by chris, 2 years ago (diff)

Switch license to GPL for backup parts, and dual GPL/BSD for common
parts, as discussed and agreed in this thread:

 http://lists.boxbackup.org/pipermail/boxbackup/2010-January/000005.html

  • Property svn:eol-style set to native
Line 
1#!@PERL@
2
3use strict;
4use Symbol;
5
6# comment string for various endings
7my %comment_chars = ('cpp' => '// ', 'h' => '// ', 'pl' => '# ', 'pm' => '# ', '' => '# ');
8
9# other extensions which need text copying, just to remove the private stuff
10# .in is included here, as these could be any kind of source, but clearly
11# they have text substitutions run on them by autoconf, so we can too :)
12my %text_files = ('txt' => 1, 'spec' => 1, 'in' => 1);
13
14# files which don't get the license added
15# my %file_license = (); # 'filename' => 'GPL', 'DUAL' or 'none'
16
17# ----------------------------------------------
18
19# filled in from the manifest file
20# my %dir_license = (); # 'dir' => 'GPL', 'DUAL' or 'none'
21#
22# most recently specified LICENSE become default until overridden
23my $current_license; # 'GPL', 'DUAL' or 'none'
24
25# distribution name
26my $distribution = $ARGV[0];
27die "No distribution name specified on the command line" if $distribution eq '';
28my $dist_root = "distribution/$distribution";
29
30# check distribution exists
31die "Distribution '$distribution' does not exist" unless -d $dist_root;
32
33# get version
34open VERSION,"$dist_root/VERSION.txt" or die "Can't open $dist_root/VERSION.txt";
35my $version = <VERSION>;
36chomp $version;
37my $archive_name = <VERSION>;
38chomp $archive_name;
39close VERSION;
40
41# consistency check
42die "Archive name '$archive_name' is not equal to the distribution name '$distribution'"
43        unless $archive_name eq $distribution;
44
45my $svnversion = `svnversion .`;
46chomp $svnversion;
47$svnversion =~ tr/0-9A-Za-z/_/c;
48
49if($version =~ /USE_SVN_VERSION/)
50{
51        # for developers, use SVN version
52        open INFO,'svn info . |';
53        my $svnurl;
54        while(<INFO>)
55        {
56                if(m/^URL: (.+?)[\n\r]+/)
57                {
58                        $svnurl = $1;
59                }
60        }
61        close INFO;
62        $svnurl =~ m'box/(.+)$';
63        my $svndir = $1;
64        $svndir =~ tr/0-9A-Za-z/_/c;
65        $version =~ s/USE_SVN_VERSION/$svndir.'_'.$svnversion/e;
66}
67
68# make initial directory
69my $base_name = "$archive_name-$version";
70system "rm -rf $base_name";
71system "rm $base_name.tgz";
72mkdir $base_name,0755;
73
74# get license files
75my %license_text; # name of license => array of lines of license text
76foreach my $license ("GPL", "DUAL")
77{
78        my $file = "./LICENSE-$license.txt";
79        open LICENSE, $file or die "Can't open $file: $!";
80        my @lines = <LICENSE>;
81        close LICENSE;
82        unshift @lines, "distribution $base_name (svn version: $svnversion)\n";
83        $license_text{$license} = \@lines;
84}
85
86# copy files, make a note of all the modules included
87my %modules_included;
88my $private_sections_removed = 0;
89my $non_distribution_sections_removed = 0;
90sub copy_from_list
91{
92        my $list = $_[0];
93        open LIST,$list or die "Can't open $list";
94       
95        while(my $line = <LIST>)
96        {
97                next unless $line =~ m/\S/;
98                chomp $line;
99                my @words = split /\s+/, $line;
100                my ($src,$dst,$other) = @words;
101                $dst = $src if $dst eq '';
102                if($src eq 'MKDIR')
103                {
104                        # actually we just need to make a directory here
105                        mkdir "$base_name/$dst",0755;
106                }
107                elsif($src eq 'LICENSE')
108                {
109                        $current_license = $dst;
110                }
111                elsif($src eq 'REPLACE-VERSION-IN')
112                {
113                        replace_version_in($dst);
114                }
115                elsif($src eq 'RUN')
116                {
117                        my ($junk,$cmd) = split /\s+/, $line, 2;
118                        print "Running $cmd...\n";
119                        if(system($cmd) != 0)
120                        {
121                                print "Error running $cmd. Aborting.\n";
122                                exit(1);
123                        }
124                }
125                elsif(-d $src)
126                {
127                        $modules_included{$line} = 1;
128                        copy_dir($src,$dst);
129                }
130                else
131                {
132                        copy_file($src,$dst);
133                }
134        }
135       
136        close LIST;
137}
138copy_from_list("distribution/COMMON-MANIFEST.txt");
139copy_from_list("$dist_root/DISTRIBUTION-MANIFEST.txt");
140
141# Copy in the root directory and delete the DISTRIBUTION-MANIFEST file
142(system("cp $dist_root/*.* $base_name/") == 0)
143        or die "Copy of root extra files failed";
144unlink "$base_name/DISTRIBUTION-MANIFEST.txt"
145        or die "Delete of DISTRIBUTION-MANIFEST.txt file failed";
146replace_version_in("VERSION.txt");
147
148# produce a new modules file
149my $modules = gensym;
150open $modules,"modules.txt" or die "Can't open modules.txt for reading";
151open MODULES_OUT,">$base_name/modules.txt";
152
153while(<$modules>)
154{
155        # skip lines for modules which aren't included
156        next if m/\A(\w+\/\w+)\s/ && !exists $modules_included{$1};
157       
158        # skip private sections
159        unless(skip_non_applicable_section($_, $modules, 'modules.txt'))
160        {
161                # copy line to out files
162                print MODULES_OUT
163        }
164}
165
166close MODULES_OUT;
167close $modules;
168
169# report on how many private sections were removed
170print "Private sections removed: $private_sections_removed\nNon-distribution sections removed: $non_distribution_sections_removed\n";
171
172# tar it up
173system "tar cf - $base_name | gzip -9 - > $base_name.tgz";
174
175sub copy_file
176{
177        my ($fn,$dst_fn) = @_;
178       
179        my $ext;
180        $ext = $1 if $fn =~ m/\.(\w+)\Z/;
181        $dst_fn =~ m~\A(.+)/[^/]+?\Z~;
182       
183        # licensed or not?
184        if(exists $comment_chars{$ext} && $current_license ne "none")
185        {
186                # copy as text, inserting license
187                # print "source copy $fn to $base_name/$dst_fn\n";
188
189                my $in = gensym;
190                open $in,$fn or die "$fn: $!";
191                open OUT,">$base_name/$dst_fn" or die "$base_name/$dst_fn: $!";
192               
193                my $first = <$in>;
194                if($first =~ m/\A#!/)
195                {
196                        print OUT $first;
197                        $first = '';
198                }
199               
200                # write license
201                my $b = $comment_chars{$ext};
202                my $this_license = $license_text{$current_license};
203                for (@$this_license)
204                {
205                        print OUT $b, $_;
206                }
207               
208                if($first ne '')
209                {
210                        print OUT $first;
211                }
212               
213                while(<$in>)
214                {
215                        unless(skip_non_applicable_section($_, $in, $fn))
216                        {
217                                print OUT
218                        }
219                }       
220               
221                close OUT;
222                close $in;
223        }
224        elsif(exists $text_files{$ext})
225        {
226                # copy this as text, to remove private stuff
227                # print "text copy $fn to $base_name/$dst_fn\n";
228
229                my $in = gensym;
230                open $in,$fn or die "$fn: $!";
231                open OUT,">$base_name/$dst_fn" or die "$base_name/$dst_fn: $!";
232
233                while(<$in>)
234                {
235                        unless(skip_non_applicable_section($_, $in, $fn))
236                        {
237                                print OUT
238                        }
239                }       
240
241                close OUT;
242                close $in;
243        }
244        else
245        {
246                # copy as binary
247                # print "binary copy $fn to $base_name/$dst_fn\n";
248                my $cmd = "cp -p $fn $base_name/$dst_fn";
249                system($cmd) == 0 or die "copy failed: $cmd";
250        }
251       
252        # copy executable bit from src
253        if(-x $fn)
254        {
255                system 'chmod','a+x',"$base_name/$dst_fn"
256        }
257        else
258        {
259                system 'chmod','a-x',"$base_name/$dst_fn"
260        }
261}
262
263sub skip_non_applicable_section
264{
265        my ($l, $filehandle, $filename) = @_;
266        if($l =~ m/BOX_PRIVATE_BEGIN/)
267        {
268                # skip private section
269                print "Removing private section from $filename\n";
270                $private_sections_removed++;
271                while(<$filehandle>) {last if m/BOX_PRIVATE_END/}
272               
273                # skipped something
274                return 1;
275        }
276        elsif($l =~ m/IF_DISTRIBUTION\((.+?)\)/)
277        {
278                # which distributions does this apply to?
279                my $applies = 0;
280                for(split /,/,$1)
281                {
282                        $applies = 1 if $_ eq $distribution
283                }
284                unless($applies)
285                {
286                        # skip section?
287                        print "Removing distribution specific section from $filename\n";
288                        $non_distribution_sections_removed++;
289                        while(<$filehandle>) {last if m/END_IF_DISTRIBUTION/}
290                }
291                # hide this line
292                return 1;
293        }
294        elsif($l =~ m/END_IF_DISTRIBUTION/)
295        {
296                # hide these lines
297                return 1;
298        }
299        else
300        {
301                # no skipping, return this line
302                return 0;
303        }
304}
305
306sub copy_dir
307{
308        my ($dir,$dst_dir) = @_;
309
310        # copy an entire directory... first make sure it exists
311        my @n = split /\//,$dst_dir;
312        my $d = $base_name;
313        for(@n)
314        {
315                $d .= '/';
316                $d .= $_;
317                mkdir $d,0755;
318        }
319       
320        # then do each of the files within in
321        opendir DIR,$dir;
322        my @items = readdir DIR;
323        closedir DIR;
324       
325        for(@items)
326        {
327                next if m/\A\./;
328                next if m/\A_/;
329                next if m/\AMakefile\Z/;
330                next if m/\Aautogen/;
331                next if m/-smf-method\Z/; # copy only the .in versions
332                next if m/-manifest.xml\Z/; # copy only the .in versions
333                if($dir eq 'docs') {
334                        next if m/.(x[sm]l|tmpl)\Z/; # don't include doc sources
335                        next if m/generate_except_xml.pl/;
336                }
337                next if !-f "$dir/$_";
338               
339                copy_file("$dir/$_","$dst_dir/$_");
340        }
341}
342
343sub replace_version_in
344{
345        my ($file) = @_;
346       
347        my $fn = $base_name . '/' . $file;
348        open IN,$fn or die "Can't open $fn";
349        open OUT,'>'.$fn.'.new' or die "Can't open $fn.new for writing";
350       
351        while(<IN>)
352        {
353                s/###DISTRIBUTION-VERSION-NUMBER###/$version/g;
354                s/.*USE_SVN_VERSION.*/$version/g;
355                print OUT
356        }
357       
358        close OUT;
359        close IN;
360
361        rename($fn.'.new', $fn) or die "Can't rename in place $fn";
362}
363
Note: See TracBrowser for help on using the repository browser.