Subversion Repositories DevTools

Rev

Rev 7300 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6133 dpurdie 1
########################################################################
7300 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
6133 dpurdie 3
#
4
# Module name   : ToolsetFiles.pm
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Provide access to the file GbeFiles.cfg
10
#                 Provides methods to create, maintain and read the file
11
#                 
12
#                 ToolsetFiles::AddFile
13
#                 ToolsetFiles::AddDir
14
#                 ToolsetFiles::GetFiles
7312 dpurdie 15
#                 ToolsetFiles::GetBuildDirs
6133 dpurdie 16
#                 ToolsetFiles::GetSubTrees
17
#                 ToolsetFiles::GetDataFile
18
#                 
19
#           Internal Use Only
20
#                 readData
21
#                 writeData
22
#                 rebuildSubdirList
7312 dpurdie 23
#                 rebuildParentDirList
6133 dpurdie 24
#
25
#......................................................................#
26
 
27
require 5.008_002;
28
use strict;
29
use warnings;
30
 
31
#===============================================================================
32
package ToolsetFiles;
33
use JatsError;
34
use FileUtils;
35
use ConfigurationFile;
36
 
37
# automatically export what we need into namespace of caller.
38
use Exporter();
39
our (@ISA, @EXPORT, %EXPORT_TAGS, @EXPORT_OK);
40
@ISA         = qw(Exporter);
41
@EXPORT      = qw();
42
@EXPORT_OK   = qw();
43
 
44
%EXPORT_TAGS = (All => [@EXPORT, @EXPORT_OK]);
45
 
46
#
47
#   Global variables
48
#
49
our %GBE_TOOLSETFiles;          # Needs to be 'our'. Data store
50
my $dataDir;                    # Path to the interface directory
51
my $dataFile;                   # Path to GbeFiles.cfg 
52
 
53
#-------------------------------------------------------------------------------
54
# Function        : ToolsetFiles::AddFile
55
#
56
# Description     : Maintain a data structure of files that are created
57
#                   by the makefile creation process.
58
#
59
#                   Used to simplify the clobber process
60
#                   All files 'added' will be deleted as a part of a clobber
61
#
62
#                   Maintains an on-disk data structure
63
#
64
# Inputs          : fileList        - Files to add to the list
65
#
66
# Returns         : Nothing
67
#
68
sub AddFile
69
{
70
    my (@fileList) = @_;
71
    Verbose2 ("ToolsetFile:", @fileList);
72
 
73
    #
74
    #   Read in the existing data
75
    #
76
    readData();
77
 
78
    # Capture the package root directory
79
    $GBE_TOOLSETFiles{Root} = FullPath($::ScmRoot)
80
        unless defined $GBE_TOOLSETFiles{Root};
81
 
82
    #
83
    # Save to disk if
84
    #   Target directory exists - creation may be delayed
85
    #   We have added entries
86
    #
87
    if ( @fileList )
88
    {
89
        #
90
        #   Add files
91
        #       Need to be full paths
92
        #       Paths are store relative to the Root
93
        #
94
        foreach ( @fileList )
95
        {
96
            $GBE_TOOLSETFiles{Files}{RelPath(FullPath($_), $GBE_TOOLSETFiles{Root} )} = 1;
97
        }
98
 
99
        #   Save file
100
        writeData();
101
    }
102
}
103
 
104
#-------------------------------------------------------------------------------
105
# Function        : GetFiles 
106
#
107
# Description     : Return an array of files from the stored data structure
108
#
7312 dpurdie 109
# Inputs          : $interface  - (Optional) Path to the interface directory
110
#                   $abs        - (Optional) True: Return Abs paths
6133 dpurdie 111
#
112
# Returns         : An array of files
113
#
114
sub GetFiles
115
{
7312 dpurdie 116
    my ($interface, $abs) = @_;
117
    readData($interface) || Error ("Internal: ToolsetFiles::GetFiles - GbeFiles not found");
118
 
119
    unless ($abs) {
120
        return keys %{$GBE_TOOLSETFiles{Files}};
121
    }
122
 
123
    my @newList;
124
    foreach my $dir (keys %{$GBE_TOOLSETFiles{Files}} ) {
125
        push @newList,CleanPath(catdir($GBE_TOOLSETFiles{Root}, $dir)); 
126
    }
127
 
128
    return @newList;
6133 dpurdie 129
}
130
 
