1:
2    eval 'exec perl -S $0 ${1+"$@"}'
3        if 0;
4#**************************************************************
5#
6#  Licensed to the Apache Software Foundation (ASF) under one
7#  or more contributor license agreements.  See the NOTICE file
8#  distributed with this work for additional information
9#  regarding copyright ownership.  The ASF licenses this file
10#  to you under the Apache License, Version 2.0 (the
11#  "License"); you may not use this file except in compliance
12#  with the License.  You may obtain a copy of the License at
13#
14#    http://www.apache.org/licenses/LICENSE-2.0
15#
16#  Unless required by applicable law or agreed to in writing,
17#  software distributed under the License is distributed on an
18#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19#  KIND, either express or implied.  See the License for the
20#  specific language governing permissions and limitations
21#  under the License.
22#
23#**************************************************************
24
25
26
27use Cwd;
28use File::Temp qw/ tempfile tempdir /;
29
30my $verbosity = 1;  # will be adjusted to the value of $Env{VERBOSE} below
31
32# platforms which are not supported anymore, and thus can be filtered from the svn:ignore list
33my %obsolete_platforms = (
34    );
35    # (none so far)
36
37# platforms whose output trees should appear in all modules' svn:ignore list
38my @platforms = (
39        "common",
40        "unxlngi6",
41        "unxlngx6",
42        "unxsols4",
43        "unxsolu4",
44        "unxsoli4",
45        "wntmsci12",
46        "unxmacxi",
47        "unxmacxp",
48        "unxmacci",
49        "unxmaccx",
50        "unxubit8",
51        "unxaixp",
52        "unxbsda",
53        "unxbsdi2",
54        "unxbsdi",
55        "unxbsds",
56        "unxfbsdi",
57        "unxfbsd",
58        "unxfbsdx",
59        "unxhpgr",
60        "unxhpxr",
61        "unxirgm",
62        "unxirxm3",
63        "unxirxm",
64        "unxlnga",
65        "unxlngm68k",
66        "unxlngmips",
67        "unxlngp",
68        "unxlngppc4",
69        "unxlngppc64",
70        "unxlngppc",
71        "unxlngr",
72        "unxlngs3904",
73        "unxlngs390x",
74        "unxlngs",
75        "unxlnxi",
76        "unxsogi",
77        "unxsogs"
78    );
79
80
81# .........................................................................
82# retrieves the repository URL of the SVN working copy in the current directory
83sub retrieve_repo_url
84{
85    open( SVN, "svn info 2>&1 |" );
86    my @result = <SVN>;
87    close( SVN );
88
89    foreach (@result)
90    {
91        chomp;
92        next if ( ! /^URL: / );
93        s/^URL: //;
94        return $_;
95    }
96    return undef;
97}
98
99# .........................................................................
100# gets the "modules" below the given SVN repository URL, by calling "svn list"
101sub get_modules
102{
103    my @modules = ();
104
105    open( SVN, "svn list $_ 2>&1 |" );
106    my @result = <SVN>;
107    close( SVN );
108
109    foreach (@result)
110    {
111        chomp;
112        s/\/$//;
113        push @modules, $_;
114    }
115
116    return @modules;
117}
118
119# .........................................................................
120sub set_ignore_property
121{
122    my ($repo_url, @modules) = @_;
123
124    # max length of a module name
125    my $max_len = 0;
126    foreach ( @modules ) { $max_len = length( $_ ) if ( length( $_ ) > $max_len ); }
127
128    my $updated = 0;
129
130    my $current = 0;
131    my $count = $#modules + 1;
132    foreach $module ( @modules )
133    {
134        ++$current;
135
136        # print progress
137        if ( $verbosity > 1 )
138        {
139            my $progress = "$module ";
140            $progress .= "(" . $current . "/" . $count . ")";
141
142            my $dots = 3 + ( $max_len - length($module) );
143            $dots += int( digits( $count ) ) - int( digits( $current ) );
144
145            $progress .= ( "." x $dots );
146            $progress .= " ";
147
148            print STDOUT $progress;
149        }
150        elsif ( $verbosity > 0 )
151        {
152            print STDOUT ".";
153        }
154
155        # retrieve the current ignore list
156        open( SVN, "svn propget svn:ignore $module 2>&1 |" );
157        my @ignore_list = <SVN>;
158        close( SVN );
159
160        # the last item in the list is an empty string, usually. Don't let it confuse the below
161        # code
162        my $supposed_empty = pop @ignore_list;
163        chomp( $supposed_empty );
164        push( @ignore_list, $supposed_empty ) if ( !( $supposed_empty =~ /^$/ ) );
165
166        # filter out obsolte entries
167        my @stripped_ignore_list = ();
168        foreach $ignore_entry (@ignore_list)
169        {
170            chomp( $ignore_entry );
171            next if ( $ignore_entry =~ /^$/ );
172
173            if  (   ( exists $obsolete_platforms{$ignore_entry} )
174                ||  ( exists $obsolete_platforms{"$ignore_entry.pro"} )
175                )
176            {
177                next;
178            }
179            push @stripped_ignore_list, $ignore_entry;
180        }
181        my $removed = $#ignore_list - $#stripped_ignore_list;
182        @ignore_list = @stripped_ignore_list;
183
184        # append the platforms which should appear in the ignore list
185        my %ignore_list = ();
186        foreach (@ignore_list) { $ignore_list{$_} = 1; }
187        foreach $platform_entry ( @platforms )
188        {
189            $ignore_list{$platform_entry} = 1;
190            $ignore_list{"$platform_entry.pro"} = 1;
191        }
192        my @extended_ignore_list = keys %ignore_list;
193        my $added = $#extended_ignore_list - $#ignore_list;
194        @ignore_list = @extended_ignore_list;
195
196        if ( $removed || $added )
197        {
198            # create a temporary file taking the new content of the svn_ignore property
199            my $temp_dir = tempdir( CLEANUP => 1 );
200            my ($fh, $filename) = tempfile( DIR => $dir );
201            open( IGNORE, ">$filename" );
202            print IGNORE join "\n", @ignore_list;
203            close( IGNORE );
204
205            # actually set the property
206            open( SVN, "svn propset -F $filename svn:ignore $module 2>&1 |" );
207
208            ++$updated;
209        }
210
211        # statistics
212        print STDOUT "done (removed/added: $removed/$added)\n" if $verbosity > 1;
213    }
214
215    print STDOUT "\n" if $verbosity eq 1;
216    print STDOUT "$updated module(s) updated\n" if $verbosity > 0;
217}
218
219# .........................................................................
220sub digits
221{
222    my ($number, $base) = @_;
223    $base = 10 if !defined $base;
224    return log($number)/log($base);
225}
226
227# .........................................................................
228# 'main'
229
230# initialize verbosity
231my $verbose = $ENV{VERBOSE};
232if ( defined $verbose )
233{
234    $verbose = uc( $verbose );
235    $verbosity = 2 if ( $verbose eq "TRUE" );
236    $verbosity = 0 if ( $verbose eq "FALSE" );
237}
238
239# work on the current directory
240my $working_copy_root = cwd();
241die "current directory does not contain an SVN working copy" if !-d $working_copy_root . "/\.svn";
242
243# retrieve repository URL
244my $repo_url = retrieve_repo_url();
245die "unable to retrieve repository URL" if !defined $repo_url;
246print STDOUT "repository URL: $repo_url\n" if $verbosity > 1;
247
248# list modules
249my @modules = get_modules( $repo_url );
250print STDOUT "processing " . ( $#modules + 1 ) . " modules\n" if $verbosity > 0;
251
252# process modules, by setting the svn:ignore property
253set_ignore_property( $repo_url, @modules );
254