1*cdf0e10cSrcweir:
2*cdf0e10cSrcweireval 'exec perl -wS $0 ${1+"$@"}'
3*cdf0e10cSrcweir    if 0;
4*cdf0e10cSrcweir#*************************************************************************
5*cdf0e10cSrcweir#
6*cdf0e10cSrcweir# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7*cdf0e10cSrcweir#
8*cdf0e10cSrcweir# Copyright 2000, 2010 Oracle and/or its affiliates.
9*cdf0e10cSrcweir#
10*cdf0e10cSrcweir# OpenOffice.org - a multi-platform office productivity suite
11*cdf0e10cSrcweir#
12*cdf0e10cSrcweir# This file is part of OpenOffice.org.
13*cdf0e10cSrcweir#
14*cdf0e10cSrcweir# OpenOffice.org is free software: you can redistribute it and/or modify
15*cdf0e10cSrcweir# it under the terms of the GNU Lesser General Public License version 3
16*cdf0e10cSrcweir# only, as published by the Free Software Foundation.
17*cdf0e10cSrcweir#
18*cdf0e10cSrcweir# OpenOffice.org is distributed in the hope that it will be useful,
19*cdf0e10cSrcweir# but WITHOUT ANY WARRANTY; without even the implied warranty of
20*cdf0e10cSrcweir# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21*cdf0e10cSrcweir# GNU Lesser General Public License version 3 for more details
22*cdf0e10cSrcweir# (a copy is included in the LICENSE file that accompanied this code).
23*cdf0e10cSrcweir#
24*cdf0e10cSrcweir# You should have received a copy of the GNU Lesser General Public License
25*cdf0e10cSrcweir# version 3 along with OpenOffice.org.  If not, see
26*cdf0e10cSrcweir# <http://www.openoffice.org/license.html>
27*cdf0e10cSrcweir# for a copy of the LGPLv3 License.
28*cdf0e10cSrcweir#
29*cdf0e10cSrcweir#*************************************************************************
30*cdf0e10cSrcweir#
31*cdf0e10cSrcweir#
32*cdf0e10cSrcweir# checkdeliver.pl - compare delivered files on solver with those on SRC_ROOT
33*cdf0e10cSrcweir#
34*cdf0e10cSrcweir
35*cdf0e10cSrcweiruse strict;
36*cdf0e10cSrcweiruse Getopt::Long;
37*cdf0e10cSrcweiruse File::stat;
38*cdf0e10cSrcweiruse IO::Handle;
39*cdf0e10cSrcweir
40*cdf0e10cSrcweiruse lib ("$ENV{SOLARENV}/bin/modules");
41*cdf0e10cSrcweir
42*cdf0e10cSrcweir#### globals #####
43*cdf0e10cSrcweir
44*cdf0e10cSrcweirmy $err              = 0;
45*cdf0e10cSrcweirmy $srcrootdir       = '';
46*cdf0e10cSrcweirmy $solverdir        = '';
47*cdf0e10cSrcweirmy $platform         = '';
48*cdf0e10cSrcweirmy $logfile          = '';
49*cdf0e10cSrcweirmy $milestoneext     = '';
50*cdf0e10cSrcweirmy $local_env        = 0;
51*cdf0e10cSrcweirmy @exceptionmodlist = (
52*cdf0e10cSrcweir                        "postprocess",
53*cdf0e10cSrcweir                        "instset.*native",
54*cdf0e10cSrcweir                        "smoketest.*native",
55*cdf0e10cSrcweir                        "testautomation",
56*cdf0e10cSrcweir                        "testgraphical"
57*cdf0e10cSrcweir                       ); # modules not yet delivered
58*cdf0e10cSrcweir
59*cdf0e10cSrcweir#### main #####
60*cdf0e10cSrcweir
61*cdf0e10cSrcweirprint_logged("checkdeliver.pl - checking delivered binaries\n");
62*cdf0e10cSrcweir
63*cdf0e10cSrcweirget_globals();                                  # get global variables
64*cdf0e10cSrcweirmy $deliverlists_ref = get_deliver_lists();     # get deliver log files
65*cdf0e10cSrcweirforeach my $listfile ( @$deliverlists_ref ) {
66*cdf0e10cSrcweir    $err += check( $listfile );                 # check delivered files
67*cdf0e10cSrcweir}
68*cdf0e10cSrcweirprint_logged("OK\n") if ( ! $err );
69*cdf0e10cSrcweirexit $err;
70*cdf0e10cSrcweir
71*cdf0e10cSrcweir#### subroutines ####
72*cdf0e10cSrcweir
73*cdf0e10cSrcweirsub get_globals
74*cdf0e10cSrcweir# set global variables using environment variables and command line options
75*cdf0e10cSrcweir{
76*cdf0e10cSrcweir    my $help;
77*cdf0e10cSrcweir
78*cdf0e10cSrcweir    # set global variables according to environnment
79*cdf0e10cSrcweir    $platform      = $ENV{INPATH};
80*cdf0e10cSrcweir    $srcrootdir    = $ENV{SOURCE_ROOT_DIR};
81*cdf0e10cSrcweir    $solverdir     = $ENV{SOLARVERSION};
82*cdf0e10cSrcweir    $milestoneext  = $ENV{UPDMINOREXT};
83*cdf0e10cSrcweir
84*cdf0e10cSrcweir    # override environment with command line options
85*cdf0e10cSrcweir    GetOptions('help' => \$help,
86*cdf0e10cSrcweir               'l=s'  => \$logfile,
87*cdf0e10cSrcweir               'p=s'  => \$platform
88*cdf0e10cSrcweir    ) or usage (1);
89*cdf0e10cSrcweir
90*cdf0e10cSrcweir    if ( $help ) {
91*cdf0e10cSrcweir        usage(0);
92*cdf0e10cSrcweir    }
93*cdf0e10cSrcweir
94*cdf0e10cSrcweir    #do some sanity checks
95*cdf0e10cSrcweir    if ( ! ( $platform && $srcrootdir && $solverdir ) ) {
96*cdf0e10cSrcweir        die "Error: please set environment\n";
97*cdf0e10cSrcweir    }
98*cdf0e10cSrcweir    if ( ! -d $solverdir ) {
99*cdf0e10cSrcweir        die "Error: cannot find solver directory '$solverdir'\n";
100*cdf0e10cSrcweir    }
101*cdf0e10cSrcweir
102*cdf0e10cSrcweir    # Check for local env., taken from solenv/bin/modules/installer/control.pm
103*cdf0e10cSrcweir    # In this case the content of SOLARENV starts with the content of SOL_TMP
104*cdf0e10cSrcweir    my $solarenv = "";
105*cdf0e10cSrcweir    my $sol_tmp;
106*cdf0e10cSrcweir    if ( $ENV{'SOLARENV'} ) {
107*cdf0e10cSrcweir        $solarenv = $ENV{'SOLARENV'};
108*cdf0e10cSrcweir    }
109*cdf0e10cSrcweir    if ( $ENV{'SOL_TMP'} ) {
110*cdf0e10cSrcweir        $sol_tmp = $ENV{'SOL_TMP'};
111*cdf0e10cSrcweir    }
112*cdf0e10cSrcweir    if ( defined $sol_tmp && ( $solarenv =~ /^\s*\Q$sol_tmp\E/ )) {
113*cdf0e10cSrcweir        # Content of SOLARENV starts with the content of SOL_TMP: Local environment
114*cdf0e10cSrcweir        $local_env = 1;
115*cdf0e10cSrcweir    }
116*cdf0e10cSrcweir}
117*cdf0e10cSrcweir
118*cdf0e10cSrcweirsub get_deliver_lists
119*cdf0e10cSrcweir# find deliver log files on solver
120*cdf0e10cSrcweir{
121*cdf0e10cSrcweir    my @files;
122*cdf0e10cSrcweir    my $pattern = "$solverdir/$platform/inc";
123*cdf0e10cSrcweir    $pattern .= "$milestoneext" if ( $milestoneext );
124*cdf0e10cSrcweir    $pattern .= "/*/deliver.log";
125*cdf0e10cSrcweir
126*cdf0e10cSrcweir    @files = glob( $pattern );
127*cdf0e10cSrcweir    # do not check modules not yet built
128*cdf0e10cSrcweir    foreach my $exceptionpattern ( @exceptionmodlist ) {
129*cdf0e10cSrcweir        @files = grep ! /\/$exceptionpattern\//, @files;
130*cdf0e10cSrcweir    }
131*cdf0e10cSrcweir    if ( ! @files ) {
132*cdf0e10cSrcweir        print_logged( "Error: cannot find deliver log files\n" );
133*cdf0e10cSrcweir        exit 1;
134*cdf0e10cSrcweir    }
135*cdf0e10cSrcweir    return \@files;
136*cdf0e10cSrcweir}
137*cdf0e10cSrcweir
138*cdf0e10cSrcweirsub check
139*cdf0e10cSrcweir# reads deliver log file given as parameter and compares pairs of files listed there.
140*cdf0e10cSrcweir{
141*cdf0e10cSrcweir    my $listname = shift;
142*cdf0e10cSrcweir    my $error = 0;
143*cdf0e10cSrcweir    my %delivered;
144*cdf0e10cSrcweir    my $module;
145*cdf0e10cSrcweir    my $repository;
146*cdf0e10cSrcweir    STDOUT->autoflush(1);
147*cdf0e10cSrcweir    # which module are we checking?
148*cdf0e10cSrcweir    if ( $listname =~ /\/([\w-]+?)\/deliver\.log$/o) {
149*cdf0e10cSrcweir        $module = $1;
150*cdf0e10cSrcweir    } else {
151*cdf0e10cSrcweir        print_logged( "Error: cannot determine module name from \'$listname\'\n" );
152*cdf0e10cSrcweir        return 1;
153*cdf0e10cSrcweir    }
154*cdf0e10cSrcweir
155*cdf0e10cSrcweir    if ( -z $listname ) {
156*cdf0e10cSrcweir        print_logged( "Warning: empty deliver log file \'$listname\'. Module '$module' not delivered correctly?\n\n" );
157*cdf0e10cSrcweir        return 0;
158*cdf0e10cSrcweir    }
159*cdf0e10cSrcweir
160*cdf0e10cSrcweir    # read deliver log file
161*cdf0e10cSrcweir    if ( ! open( DELIVERLOG, "< $listname" ) ) {
162*cdf0e10cSrcweir        print_logged( "Error: cannot open file \'$listname\'\n$!" );
163*cdf0e10cSrcweir        exit 2;
164*cdf0e10cSrcweir    }
165*cdf0e10cSrcweir    while ( <DELIVERLOG> ) {
166*cdf0e10cSrcweir        next if ( /^LINK / );
167*cdf0e10cSrcweir        # What's this modules' repository?
168*cdf0e10cSrcweir        if ( /COPY\s+(.+?)\/$module\/prj\/build.lst/ ) {
169*cdf0e10cSrcweir#        if ( /COPY (\w[\w\s-]*?)\/$module\/prj\/build.lst/ ) {
170*cdf0e10cSrcweir            $repository = $1;
171*cdf0e10cSrcweir        }
172*cdf0e10cSrcweir        # For now we concentrate on binaries, located in 'bin' or 'lib' and 'misc/build/<...>/[bin|lib]'.
173*cdf0e10cSrcweir        next if ( (! /\/$module\/$platform\/[bl]i[nb]\//) && (! /\/$module\/$platform\/misc\/build\//));
174*cdf0e10cSrcweir        next if (! /[bl]i[nb]/);
175*cdf0e10cSrcweir        next if ( /\.html$/ );
176*cdf0e10cSrcweir        chomp;
177*cdf0e10cSrcweir        if ( /^\w+? (\S+) (\S+)\s*$/o ) {
178*cdf0e10cSrcweir            my $origin = $1;
179*cdf0e10cSrcweir            $delivered{$origin} = $2;
180*cdf0e10cSrcweir        } else {
181*cdf0e10cSrcweir            print_logged( "Warning: cannot parse \'$listname\' line\n\'$_\'\n" );
182*cdf0e10cSrcweir        }
183*cdf0e10cSrcweir    }
184*cdf0e10cSrcweir    close( DELIVERLOG );
185*cdf0e10cSrcweir
186*cdf0e10cSrcweir    if ( ! $repository ) {
187*cdf0e10cSrcweir        print_logged( "Error parsing \'$listname\': cannot determine repository. Module '$module' not delivered correctly?\n\n" );
188*cdf0e10cSrcweir        $error ++;
189*cdf0e10cSrcweir        return $error;
190*cdf0e10cSrcweir    }
191*cdf0e10cSrcweir
192*cdf0e10cSrcweir    my $path = "$srcrootdir/$repository/$module";
193*cdf0e10cSrcweir    # is module physically accessible?
194*cdf0e10cSrcweir    # there are valid use cases where we build against a prebuild solver whithout having
195*cdf0e10cSrcweir    # all modules at disk
196*cdf0e10cSrcweir    my $canread = is_moduledirectory( $path );
197*cdf0e10cSrcweir    if ( ! $canread ) {
198*cdf0e10cSrcweir        # do not bother about non existing modules in local environment
199*cdf0e10cSrcweir        # or on childworkspaces
200*cdf0e10cSrcweir        if (( $local_env ) || ( $ENV{CWS_WORK_STAMP} )) {
201*cdf0e10cSrcweir            return $error;
202*cdf0e10cSrcweir        }
203*cdf0e10cSrcweir        # in a master build it is considered an error to have deliver leftovers
204*cdf0e10cSrcweir        # from non exising (removed) modules
205*cdf0e10cSrcweir        print_logged( "Error: module '$module' not found.\n" );
206*cdf0e10cSrcweir        $error++;
207*cdf0e10cSrcweir        return $error;
208*cdf0e10cSrcweir    }
209*cdf0e10cSrcweir    if ( $canread == 2 ) {
210*cdf0e10cSrcweir        # module is linked and not built, no need for checking
211*cdf0e10cSrcweir        # should not happen any more nowadays ...
212*cdf0e10cSrcweir        return $error;
213*cdf0e10cSrcweir    }
214*cdf0e10cSrcweir
215*cdf0e10cSrcweir    # compare all delivered files with their origin
216*cdf0e10cSrcweir    # no strict 'diff' allowed here, as deliver may alter files (hedabu, strip, ...)
217*cdf0e10cSrcweir    foreach my $file ( sort keys %delivered ) {
218*cdf0e10cSrcweir        my $ofile = "$srcrootdir/$file";
219*cdf0e10cSrcweir        my $sfile = "$solverdir/$delivered{$file}";
220*cdf0e10cSrcweir        if ( $milestoneext ) {
221*cdf0e10cSrcweir            # deliver log files do not contain milestone extension on solver
222*cdf0e10cSrcweir            $sfile =~ s/\/$platform\/(...)\//\/$platform\/$1$milestoneext\//;
223*cdf0e10cSrcweir        }
224*cdf0e10cSrcweir        my $orgfile_stats = stat($ofile);
225*cdf0e10cSrcweir        next if ( -d _ );  # compare files, not directories
226*cdf0e10cSrcweir        my $delivered_stats = lstat($sfile);
227*cdf0e10cSrcweir        next if ( -d _ );  # compare files, not directories
228*cdf0e10cSrcweir        if ( $^O !~ /^MSWin/ ) {
229*cdf0e10cSrcweir            # windows does not know about links.
230*cdf0e10cSrcweir            # Therefore lstat() is not a lstat, and the following check would break
231*cdf0e10cSrcweir            next if ( -l _ );  # compare files, not links
232*cdf0e10cSrcweir        }
233*cdf0e10cSrcweir
234*cdf0e10cSrcweir        if ( $orgfile_stats && $delivered_stats ) {
235*cdf0e10cSrcweir            # Stripping (on unix like platforms) and signing (for windows)
236*cdf0e10cSrcweir            # changes file size. Therefore we have to compare for file dates.
237*cdf0e10cSrcweir            # File modification time also can change after deliver, f.e. by
238*cdf0e10cSrcweir            # rebasing, but only increase. It must not happen that a file on
239*cdf0e10cSrcweir            # solver is older than it's source.
240*cdf0e10cSrcweir            if ( ( $orgfile_stats->mtime - $delivered_stats->mtime ) gt 1 ) {
241*cdf0e10cSrcweir                print_logged( "Error: " );
242*cdf0e10cSrcweir                print_logged( "delivered file is older than it's source '$ofile' '$sfile'\n" );
243*cdf0e10cSrcweir                $error ++;
244*cdf0e10cSrcweir            }
245*cdf0e10cSrcweir        } elsif ( !$orgfile_stats && $delivered_stats ) {
246*cdf0e10cSrcweir            # This is not an error if we have a solver and did not build the
247*cdf0e10cSrcweir            # module!
248*cdf0e10cSrcweir        } elsif ( !$orgfile_stats && !$delivered_stats ) {
249*cdf0e10cSrcweir            # This is not necessarily an error.
250*cdf0e10cSrcweir            # Instead, this seems to be an error of the deliver.log file.
251*cdf0e10cSrcweir        } else {
252*cdf0e10cSrcweir            print_logged( "Error: no such file '$ofile'\n" ) if ( ! $orgfile_stats );
253*cdf0e10cSrcweir            print_logged( "Error: no such file '$sfile'\n" ) if ( ! $delivered_stats );
254*cdf0e10cSrcweir            $error ++;
255*cdf0e10cSrcweir        }
256*cdf0e10cSrcweir    }
257*cdf0e10cSrcweir    if ( $error ) {
258*cdf0e10cSrcweir        print_logged( "$error errors found: Module '$module' not delivered correctly?\n\n" );
259*cdf0e10cSrcweir    }
260*cdf0e10cSrcweir    STDOUT->autoflush(0);
261*cdf0e10cSrcweir    return $error;
262*cdf0e10cSrcweir}
263*cdf0e10cSrcweir
264*cdf0e10cSrcweirsub is_moduledirectory
265*cdf0e10cSrcweir# Test whether we find a module having a d.lst file at a given path.
266*cdf0e10cSrcweir# Return value: 1: path is valid directory
267*cdf0e10cSrcweir#               2: path.link is a valid link
268*cdf0e10cSrcweir#               0: module not found
269*cdf0e10cSrcweir{
270*cdf0e10cSrcweir    my $dirname = shift;
271*cdf0e10cSrcweir    if ( -e "$dirname/prj/d.lst" ) {
272*cdf0e10cSrcweir        return 1;
273*cdf0e10cSrcweir    } elsif ( -e "$dirname.link/prj/d.lst" ) {
274*cdf0e10cSrcweir        return 2
275*cdf0e10cSrcweir    } else {
276*cdf0e10cSrcweir        return 0;
277*cdf0e10cSrcweir    }
278*cdf0e10cSrcweir}
279*cdf0e10cSrcweir
280*cdf0e10cSrcweirsub print_logged
281*cdf0e10cSrcweir# Print routine.
282*cdf0e10cSrcweir# If a log file name is specified with '-l' option, print_logged() prints to that file
283*cdf0e10cSrcweir# as well as to STDOUT. If '-l' option is not set, print_logged() just writes to STDOUT
284*cdf0e10cSrcweir{
285*cdf0e10cSrcweir    my $message = shift;
286*cdf0e10cSrcweir    print "$message";
287*cdf0e10cSrcweir    if ( $logfile ) {
288*cdf0e10cSrcweir        open ( LOGFILE, ">> $logfile" ) or die "Can't open logfile '$logfile'\n";
289*cdf0e10cSrcweir        print LOGFILE "$message";
290*cdf0e10cSrcweir        close ( LOGFILE) ;
291*cdf0e10cSrcweir    }
292*cdf0e10cSrcweir}
293*cdf0e10cSrcweir
294*cdf0e10cSrcweir
295*cdf0e10cSrcweirsub usage
296*cdf0e10cSrcweir# print usage message and exit
297*cdf0e10cSrcweir{
298*cdf0e10cSrcweir    my $retval = shift;
299*cdf0e10cSrcweir    print STDERR "Usage: checkdeliver.pl [-h] [-p <platform>]\n";
300*cdf0e10cSrcweir    print STDERR "Compares delivered files on solver with original ones in build tree\n";
301*cdf0e10cSrcweir    print STDERR "Options:\n";
302*cdf0e10cSrcweir    print STDERR "    -h              print this usage message\n";
303*cdf0e10cSrcweir    print STDERR "    -p platform     specify platform\n";
304*cdf0e10cSrcweir
305*cdf0e10cSrcweir    exit $retval;
306*cdf0e10cSrcweir}
307*cdf0e10cSrcweir
308