131
#-------------------------------------------------------------------------------
7312 dpurdie 132
# Function        : GetBuildDirs
133
#
134
# Description     : Return an array the internal directories from the stored data structure
135
#
136
# Inputs          : $interface  - (Optional) Path to the interface directory
137
#
138
# Returns         : An array of files
139
#
140
sub GetBuildDirs
141
{
142
    my ($interface) = @_;
143
    readData($interface) || Error ("Internal: ToolsetFiles::GetBuildDirs - GbeFiles not found");
144
 
145
    my @newList;
146
    foreach my $dir (@{$GBE_TOOLSETFiles{Dirs}{Internal}} ) {
147
        push @newList,CleanPath(catdir($GBE_TOOLSETFiles{Root}, $dir)); 
148
    }
149
 
150
    return @newList;
151
}
152
 
153
 
154
#-------------------------------------------------------------------------------
6133 dpurdie 155
# Function        : ToolsetFiles::AddDir
156
#
157
# Description     : Maintain a data structure of directories that are used
158
#                   by the makefile creation process.
159
#
160
#                   Used to track directories used by the build. These are used
161
#                   to calculate package signatures and fingerprints
162
#
163
#                   Maintains an on-disk data structure
164
#
165
# Inputs          : $dir        - Files to add to the list
166
#                   $mode       - 'Internal', Include SubDir
167
#                   
168
#                   $mode=Internal 
169
#                       directories are ignored
170
#                           
171
#                   $mode=Include and SubDir
172
#                       Are processed to remove subdirectories
173
#                       Needing a list of distinct directory trees that are a 
174
#                       part of the build. Used to calculate signatures.
175
#                            
176
#
177
# Returns         : Nothing
178
#
179
sub AddDir
180
{
181
    my ($dir, $mode) = @_;
182
    Verbose2 ("ToolsetDir:", $dir, $mode);
183
    #
184
    #   Only track directories that exist
185
    return unless -d $dir;
186
 
187
    #
188
    #   Read in the existing data
189
    #
190
    readData();
191
 
192
    #
193
    #   Need to know the current directory in order to calculate the
194
    #   FullPath and others
195
    #
196
    Error ("Internal: ToolsetFiles. Cwd not defined")
197
        unless ( defined $::Cwd );
198
 
199
    # Capture the package root directory
200
    $GBE_TOOLSETFiles{Root} = FullPath($::ScmRoot)
201
        unless defined $GBE_TOOLSETFiles{Root};
202
 
203
    #
204
    # Save to disk if
205
    #   Target directory exists - creation may be delayed
206
    #   We have added entries
207
    #
208
    my $dirList = ($mode =~ m/Internal/i) ? 'Internal' : 'Src';
209
    if ( $dir )
210
    {
211
        #
212
        #   Add files - Need to be full paths
213
        #
214
        my $relDir = RelPath(FullPath($dir), $GBE_TOOLSETFiles{Root} );
215
 
216
        #
217
        #   Ignore Src directories that are a subdirectory of the current root dir
218
        #
219
        if (($relDir =~ m~^\.\.(/|$)~) || ($dirList eq 'Internal'))
220
        {
7312 dpurdie 221
            #
222
            #   Maintain @{$GBE_TOOLSETFiles{Dirs}} as a list of parent directories
223
            #       The Root directory is assumed
224
            #
6133 dpurdie 225
 
7312 dpurdie 226
            # Add the new item and rebuild the list
227
            @{$GBE_TOOLSETFiles{Dirs}{$dirList}} = rebuildParentDirList($relDir, @{$GBE_TOOLSETFiles{Dirs}{$dirList}});
6133 dpurdie 228
 
229
            #   Save file
230
            writeData();
231
        }
232
    }
233
}
234
 
235
#-------------------------------------------------------------------------------
236
# Function        : ToolsetFiles::GetSubTrees 
237
#
238
# Description     : Return an ordered list of directory subtrees used by the build
239
#                   These will be absolute paths
240
#                   
241
#                   This contains a list of all directories used by the build/make 
242
#                   as discovered when creating files. 
243
#                       IFF all source was below the build.pl dir, then we wouldn't need
244
#                       to do this and life would be much simpler (and faster)
245
#                       
246
#                   Used by the 'sandbox':
247
#                       To create a fingerprint over all files in a package.
248
#                   Used by 'buildlib':
249
#                       To create a signature of the package
250
#
251
# Inputs          : $interface  - (Optional) Path to the interface directory
252
#
253
# Returns         : Ordered list of absolute paths of all subdirectory trees discovered
254
#                   during the build phase.
255
#                   
256
#                   Needs to be the same order on all machines
257
#
258
sub GetSubTrees
259
{
260
    my ($interface) = @_;
261
    my @dirList;
262
 
263
    #
264
    #   Read in GbeFiles.cfg
265
    #   It must exist
266
    #
267
    readData($interface) || Error ("Internal: ToolsetFiles::GetSubTrees - GbeFiles not found");
268
 
269
    #
270
    #   Generate a list of directories in the package
271
    #   This is the root directory and all other Src directories discovered
272
    #
273
    push @dirList, $GBE_TOOLSETFiles{Root};
274
    if (exists $GBE_TOOLSETFiles{Dirs}{Src})
275
    {
276
        foreach my $dir ( sort {uc($a) cmp uc($b) } @{$GBE_TOOLSETFiles{Dirs}{Src}})
277
        {
278
            push @dirList,CleanPath(catdir($GBE_TOOLSETFiles{Root}, $dir)); 
279
        }
280
    }
281
 
282
    # Process the complete list to remove subdirectories
7312 dpurdie 283
    #   The paths are absolute
6133 dpurdie 284
    @dirList = rebuildSubdirList(@dirList);
285
#DebugDumpData("GetSubTrees", \@dirList);
286
    return @dirList;
287
}
288
#-------------------------------------------------------------------------------
289
# Function        : rebuildSubdirList 
290
#
291
# Description     : Internal function - not intended to be used externally
7312 dpurdie 292
#                   Only work when the @dirlist contains absolute paths
6133 dpurdie 293
# 
294
#                   Rebuild the subdirectory list
295
#                   Remove items that are subdirectories of other items
296
#                   We only want the parents, not children
297
#
298
# Inputs          : @dirList        - List of items to process 
299
#
300
# Returns         : Rebuild list
301
#
302
sub rebuildSubdirList
303
{
304
    #   Process the complete list to remove subdirectories
305
    #   Process is:
306
    #       Sort list. Will end up with shortest directories first, thus subdirs will follow parents
307
    #       Insert each item into a new list iff it is not a subdir of something already in the list
308
    #
309
    my @newList;
310
    my @dirList = sort {uc($a) cmp uc($b)} @_;
311
 
312
    foreach my $newItem ( @dirList )
313
    {
314
        my $match = 0;
315
        foreach my $item ( @newList )
316
        {
317
            if (index ($newItem, $item) == 0)
318
            {
319
                $match = 1;
320
                last;
321
            }
322
        }
323
        if (! $match)
324
        {
325
            push @newList, $newItem;
326
        }
327
   }
328
 
329
   return @newList;
330
}
331
 
332
#-------------------------------------------------------------------------------
7312 dpurdie 333
# Function        : rebuildParentDirList 
334
#
335
#
336
# Description     : Internal function - not intended to be used externally
337
#                   Only work when with relative paths
338
#                   
339
#                   Given: .., ../.., ../../AA Result: ../..
340
#                   Given  .., ../AA, ../BB    Result: .., ../AA, ../BB
341
#                   
342
#                   Must handle both parent and child directoires
343
# 
344
#                   Rebuild the subdirectory list
345
#                   Remove items that are subdirectories of other items
346
#                   We only want the parents, not children
347
#
348
# Inputs          : @dirList        - List of items to process 
349
#
350
# Returns         : Rebuild list
351
sub rebuildParentDirList
352
{
353
    my (@dirlist) = @_;
354
 
355
    #
356
    #   Convert to absolute
357
    #   Use rebuildSubdirList
358
    #   Convert back to relative
359
    #
360
    my @newList;
361
    foreach my $dir ( @dirlist ) {
362
        push @newList,CleanPath(catdir($GBE_TOOLSETFiles{Root}, $dir)); 
363
    }
364
 
365
    # Process the complete list to remove subdirectories
366
    #   The paths are now absolute
367
    @newList = rebuildSubdirList(@newList);
368
 
369
    #
370
    #   Convert back to Relative
371
    #
372
    my @relList;
373
    foreach my $dir ( @newList ) {
374
        push @relList, RelPath(FullPath($dir), $GBE_TOOLSETFiles{Root} );
375
    }
376
 
377
    return @relList;
378
}
379
 
380
 
381
#-------------------------------------------------------------------------------
6133 dpurdie 382
# Function        : GetDataFile 
383
#
384
# Description     : Return the full path to the data file
385
#                   May be used to test existence
386
#
387
# Inputs          : $interface - Path to the interface directory (Optional) 
388
#
389
# Returns         : Path to file, or undefined
390
#
391
sub GetDataFile
392
{
393
    my ($interface) = @_;
394
    #
395
    #   Use the global path to the interface directory
396
    #   unless specifically provided by the user
397
    #
398
    if ($interface) {
399
        $dataDir = $interface;
400
    } else {
401
        Error ("Internal: ToolsetFiles. ScmRoot or ScmInterface not defined")
402
            unless ( defined $::ScmRoot && defined $::ScmInterface );
403
        $dataDir = "$::ScmRoot/$::ScmInterface";
404
    }
405
    $dataFile = "$dataDir/GbeFiles.cfg";
406
 
407
    return $dataFile if (-f $dataFile );
408
    return undef;
409
}
410
 
411
 
412
#-------------------------------------------------------------------------------
413
# Function        : readData 
414
#
415
# Description     : Read the data file into memory
416
#                   Data may not be present
417
#
418
# Inputs          : $interface - Path to the interface directory (Optional) 
419
#
420
# Returns         : True - file found and read 
421
#
422
sub readData
423
{
424
    my ($interface) = @_;
425
 
426
    #
427
    #   Use the global path to the interface directory
428
    #   unless specifically provided by the user
429
    #
430
    if ($interface) {
431
        $dataDir = $interface;
432
    } else {
433
        Error ("Internal: ToolsetFiles. ScmRoot or ScmInterface not defined")
434
            unless ( defined $::ScmRoot && defined $::ScmInterface );
435
        $dataDir = "$::ScmRoot/$::ScmInterface";
436
    }
437
    $dataFile = "$dataDir/GbeFiles.cfg";
438
 
439
    #
440
    #   Read the file on every usage
441
    #   Its used in a nested program call structure so the data may be stale
442
    #
443
    if ( -f  $dataFile )
444
    {
445
        do $dataFile;
446
        return 1 if %GBE_TOOLSETFiles;
447
    }
448
 
449
    return 0;
450
}
451
 
452
 
453
#-------------------------------------------------------------------------------
454
# Function        : writeData 
455
#
456
# Description     : Write the data out to the physical file
457
#                   Simply rewrite the file - if the target directory exists
458
#                   Its creation may be after we have started accumulating files
459
#  
460
#
461
# Inputs          : 
462
#
463
# Returns         : 
464
#
465
sub writeData
466
{
467
    if ( -d $dataDir  ) {
468
        my $fh = ConfigurationFile::New( $dataFile );
469
        $fh->Header( "ToolsetFile", "Toolset Files" );
470
        $fh->Dump( [\%GBE_TOOLSETFiles], [qw(*GBE_TOOLSETFiles)] );
471
        $fh->Close();
472
    }
473
}
474
 
475
 
476
#------------------------------------------------------------------------------
477
1;