Subversion Repositories DevTools

Rev

Rev 5709 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
392 dpurdie 1
########################################################################
5709 dpurdie 2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
392 dpurdie 3
#
4
# Module name   : cc2svn_importpackage.pl
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Get package information for a package name specified on the
10
#                 command line.
11
#
12
#                 Determine the package id
13
#                 Locate all packages that have the same package name
14
#                 Determine essential packages
15
#                 Prune uneeded packages
16
#
17
#                 Pump it into SVN
18
#
19
#                 Project Based Pumping, creating branches as needed
20
#
21
#......................................................................#
22
 
23
require 5.006_001;
24
use strict;
25
use warnings;
26
use JatsError;
27
use JatsRmApi;
28
use FileUtils;
29
use JatsSystem;
30
use HTTP::Date;
31
use JatsProperties;
32
use JatsEnv;
33
use ConfigurationFile;
34
use JatsSvn qw(:All);
1197 dpurdie 35
use JatsLocateFiles;
3967 dpurdie 36
use JatsBuildFiles;
2429 dpurdie 37
use Encode;
392 dpurdie 38
 
39
 
40
#use Data::Dumper;
41
use Fcntl ':flock'; # import LOCK_* constants
42
use Cwd;
43
use DBI;
44
use Getopt::Long;
45
use Pod::Usage;                             # required for help support
1356 dpurdie 46
use Encode;
392 dpurdie 47
 
48
#
49
#   Options
50
#
51
my $opt_help = 0;
52
my $opt_manual = 0;
53
my $opt_verbose = 0;
54
my $opt_repo_base = 'AUPERASVN01/';
55
my $opt_repo = '';
2931 dpurdie 56
my $opt_repoSubdir = '';
392 dpurdie 57
my $opt_flat;
58
my $opt_test;
2931 dpurdie 59
my $opt_reuse = 0;
392 dpurdie 60
my $opt_age;
61
my $opt_dump = 0;
62
my $opt_images = 0;
63
my $opt_retaincount = 2;
64
my $opt_pruneModeString;
65
my $opt_listTags;
66
my $opt_name;
67
my $opt_log = 0;
68
my @opt_tip;
69
my $opt_postimage = 1;
70
my $opt_workDir = '/work';
71
my $opt_vobMap;
1197 dpurdie 72
my $opt_preserveProjectBase;
73
my $opt_ignoreProjectBaseErrors;
2429 dpurdie 74
my $opt_ignoreMakeProjectErrors;
3967 dpurdie 75
my $opt_ignoreBuildFileClashes;
2764 dpurdie 76
my $opt_forceProjectBase;
77
my @opt_limitProjectBase;
3967 dpurdie 78
my @opt_selectProjectBase;
2931 dpurdie 79
my @opt_mergePaths;
2764 dpurdie 80
my $opt_ignoreBadPaths;
1270 dpurdie 81
my $opt_delete;
1341 dpurdie 82
my $opt_recentAge = 14;             # Days
2429 dpurdie 83
my $opt_relabel = 0;
2450 dpurdie 84
my $opt_protected;
85
my $opt_useSvn = 1;
86
my $opt_testRmDatabase;
2764 dpurdie 87
my $opt_extractFromSvn;
88
my $opt_AllowMuliplePaths = 1;      #29-Nov-2012
89
my $opt_resume;
2931 dpurdie 90
my $opt_processRipples = 1;
91
my $opt_mergePackages;
92
my @opt_deleteFiles;
3967 dpurdie 93
my $opt_useTestRepo;
94
my $opt_saveCompressed;
95
my $opt_skipBuildNameCheck;
96
my $opt_deleteLinks;
97
my $count_BadPaths = 0;
98
my $opt_IgnoreBadSourcePath;
99
my $opt_forceSuck;
392 dpurdie 100
 
101
################################################################################
102
#   List of Projects Suffixes and Branch Names to be used within SVN
103
#
104
#       Name        - Name of branch for the project
105
#       Trunk       - Can be a trunk project
106
#                     First one seen will be placed on the trunk
107
#                     Others will create project branches
108
#
109
my $ProjectTrunk;
110
my %ProjectsBaseCreated;
111
my %Projects = (
112
    '.sea'      => { Name => 'Seattle' },
113
    '.coct'     => { Name => 'CapeTown' },
114
    '.sls'      => { Name => 'Stockholm' },
115
    '.syd'      => { Name => 'Sydney' },
116
    '.vtk'      => { Name => 'Vasttrafik' },
117
    '.bei'      => { Name => 'Beijing' },
118
    '.bkk'      => { Name => 'Bangkok' },
119
    '.ndl'      => { Name => 'NewDelhi' },
120
    '.nzs'      => { Name => 'NewZealandStageCoach' },
121
    '.wdc'      => { Name => 'Washington' },
122
    '.oso'      => { Name => 'Oslo' },
123
    '.lvs'      => { Name => 'LasVegas' },
124
    '.mlc'      => { Name => 'BeijingMlc' },
125
    '.sfo'      => { Name => 'SanFrancisco' },
126
    '.sg'       => { Name => 'Singapore' },
127
    '.gmp'      => { Name => 'GmpteProject' },
128
    '.ssw'      => { Name => 'UkStageCoach' },
129
    '.uk'       => { Name => 'UkProject' },
130
    '.pmb'      => { Name => 'Pietermaritzburg' },
131
    '.vps'      => { Name => 'VixPayments' },
132
    '.ncc'      => { Name => 'NSWClubCard' },
133
    '.rm'       => { Name => 'Rome' },
2429 dpurdie 134
    '.vss'      => { Name => 'SmartSite' },
3967 dpurdie 135
    '.ssts'     => { Name => 'SydneySchoolbus' },
392 dpurdie 136
    'unknown'   => { Name => 'UnknownProject' },
137
 
138
    '.ebr'      => { Name => 'eBrio' , Trunk => 1 },
139
    '.mas'      => { Name => 'Mass'  , Trunk => 1 },
140
    '.cr'       => { Name => 'Core'  , Trunk => 1 },
141
    '.cots'     => { Name => 'Cots'  , Trunk => 1 },
142
    '.tool'     => { Name => 'Tools' , Trunk => 1 },
143
);
144
 
145
my %suffixFixup = (
146
    '.sf'           => '.sfo',
147
    '.vt'           => '.vtk',
148
    '.lv'           => '.lvs',
149
    '.was'          => '.wdc',
150
    '.uk.1'         => '.uk',
151
    '.ssts.demo'    => '.ssts',
152
    '.u244.syd'     => '.syd',
153
    '.pxxx.sea'     => '.sea',
154
    '.pxxx.syd'     => '.syd',
155
    '.pxxx.sydddd'  => '.syd',
156
    '.oslo'         => '.oso',
1272 dpurdie 157
    '.osl'          => '.oso',
2931 dpurdie 158
    '.0x3'          => '.cr',
159
    '.0x4'          => '.cr',
160
    '.0x5'          => '.cr',
161
    '.0x13'         => '.cr',
392 dpurdie 162
);
163
 
164
my %specialPackages = (
2429 dpurdie 165
    'core_devl'           =>  ',all,protected,',
166
    'daf_utils_mos'       => ',flat,',
167
    'mos_packager'        => ',all,',
168
    'cfmgr-cfmgr'         => ',flat,',
169
    'daf_utils_button_st' => ',flat,',
170
    'ReleaseName'         => ',flat,',
171
    'reports'             => ',utf8,',
172
    'cda_imports'         => ',utf8,',
173
    'cdxforms'            => ',utf8,',
174
    'db_cda'              => ',utf8,',
2450 dpurdie 175
    'CommandServer'       => ',IgnoreMakeProject,',
176
    'TDSExporterControl'  => ',IgnoreMakeProject,',
177
    'cdagui'              => ',IgnoreMakeProject,',
395 dpurdie 178
 
2450 dpurdie 179
    'daf_bvt'                 => ',IgnoreMakeProject,',  # Look OK
180
    'daf_dll'                 => ',IgnoreMakeProject,',  # MakeProject not in used makefile
181
    'PFTPi'                   => ',IgnoreMakeProject,',  # Looks OK
182
    'PFTPu'                   => ',IgnoreMakeProject,',  # Looks OK
183
    'WinCEBlocker'            => ',IgnoreMakeProject,',  # Looks OK
184
    'WinCEDeviceAutoInject'   => ',IgnoreMakeProject,',  # Looks OK
185
    'WinCEReboot'             => ',IgnoreMakeProject,',  # Looks OK
2429 dpurdie 186
 
2764 dpurdie 187
    'ftp'                   => ',SetProjectBase,',
188
    'ddu_app_manager'       => ',SetProjectBase,IgnoreMakeProject,',
189
    'ddu_afc'               => ',SetProjectBase,IgnoreMakeProject,',
190
    'ddu_dog'               => ',SetProjectBase,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode/projects/seattle/ddu,',
191
    'ddu_management'        => ',SetProjectBase,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode,',
192
    'ddu_fim'               => ',IgnoreMakeProject,',
193
    'ddu_mccain'            => ',SetProjectBase,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode/projects/seattle/ddu,',
194
    'ddu_mon'               => ',SetProjectBase,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode/projects/seattle,',
195
    'ddu_rcu'               => ',SetProjectBase,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode,',
196
    'ddu_status_logging'    => ',SetProjectBase,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode/projects/seattle,',
197
    'ddu_logging_lib'       => ',SetProjectBase,ForceProjectBase=/DPG_SWCode/projects/seattle/ddu,',
198
    'verifone'              => ',ForceProjectBase=/DPG_SWCode/products/verifone,',
199
    'dm_devcdfile'          => 'AllowMultiPath',
200
    'daf_ct_mcr_unified'    => 'AllowMultiPath',
201
    'cst-rms-db'            => 'AllowMultiPath',
202
    'daf_common'            => 'IgnoreProjectBase',
203
    'devcd'                 => 'AllowMultiPath',
204
    'daf_dll'                   => 'AllowMultiPath,IgnoreMakeProject',  # MakeProject not in used makefile
205
    'daf_transap_proxyman_edf'  => 'AllowMultiPath,IgnoreProjectBase',
206
    'devrelease'                => 'AllowMultiPath',
395 dpurdie 207
 
2764 dpurdie 208
    'dm_devrelease'             => 'AllowMultiPath',
209
    'dm_rtswis'                 => 'AllowMultiPath',
210
    'dm_devcd'                  => 'AllowMultiPath',
211
    'dm_documentation'          => 'AllowMultiPath,IgnoreBadPath',
212
    'dm_eventhdr'               => 'AllowMultiPath',
213
    'dm_javaenums'              => 'AllowMultiPath',
214
    'dm_solidbasetypes'         => 'AllowMultiPath',
215
    'dm_swismetadata'           => 'AllowMultiPath',
216
    'dm_cuttables'              => 'AllowMultiPath',
217
    'dm_devudapi'               => 'AllowMultiPath',
218
    'buscdapi'                  => 'AllowMultiPath',
219
    'daf_bvt'                   => 'AllowMultiPath,IgnoreMakeProject,',  # Look OK
220
    'daf_cd_transap'            => 'AllowMultiPath,IgnoreBadPath,IgnoreProjectBase',
221
    'cdref'                     => 'AllowMultiPath',
222
    'dm_sysbasetypes'           => 'AllowMultiPath',
223
    'dm_sysswis'                => 'AllowMultiPath',
224
    'dm_syscd'                  => 'AllowMultiPath',
225
    'dm_udtypes'                => 'AllowMultiPath',
226
    'dm_systemcdtables'         => 'AllowMultiPath',
227
    'dm_utils'                  => 'AllowMultiPath',
228
    'dm_udxml'                  => 'AllowMultiPath',
229
    'HCP5000_resources'         => 'AllowMultiPath',
230
    'massrtswis'                => 'AllowMultiPath',
231
    'pcp5000'                   => 'AllowMultiPath,ForceProjectBase=/DPG_SWCode',
232
    'PFTPi'                     => 'AllowMultiPath,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode',  # Looks OK
233
    'PFTPu'                     => 'AllowMultiPath,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode',  # Looks OK
234
    'WinCEBlocker'              => ',IgnoreMakeProject,',  # Looks OK
235
    'WinCEDeviceAutoInject'     => ',IgnoreMakeProject,',  # Looks OK
236
    'WinCEReboot'               => ',IgnoreMakeProject,',  # Looks OK
237
    'rsmaint'                   => 'AllowMultiPath',
238
    'sysbasetypes'              => 'AllowMultiPath',
239
    'syscd'                     => 'AllowMultiPath',
240
    'sysswis'                   => 'AllowMultiPath',
241
    'udserialiser'              => 'AllowMultiPath',
242
    'systemcdtables'            => 'AllowMultiPath',
243
    'udxml'                     => 'AllowMultiPath',
244
    'ERGoracs'                  => 'AllowMultiPath',
245
    'daf_cd_desfireparams'      => 'AllowMultiPath',
246
    'daf_ct_mag_virtual'        => 'AllowMultiPath',
247
    'daf_br_applets'            => 'AllowMultiPath',
248
    'daf_paper_variables'       => 'AllowMultiPath',
249
    'daf_transap_api'           => 'AllowMultiPath,ForceProjectBase=/DPG_SWBase/transap',
250
    'daf_br_applets'            => 'AllowMultiPath,IgnoreProjectBase',  # Not used
251
    'daf_udlib_api'             => 'AllowMultiPath,ForceProjectBase=/DPG_SWBase/ud',
252
    'daf_ct_mcr_14443'          => 'LimitProjectBase=/DPG_SWBase/ct',
1197 dpurdie 253
 
2764 dpurdie 254
 
255
    'daftestcd_sales'               => 'AllowMultiPath,ForceProjectBase=/ProjectCD/seattle',
256
    'daftestcd_vanpool'             => 'AllowMultiPath,ForceProjectBase=/ProjectCD',
257
    'daf_transap_edf'               => 'AllowMultiPath,IgnoreProjectBase',
258
    'daf_transap_extensions'        => 'AllowMultiPath',
259
    'daf_transap_proxyman_rkf_mag'  => 'AllowMultiPath',
260
    'daf_utils_appupgrade'          => 'AllowMultiPath',
261
    'dc5000'                        => 'AllowMultiPath,IgnoreMakeProject,ForceProjectBase=/DPG_SWCode',
262
    'uiconv'                        => 'AllowMultiPath',
263
 
264
    'daf_ct_api'                    => 'AllowMultiPath',
265
 
266
 
267
    'ocpsupport'                    => 'AllowMultiPath,IgnoreMakeProject', # MakeProject Tested on at least one
268
    'emv_cs_test_ingenico'          => 'AllowMultiPath,IgnoreMakeProject', # MakeProject Tested on at least one
269
    'deviceicons'                   => 'AllowMultiPath,LimitProjectBase=/DPG_SWBase/resources:/DPG_SWCode/resources',
270
    'pcv_final_wce'                 => 'IgnoreMakeProject', # MakeProject Tested on at least one
271
    'pcv_wce'                       => 'IgnoreMakeProject', # MakeProject Tested on at least one
272
    'WinCEDeviceUpgrade'            => 'IgnoreMakeProject', # MakeProject Tested on at least one
273
    'scil'                          => 'LimitProjectBase=/DPG_SWCode/projects/seattle/tvm',
274
    'daf_br_compiler_support'       => 'ForceProjectBase=/DPG_SWBase/daf_br_compiler/support',
275
    'daf_br_th'                     => 'IgnoreBadPath,all,IgnoreMakeProject', # MakeProject Tested. Bad Paths not used
276
    'linux_kernel_bcp4600'          => 'ForceProjectBase=/LMOS/linux/kernel',
277
    'linux_kernel_viper'            => 'ForceProjectBase=/LMOS/linux/kernel',
278
    'linux_kernel_cobra'            => 'ForceProjectBase=/LMOS/linux/kernel',
279
 
3967 dpurdie 280
    'LinuxDrivers'                  => 'flatTime,processRipples,LimitProjectBase=/LMOS/linux/drivers'.
2931 dpurdie 281
                                       ',mergePaths=modules:bcp4600:cobra:eb5600:etx86:tp5600:viper',
2764 dpurdie 282
 
2931 dpurdie 283
    'flashCopier'                   => 'flatTime,LimitProjectBase=/LMOS/tools/flashCopier'.
284
                                       ',mergePaths=+:src:pcp5700:eb5600:tp5600',
285
 
286
    'u-boot'                        => 'flatTime,LimitProjectBase=/LMOS/linux/bootstrap/u-boot'.
287
                                       ',mergePaths=+:src:u-boot:u-boot-hk',
288
 
289
    'dams_gen1'                      => 'flatTime,LimitProjectBase=/LMOS/apps/dams'.
290
                                       ',mergePaths=+:tp5600:eb5600:pcp5700:core:doc'.
291
                                       ',processRipples',
292
 
293
    'linux_day0fs_gen1'            => 'flatTime,LimitProjectBase=/LMOS/linux/filesystems/day0-fs'.
294
                                       ',mergePaths=+:tp5600:eb5600:pcp5700:etx86:common'.
295
                                       ',processRipples',
296
 
297
    'linux_kernel_gen1'               => 'flatTime,mergePaths=,processRipples,LimitProjectBase=/LMOS/linux/kernel',
3967 dpurdie 298
 
299
    'serpent'                         => 'flatTime,processRipples,LimitProjectBase=/LMOS/linux/kernel'.
300
                                         ',mergePaths=serpent-common:common:cobra:viper',
301
 
2931 dpurdie 302
    'rt3070'                          => 'flatVersion',
303
 
304
    'TRACS'                           => 'IgnoreMakeProject,DeleteFiles=*.plg',   # not tested
305
 
3967 dpurdie 306
    'qtobeapp'                        => 'Trunk=.uk',
2931 dpurdie 307
 
3967 dpurdie 308
    'br_applets'                      => 'flatTime,LimitProjectBase=/ProjectCD/seattle'.
309
                                       ',mergePaths=++:build/**:Sales/**:FarePayment/**:KCM/**:unit_test/**:VP/**:WSF/**'.
310
                                       ',processRipples',
311
 
312
    'CDAdministration'      => 'RetainCompressed,IgnoreMakeProject,SelectProjectBase=MASS_Dev_Infra/DeviceCDManagement/cpp/CDAdministrator:MASS_Dev_Infra/CDAdministrator:MASS_Dev_Infra/CDAdministrator_vt:MASS_Dev_Infra/Cda/java:MASS_Dev_Infra/CDA:MASS_Dev_Infra',
313
 
314
    'obme'                  => ',IgnoreMakeProject,',
315
 
316
    'apportionment'         => 'SkipBuildFileCheck',
317
    'almgr'                 => 'SkipBuildFileCheck,SelectProjectBase=MASS_Dev_Bus/CBP/al/almgr/cpp:MASS_Dev_Bus/CBP/al/almgr:MASS_Dev_Bus/CBP/al:MASS_Dev_Bus/CBP',
318
    'cvm'                   => 'SelectProjectBase=MASS_Dev_Bus/CBP/cvm/cpp:MASS_Dev_Bus/CBP/cvm',
319
    'esvrapi'               => 'SelectProjectBase=MASS_Dev_Bus/CBP/enquiry/esvrapi/cpp:MASS_Dev_Bus/CBP/enquiry/esvrapi',
320
    'Validation'            => 'SelectProjectBase=MASS_Dev_Bus/CBP/validation/validation/cpp:MASS_Dev_Bus/CBP/validation/validation',
321
    'txnfilter'             => 'DeleteLinks,SelectProjectBase=MASS_Dev_Bus/CBP/txnfilter/txnfilter:MASS_Dev_Bus/CBP/txnfilter/cpp:MASS_Dev_Bus/CBP/txnfilter',
322
 
323
    'card'                  => 'SelectProjectBase=MASS_Dev_Bus/Card/cpp:MASS_Dev_Bus/Card',
324
    'cbps'                  => 'SelectProjectBase=MASS_Dev_Bus/CBP/cbps/cpp:MASS_Dev_Bus/CBP/cbps:MASS_Dev_Bus/CBP',
325
    'issuercommon'          => 'SelectProjectBase=MASS_Dev_Bus/Issuer/issuerCommon/cpp:MASS_Dev_Bus/Issuer/issuerCommon',
326
    'ivp'                   => 'SelectProjectBase=MASS_Dev_Bus/CBP/ivp/ivp/cpp:MASS_Dev_Bus/CBP/ivp/ivp:MASS_Dev_Bus/CBP/ivp:MASS_Dev_Bus/CBP',
327
 
328
    'daf_transap_mag'       => 'SelectProjectBase=DPG_SWBase/transap/proxy/mag:DPG_SWBase/transap/proxy',
329
    'daf_transap_proxyman'  => 'SelectProjectBase=DPG_SWBase/transap/proxymanager',
330
    'daf_transap_rkf'       => 'SkipBuildFileCheck',
331
 
332
    'daf_cd_common'         => 'IgnoreProjectBase',
333
 
334
    'altp'                  => 'SelectProjectBase=MASS_Dev_Bus/CBP/al/altp/cpp:MASS_Dev_Bus/CBP/al/altp',
335
    'cfm'                   => 'SelectProjectBase=MASS_Dev_Bus/CBP/cfm/cpp:MASS_Dev_Bus/CBP/cfm',
336
    'enqdef'                => 'SelectProjectBase=MASS_Dev_Bus/CBP/enquiry/enqdef',
337
    'expstat'               => 'SelectProjectBase=MASS_Dev_Bus/CBP/expstat/cpp:MASS_Dev_Bus/CBP/expstat',
338
    'olsenqxdr'             => 'SelectProjectBase=MASS_Dev_Bus/CBP/enquiry/olsenqxdr/cpp:MASS_Dev_Bus/CBP/enquiry/olsenqxdr',
339
    'olseod'                => 'SelectProjectBase=MASS_Dev_Bus/CBP/olseod/olseod/cpp:MASS_Dev_Bus/CBP/olseod/olseod:MASS_Dev_Bus/CBP/olseod',
340
    'streamer'              => 'SelectProjectBase=MASS_Dev_Bus/CBP/streamer/cpp:MASS_Dev_Bus/CBP/streamer',
341
    'tgen'                  => 'SelectProjectBase=MASS_Dev_Bus/CBP/tgen/cpp:MASS_Dev_Bus/CBP/tgen',
342
 
343
    'daf_transap_ultralight'=> 'flatTime,processRipples,mergePaths=++',
344
#    'daf_cardshark'        => 'flatTime,processRipples,mergePaths=++',
345
 
346
    'emv_raw_cs'            => 'flatTime,processRipples,SelectProjectBase=DPG_SWBase/emv_cs/emv_raw_cs/cpf:DPG_SWBase/emv_cs/emv_raw_cs'.
347
                                    ',mergePaths=++:linux/**:win32/**',
348
    'OpManCronJob'          => 'SkipBuildFileCheck',
349
    'issuertest'            => 'SelectProjectBase=MASS_Dev_Bus/Issuer/test/IssuerTest:MASS_Dev_Bus/Issuer/test/cpp:MASS_Dev_Bus/Card/test/cpp:MASS_Dev_Bus/Card/test/cpp',
350
    'obits_simulator'       => 'IgnoreMakeProject',
351
    'application'           => 'IgnoreMakeProject,SelectProjectBase=MASS_Dev_Bus/Application',
352
    'FinCommon'             => 'SkipBuildFileCheck,SelectProjectBase=MASS_Dev_Bus/Financial',
353
    'FinRun'                => 'SkipBuildFileCheck,SelectProjectBase=MASS_Dev_Bus/Financial',
354
    'olstxnstream'          => 'SelectProjectBase=MASS_Dev_Infra/core_olstxnstream',
355
 
356
    'product'               => 'SkipBuildFileCheck,SelectProjectBase=MASS_Dev_Bus/Product',
357
    'oracen-bei-patch'      => 'RetainCompressed',
358
    'oracen-patch'          => 'RetainCompressed',
359
    'pcv'                   => 'IgnoreMakeProject',
360
    'summarisation'         => 'SkipBuildFileCheck',
361
    'AVMApplicationEngine'  => 'IgnoreMakeProject',
362
    'ESL'                   => 'IgnoreMakeProject',
363
    'daf_br_oar'            => 'IgnoreProjectBase',         # Look OK
364
    'daf_br'                => 'RetainCompressed,IgnoreProjectBase,IgnoreMakeProject,SelectProjectBase=DPG_SWBase/daf_br:DPG_SWBase/br',    # Look OK
365
    'daf_dti'               => 'IgnoreProjectBase,SelectProjectBase=DPG_SWBase/dti;DPG_SWBase',
366
    'OcpGui'                => 'IgnoreMakeProject',
367
    'ssu5000'               => 'ForceProjectBase=/DPG_SWCode',
368
    'obftp'                 => 'IgnoreMakeProject,IgnoreProjectBase,ForceProjectBase=/DPG_SWCode',
369
    'saftp'                 => 'IgnoreProjectBase,ForceProjectBase=/DPG_SWCode',
370
    'PFTPp'                 => 'IgnoreMakeProject,ForceProjectBase=/DPG_SWCode',        # Need to test
371
    'ocp5000'               => 'ForceProjectBase=/DPG_SWCode,RetainCompressed,IgnoreMakeProject', # Need to test
372
    'SPOS'                  => 'ForceProjectBase=/DPG_SWCode',
373
 
374
    'gak6000'               => 'ForceProjectBase=/DPG_SWCode,IgnoreProjectBase',
375
    'gak5000'               => 'ForceProjectBase=/DPG_SWCode,IgnoreProjectBase,IgnoreBadPath',
376
    'hcp5000'               => 'IgnoreMakeProject,ForceProjectBase=/DPG_SWCode,RetainCompressed,IgnoreBadSourcePath',
377
    'agents_unit'           => 'IgnoreProjectBase,ForceProjectBase=/DPG_SWCode',
378
 
379
    'tp5000'                => 'IgnoreProjectBase,ForceProjectBase=/DPG_SWCode',
380
    'vcp5000'               => 'IgnoreProjectBase,ForceProjectBase=/DPG_SWCode',
381
 
382
    'MetrixOra'             => 'ForceSuck,ForceProjectBase=/MASS_Dev_Bus,IgnoreBadSourcePath,NoProcessRipples',
383
    'oracs'                 => 'ForceSuck,ForceProjectBase=/MASS_Dev_Bus,IgnoreBadSourcePath,NoProcessRipples',
384
    'oradacw'               => 'ForceSuck,ForceProjectBase=/MASS_Dev_Bus,IgnoreBadSourcePath,NoProcessRipples,SelectProjectBase=MASS_Dev_Bus/web/patches/oradacw:MASS_Dev_Bus/web/patches:MASS_Dev_Bus/web',
385
    'orabocw'               => 'ForceSuck,ForceProjectBase=/MASS_Dev_Bus,IgnoreBadSourcePath,NoProcessRipples,SelectProjectBase=MASS_Dev_Bus/web/patches/orabocw:MASS_Dev_Bus/web/patches:MASS_Dev_Bus/web',
386
 
387
 
1197 dpurdie 388
    'icl'                   => 'IgnoreProjectBase,',
389
    'itso'                  => 'IgnoreProjectBase,',
2450 dpurdie 390
#    'daf_osa_mos'           => 'IgnoreProjectBase,',
1197 dpurdie 391
    'daf_utils_mos'         => 'IgnoreProjectBase,',
392
    'itso_ud'               => 'IgnoreProjectBase,',
393
#    'mos_api'               => 'IgnoreProjectBase,',
394
#    'mos_fonts'             => 'IgnoreProjectBase,',
395
#    'sntp'                  => 'IgnoreProjectBase,',
396
#    'time_it'               => 'IgnoreProjectBase,',
392 dpurdie 397
);
398
 
2931 dpurdie 399
 
400
my %mergePathExtended = (
401
 
402
    'linux_kernel_gen1' => {
403
            'linux_kernel_eb5600_2.6.21.1.0.cots' => '+:TP5600:EB5600:ETX86:common:packager.sflash:www.kernel.org:packager.grub',
404
            'linux_kernel_tp5600_2.6.21.1.0.cots' => '+:tp5600:eb5600:etx86:bcp4600:common:packager.sflash:www.kernel.org:packager.grub',
405
            },
406
 
3967 dpurdie 407
    'serpent'   => {
408
        'linux_kernel_viper_2.6.24.6.0000.cots' => 'common:viper',
409
        'linux_kernel_viper_2.6.24.6.1000.cots' => 'serpent-common:cobra:viper',
410
 
411
    },
412
 
2931 dpurdie 413
);
414
 
415
my %packageRippleControl = (
416
    'linux_drivers_etx86' => 'major',
417
    'linux_drivers_eb5600' => 'major',
418
    'linux_drivers_tp5600' => 'major',
419
);
420
 
421
 
392 dpurdie 422
my %notCots = (
423
    'isl'       => 1,
424
);
425
 
2429 dpurdie 426
my %ukHopsReleases = (
427
    '6222'      => { name => 'MainLine', 'trunk' => 1 },
428
    '14503'     => { name => 'Hops3' },
429
    '21864'     => { name => 'Hops3.6' },
430
    '22303'     => { name => 'Hops3.7' },
431
    '17223'     => { name => 'Hops4' },
2931 dpurdie 432
 
3967 dpurdie 433
#    '19743' => {name => 'ITSO.2.1.4-MainlineOBE_Validator'},
434
#    '11743' => {name => 'ITSO.2.1.3-MainlineOBE_Validator'},
435
#    '21384' => {name => 'OBE2.1.3-GoAheadRelease-R4'},
436
#    '23243' => {name => 'OBE2.1.3-GoAheadRelease-R4.5'},
437
#    '23843' => {name => 'Validator.2.1.3-UKlive'},
438
#    '15663' => {name => 'Validator.2.1.3-LegacyVersion_SSW_LMR'},
439
#    '25183' => {name => 'ITSO.2.1.4-Validator-cmnITSO.V2src'},
440
#    '24303' => {name => 'OBME_PSION-MAINLINE-ITSO.2.1.4'},
441
#    '13143' => {name => 'OBME_PSION-MAINLINE-ITSO.2.1.2'},
442
#    '24443' => {name => 'OBME_PSION-MAINLINE-ITSO.2.1.2-hot-fix'},
443
#    '16023' => {name => 'OBME_PSION-TransportScotlandDLL'},
2931 dpurdie 444
 
2429 dpurdie 445
);
446
 
447
# The following packages will have the version in the specified release forced to be on the trunk
448
# A trunk will be forced and the version will be on it.
449
#   May only work if the version in the release is also a TIP
450
my %ukHopsTip = (
451
    'ItsoMessaging'         => '6222',
452
    'MessageProcessor'      => '6222',
453
    'StrongNameKey'         => '6222',
454
);
455
 
392 dpurdie 456
################################################################################
457
#   Global data
458
#
459
my $VERSION = "1.0.0";
460
my $RM_DB;
461
my $last_pv_id;
462
my %pkg_ids;
463
my $first_pkg_id;
464
my %versions;
465
my %suffixes;
466
my @processOrder;
467
my @startPoints;
468
my @allStartPoints;
469
my @endPoints;
470
my $now = time();
471
my $logSummary;
472
my $firstVersionCreated;
473
my @EssentialPackages;
474
my $createBranch;
475
my $createSuffix;
476
my $currentBranchName;
477
my $singleProject;
478
my $pruneCount = 0;
479
my $trimCount = 0;
480
my $badVcsCount = 0;
481
my $ProjectCount = 0;
482
my $totalVersions = 0;
483
my $initialTrees = 0;
484
my $globalError;
485
my @unknownProjects;
486
my %knownProjects;
487
my $badSingletonCount = 0;
488
my @flatOrder;
2931 dpurdie 489
my $flatMode = 0;
392 dpurdie 490
my $pruneMode;
491
my $pruneModeString;
492
my $threadId = 0;
493
my $threadCount;
494
my %tipVersions;
495
my $allSvn;
496
my @multiplePaths;
497
my @badEssentials;
498
my %svnData;
499
my $cwd;
2429 dpurdie 500
my $mustConvertFileNames;
501
my $workDir;
392 dpurdie 502
 
503
my $packageNames;
504
my @packageNames;
505
my $multiPackages = -1;
506
my $visitId = 0;
507
my $noTransfer;
508
my $rippleCount = 0;
509
my $svnRepo;
1270 dpurdie 510
my $processCount = 0;
511
my $processTotal = 0;
1341 dpurdie 512
my $recentCount = 0;
2429 dpurdie 513
my $packageReLabelCount = 0;
514
my %saneLabels;
2764 dpurdie 515
my $adjustedPath = 0;
516
my $forceImportFlush = 0;
517
my %restoreData;
392 dpurdie 518
 
519
our $GBE_RM_URL;
520
my $UNIX = $ENV{'GBE_UNIX'};
521
 
522
my $result = GetOptions (
2931 dpurdie 523
                'help+'             => \$opt_help,          # flag, multiple use allowed
524
                'manual:3'          => \$opt_help,
525
                'verbose:+'         => \$opt_verbose,       # Versose
526
                'repository:s'      => \$opt_repo,          # Name of repository
2764 dpurdie 527
                'rbase:s'           => \$opt_repo_base,     # Base of the repo
2931 dpurdie 528
                'flat!'             => \$opt_flat,          # Flat structure
529
                'test!'             => \$opt_test,          # Test operations
530
                'reuse:1'           => \$opt_reuse,         # Reuse ClearCase views 0:None, 1=Retain, 2=Use+Delete
531
                'age:i'             => \$opt_age,           # Only recent versions
532
                'dump:1'            => \$opt_dump,          # Dump Data
533
                'images:1'          => \$opt_images,        # Create DOT images
534
                'retain:i'          => \$opt_retaincount,   # Retain N packages
535
                'pruneMode:s'       => \$opt_pruneModeString,
536
                'listtags:i'        => \$opt_listTags,
537
                'name:s'            => \$opt_name,          # Alternate output
538
                'tip:s'             => \@opt_tip,           # Force tip version(s)
539
                'log!'              => \$opt_log,
540
                'delete!'           => \$opt_delete,
541
                'postimage!'        => \$opt_postimage,
2764 dpurdie 542
                'workdir:s'         => \$opt_workDir,
543
                'relabel!'          => \$opt_relabel,
544
                'svn!'              => \$opt_useSvn,
545
                'testRmDatabase'    => \$opt_testRmDatabase,
546
                'resume'            => \$opt_resume,
2931 dpurdie 547
                'mergePackages:s'   => \$opt_mergePackages,
548
                'subdir:s'          => \$opt_repoSubdir,    # Subdir within repo
549
                'fromSvn!'          => \$opt_extractFromSvn,
3967 dpurdie 550
                'testRepo!'         => \$opt_useTestRepo,
392 dpurdie 551
                );
552
 
553
#
554
#   Process help and manual options
555
#
556
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
557
pod2usage(-verbose => 1)  if ($opt_help == 2 );
558
pod2usage(-verbose => 2)  if ($opt_manual || ($opt_help > 2));
559
 
560
#
561
#   Configure the error reporting process now that we have the user options
562
#
563
SystemConfig ('ExitOnError' => 1);
564
ErrorConfig( 'name'    =>'CC2SVN_IMPORT',
565
             'verbose' => $opt_verbose,
566
              );
567
 
568
Error("Workdir does not exist" ) unless ( -d $opt_workDir );
569
Error("Specify a package as 'name'" ) unless ( defined $ARGV[0] );
570
EnvImport('GBE_RM_URL');
571
$cwd = Getcwd();
572
 
573
#
2450 dpurdie 574
#   Allow use of the test database
575
#   Defaut is live data, but some error recovery stuff can be done via
576
#   the test database.
577
#
578
if ( $opt_testRmDatabase )
579
{
580
    Warning ("Using Test Database");
581
    $ENV{GBE_RM_USERNAME} = 'RELEASE_MANAGER';
582
    $ENV{GBE_RM_PASSWORD} = 'RELEASE_MANAGER';
583
    $ENV{GBE_RM_LOCATION} = 'jdbc:oracle:thin:@auperaora07.vix.local:1521:RELMANU1';
584
}
585
 
586
#
392 dpurdie 587
#   Init the pruning mode
588
#
589
setPruneMode( $opt_pruneModeString || 'ripple');
590
 
591
#
2931 dpurdie 592
#   Detect Merge Package Request
593
#   These use pre-configured bits
594
#
595
if ( $opt_mergePackages )
596
{
597
    if ( $opt_mergePackages eq 'LinuxDrivers' )
598
    {
599
        $opt_name = $opt_mergePackages;
600
        @ARGV = qw (linux_drivers_eb5600
601
                    linux_drivers_viper
602
                    linux_drivers_cobra
603
                    linux_drivers_etx86
604
                    linux_drivers_tp5600);
605
#                    linux_drivers_bcp4600
606
 
607
 
608
    } elsif ( $opt_mergePackages eq 'flashCopier' ) {
609
        $opt_name = $opt_mergePackages;
610
        @ARGV = qw (
611
                flash_copier_eb5600
612
                flash_copier_pcp5700
613
                flash_copier_tp5600
614
                );
615
 
616
    } elsif ( $opt_mergePackages eq 'u-boot' ) {
617
        $opt_name = $opt_mergePackages;
618
        @ARGV = qw (
619
                u-boot
620
                u-boot-hk
621
                );
622
 
623
    } elsif ( $opt_mergePackages eq 'dams_gen1' ) {
624
        $opt_name = $opt_mergePackages;
625
        @ARGV = qw (
626
                    dams_eb5600
627
                    dams_pcp5700
628
                    dams_tp5600
629
                );
630
 
631
    } elsif ( $opt_mergePackages eq 'linux_day0fs_gen1' ) {
632
        $opt_name = $opt_mergePackages;
633
        @ARGV = qw (
634
                    linux_day0fs_eb5600
635
                    linux_day0fs_tp5600
636
                    linux_day0fs_etx86
637
                );
638
 
639
    } elsif ( $opt_mergePackages eq 'linux_kernel_gen1' ) {
640
        $opt_name = $opt_mergePackages;
641
        @ARGV = qw (
642
                    linux_kernel_etx86
643
                    linux_kernel_tp5600
644
                    linux_kernel_eb5600
645
                    linux_kernel_bcp4600
646
                );
647
 
3967 dpurdie 648
    } elsif ( $opt_mergePackages eq 'serpent' ) {
649
        $opt_name = $opt_mergePackages;
650
        @ARGV = qw (
651
                    linux_kernel_viper
652
                    linux_kernel_cobra
653
                );
654
 
655
    } elsif ( $opt_mergePackages eq 'emv_raw_cs_merge' ) {
656
        $opt_name = 'emv_raw_cs';
657
        @ARGV = qw (
658
                    emv_raw_cs
659
                    emv_raw_cs-w32
660
                );
661
 
662
 
663
    } elsif ( $opt_mergePackages eq 'seattleBr' ) {
664
        $opt_name = 'br_applets';
665
        @ARGV = qw (
666
                    br_applet_cst
667
                    br_applet_gak_wsf
668
                    br_applet_gak_wsf_pos
669
                    br_applet_obftp_ct
670
                    br_applet_obftp_et
671
                    br_applet_obftp_kcm
672
                    br_applet_obftp_kt
673
                    br_applet_obftp_pt
674
                    br_applet_obftp_st
675
                    br_applet_pftp_ct_brt
676
                    br_applet_pftp_ct_vanpool
677
                    br_applet_pftp_kcm_dart
678
                    br_applet_pftp_kcm_rr
679
                    br_applet_pftp_kcm_vanpool
680
                    br_applet_pftp_kt
681
                    br_applet_pftp_pt_vanpool
682
                    br_applet_pftp_st
683
                    br_applet_pftp_st_llr
684
                    br_applet_pftp_wsf
685
                    br_applet_saftp_ct_brt
686
                    br_applet_saftp_kcm_rr
687
                    br_applet_saftp_st
688
                    br_applet_saftp_st_llr
689
                    br_applet_tru
690
                    br_applet_tvm
691
                    unit_test_br_cst
692
                    unit_test_br_gak
693
                    unit_test_br_kcm_ct_saftp
694
                    unit_test_br_obftp
695
                    unit_test_br_st_saftp
696
                    unit_test_br_vanpool
697
                    SalesConfiguration
698
                );
2931 dpurdie 699
    } else
700
    {
701
        Error ("Unknown Merge Package Name: $opt_mergePackages");
702
    }
703
}
392 dpurdie 704
#   Get data for all packages
705
#
706
foreach my $packageName ( @ARGV )
707
{
708
    next unless ( $packageName );
709
    Verbose( "Base Package: $packageName");
710
 
711
    my $pkg_id = GetPkgIdByName ( $packageName );
712
    GetData_by_pkg_id ( $pkg_id, $packageName  );
713
    $pkg_ids{$pkg_id} = 1;
714
    $first_pkg_id = $pkg_id unless ( $first_pkg_id );
715
    push @packageNames, $packageName;
716
    $multiPackages++;
717
}
718
 
719
{
720
    #
721
    #   Delete entries that have been created as we read in
722
    #   data, but don't exist in RM. They will not have a pvid.
723
    #
724
    foreach my $entry ( keys(%versions) )
725
    {
726
        delete $versions{$entry}
727
            unless ( exists $versions{$entry}{pvid} );
728
    }
729
}
730
 
731
$totalVersions = scalar keys %versions;
732
Error ("No packages specified") unless ( $multiPackages >= 0 );
733
Warning ("Multiple Packages being processed") if ( $multiPackages > 1 );
734
$packageNames = join ('_', @packageNames );
735
$packageNames = $opt_name if ( defined $opt_name );
736
Message ("PackageName: $packageNames" );
737
 
738
#
739
#   Save logging data
740
#
741
if ( $opt_log )
742
{
743
    my $opt_logfile = $packageNames . '.import';
744
    Message ("Logging outout: $opt_logfile" );
745
    open STDOUT, '>', $opt_logfile  or die "Can't redirect STDOUT: $!";
746
    open STDERR, ">&STDOUT"         or die "Can't dup STDOUT: $!";
747
}
748
 
749
#
750
#   Prepare tip version hash
751
#
752
$tipVersions{$_} = 1 foreach ( @opt_tip );
753
 
754
#
755
#   Read in external data and massage it all
756
#
757
getEssenialPackageVersions();
758
getVobMapping();
759
smartPackageType();                 # Determine special prune mode
760
ReportPathVariance();
761
massageData();
762
getSvnData();
763
smartPackageType();                 # Have another go
2764 dpurdie 764
restoreData() if ( $opt_resume );
392 dpurdie 765
 
766
my @missedTips = keys %tipVersions;
767
Error ("Specified tip version not found: @missedTips") if ( @missedTips );
768
 
769
if ( $opt_flat )
770
{
771
#    @flatOrder = sort {$versions{$a}{version} cmp $versions{$b}{version}} keys(%versions);
772
#    @flatOrder = sort {$versions{$a}{created} cmp $versions{$b}{created}} keys(%versions);
2931 dpurdie 773
 
774
    if ( $flatMode == 1 ) {
775
        Message ("Flat import. Sorted by TimeStamp");
776
        @flatOrder = sort {$versions{$a}{TimeStamp} cmp $versions{$b}{TimeStamp}} keys(%versions);
777
    } elsif ( $flatMode == 2 ) {
778
        Message ("Flat import. Sorted by Version");
779
 
780
        # Only iff all the bits are numeric
781
        sub sortCotsVersion
782
        {
783
            my @va = split '\.', $versions{$a}{vname};
784
            my @vb = split '\.', $versions{$b}{vname};
785
 
786
            my $rv = scalar @va <=> scalar @vb;
787
            return $rv if ( $rv );
788
 
789
            foreach my $ii ( 0 .. scalar @va )
790
            {
791
                $va[$ii] = '' unless ( defined $va[$ii] );
792
                $vb[$ii] = '' unless ( defined $vb[$ii] );
793
                if ( ($va[$ii] =~ m~^\d+$~) && ($va[$ii] =~ m~^\d+$~)  )
794
                {
795
                    $rv = $va[$ii] <=> $vb[$ii];
796
                }
797
                else
798
                {
799
                    $rv = $va[$ii] cmp $vb[$ii];
800
                }
801
                return $rv if ( $rv );
802
            }
803
            return $rv;
804
        }
805
 
806
        @flatOrder = sort sortCotsVersion keys(%versions);
807
#        @flatOrder = sort {$versions{$a}{vname} cmp $versions{$b}{vname}} keys(%versions);
808
    } else {
809
        @flatOrder = sort {$a <=> $b} keys(%versions);
810
    }
392 dpurdie 811
    my $tip = $flatOrder[-1];
812
    $versions{$tip}{Tip} = 1 if $tip;
813
}
814
 
815
#
816
#   Generate dumps and images
3967 dpurdie 817
#       Always create image first - we are doing it after every transfer
392 dpurdie 818
#
3967 dpurdie 819
if ( $opt_images || 1 )
392 dpurdie 820
{
821
    createImages();
822
}
823
 
824
if ( $opt_dump )
825
{
826
    DebugDumpData ("Versions", \%versions );
827
    DebugDumpData ("Starts", \@startPoints );
828
    DebugDumpData ("Ends", \@endPoints );
829
    DebugDumpData ("Suffixes", \%suffixes );
830
}
831
 
832
 
833
#   Display VCS tags
834
#
835
if ( $opt_listTags )
836
{
837
    foreach my $entry (sort {$versions{$a}{version} cmp $versions{$b}{version}} keys(%versions) )
838
    {
839
        print $versions{$entry}{vcsTag} || '-' ,"\n";
840
    }
841
}
842
exit if ( ($opt_dump > 1) || ($opt_images > 1) );
843
 
844
transferPackageToSvn();
845
 
846
if ( $opt_postimage )
847
{
848
    getSvnData();
849
    createImages();
850
}
851
 
852
exit 0;
853
 
854
#-------------------------------------------------------------------------------
855
# Function        : transferPackageToSvn
856
#
857
# Description     : Transfer the package to SVN
858
#
859
# Inputs          : 
860
#
861
# Returns         : 
862
#
863
sub transferPackageToSvn
864
{
865
    Error ("Repository Path not setup")
866
        unless ( $svnRepo );
867
 
868
    #
869
    #   Going to do serious work
870
    #   Need to ensure we have more arguments
871
    #
2450 dpurdie 872
    if ( $opt_protected )
873
    {
2931 dpurdie 874
        Warning("Protected Package not transferred: $packageNames - $opt_protected",
2450 dpurdie 875
                "See cc2svn_protected.txt for details");
876
        exit 0;
877
    }
878
 
392 dpurdie 879
    if ( $noTransfer )
880
    {
2931 dpurdie 881
        Warning("Protected Package not transferred: $packageNames",
2450 dpurdie 882
                "Configured within this program");
392 dpurdie 883
        exit 0;
884
    }
885
 
886
    #
887
    #   Perform all the work in a package specific subdirectory
888
    #
2429 dpurdie 889
    $workDir = $opt_workDir . '/' . $packageNames;
392 dpurdie 890
    mkdir $workDir unless ( -d $workDir );
891
    chdir $workDir || Error ("Cannot cd to $workDir");
892
 
893
    #
894
    #   Process all packages
895
    #       Going to create versions based on RM structure
896
    #       May have several starting points: Process each
897
    #
898
    newPackage();
899
    if ( $opt_flat )
900
    {
901
        newProject();
902
        foreach my $entry (@flatOrder )
903
        {
904
            newPackageVersion( $entry, $versions{$entry}{suffix} );
905
        }
906
    }
907
    else
908
    {
909
        processBranch(@allStartPoints);
910
    }
911
    endPackage();
912
 
913
    chdir $cwd || Error ("Cannot cd back to $cwd");
914
    rmdir $workDir;
915
    Warning ("Work Directory still exists: $workDir");
916
    saveData();
917
}
918
 
919
#-------------------------------------------------------------------------------
920
# Function        : setPruneMode
921
#
922
# Description     : Set the pruning mode
923
#
924
# Inputs          : mode                    - Text mode value
925
#
926
# Returns         : Nothing
927
#
928
sub setPruneMode
929
{
930
    my ($mode) = @_;
931
    my $value;
932
    if ( $mode )
933
    {
934
        if ( $mode =~ m/none/i) {
935
            $value = 0;
936
        } elsif ( $mode =~ m/ripple/i) {
937
            $value = 1;
938
        } elsif ( $mode =~ m/retain/i) {
939
            $value = 2;
940
        } elsif ( $mode =~ m/severe/i) {
941
            $value = 3;
942
        } else {
943
            Error ("Unknown pruning mode", "Use: none, ripple, retain or severe");
944
        }
945
 
946
        $pruneModeString = $mode;
947
        $pruneMode = $value;
948
    }
949
}
950
 
951
#-------------------------------------------------------------------------------
952
# Function        : smartPackageType
953
#
954
# Description     : Have a look at the projects in the package set and
955
#                   attempt to determine what sort of mechanism to use
956
#
957
# Inputs          : Uses %suffixes data
958
#
959
# Returns         : 
960
#
961
my $packageType = 'UNKNOWN';
962
sub smartPackageType
963
{
964
    #
965
    #   Rebuild suffixes hash based on  post massaged versions
966
    #
967
    my %suffixes;
968
    my @unknown;
969
    foreach my $entry ( keys %versions )
970
    {
971
        my $suffix = $versions{$entry}{suffix} || '';
972
        push (@unknown, $entry) if ($suffix eq 'unknown');
973
 
974
        next if ( exists $suffixes{$suffix} );
975
        next if ( $versions{$entry}{badSingleton} );
976
        next if ( $versions{$entry}{locked} eq 'N' || $versions{$entry}{isaWip} );
977
        $suffixes{$suffix} = 1;
978
        $knownProjects{$suffix}{seen} = 1;
979
 
980
    }
981
 
982
    #
983
    #   The 'unknown' suffix is really an 'empty' suffix
984
    #   Try to be clever
985
    #       Map unknown to 'cr' or 'mas' if present
986
    #
987
    #
988
    if ( exists $suffixes{'unknown'}  )
989
    {
990
        my $new_suffix;
991
        if ( exists $suffixes{'.cr'} ) {
992
            $new_suffix = '.cr';
993
        } elsif ( exists $suffixes{'.mas'} ) {
994
            $new_suffix = '.mas';
995
        }
996
 
997
        if ( $new_suffix )
998
        {
999
            foreach my $entry ( @unknown )
1000
            {
1001
                $versions{$entry}{suffix} = $new_suffix;
1002
            }
1003
            delete $suffixes{'unknown'};
1004
            delete $knownProjects{'unknown'}{seen};
1005
        }
1006
    }
1007
 
1008
    if ( exists $suffixes{'.cots'} && !exists ($notCots{$packageNames}) ) {
1009
        $packageType = 'COTS';
1010
        $Projects{'.cots'}{Trunk} = 1;
1011
        $singleProject = 1;
1012
        $opt_flat = 1 unless defined $opt_flat;
1013
        setPruneMode('none') unless (defined $opt_pruneModeString);
1014
 
1015
    } elsif ( exists $suffixes{'.tool'} ) {
1016
        $packageType = 'TOOL';
2429 dpurdie 1017
        $Projects{'.tool'}{Trunk} = 1;
392 dpurdie 1018
        $singleProject = 1;
1019
        setPruneMode('none') unless (defined $opt_pruneModeString);
1020
#        $opt_flat = 1;
1021
 
1022
    } elsif ( scalar (keys %suffixes ) == 1 ) {
1023
        $packageType = 'SINGLE_PROJECT';
1024
        $singleProject = 1;
1025
 
1026
    } else {
1027
        $packageType = 'MULTIPLE_PROJECT';
1028
    }
1029
 
1030
    #
1031
    #   Some packages are special
1032
    #
2429 dpurdie 1033
    if ( $svnRepo =~ m~/Manufacturing(/|$)~ )
1034
    {
1035
        Message ("Set Manufacturing Repo style");
1036
        $opt_flat = 1;
1037
        setPruneMode('none') unless (defined $opt_pruneModeString);
1038
    }
392 dpurdie 1039
 
2429 dpurdie 1040
 
2931 dpurdie 1041
    if ( $packageNames =~ m'^br_applet_' )
392 dpurdie 1042
    {
2429 dpurdie 1043
      $opt_flat = 1 unless defined $opt_flat;
392 dpurdie 1044
    }
1045
 
2931 dpurdie 1046
    if ( exists $specialPackages{$packageNames} )
392 dpurdie 1047
    {
2931 dpurdie 1048
        my $data = ',' . $specialPackages{$packageNames} . ',';
2764 dpurdie 1049
 
392 dpurdie 1050
        if ( index( $data, ',all' ) >= 0) {
1051
            setPruneMode('none') unless (defined $opt_pruneModeString);
1052
        }
1053
 
2931 dpurdie 1054
        if ( index( $data, ',protected,' ) >= 0) {
392 dpurdie 1055
            $noTransfer = 1;
1056
        }
1057
 
2931 dpurdie 1058
        if ( index( $data, ',flat,' ) >= 0) {
392 dpurdie 1059
            $opt_flat = 1;
1060
        }
1197 dpurdie 1061
 
2931 dpurdie 1062
        if ( index( $data, ',flatTime,' ) >= 0) {
1063
            Message ("Flatten import tree. Sort by Time");
1064
            $opt_flat = 1;
1065
            $flatMode = 1;          # By Time
1066
            $opt_processRipples = 0;
1067
        }
1068
 
1069
        if ( index( $data, ',flatVersion,' ) >= 0) {
1070
            Message ("Flatten import tree. Sort by Version");
1071
            $opt_flat = 1;
1072
            $flatMode = 2;          # By Version
1073
            $opt_processRipples = 0;
1074
        }
1075
 
1076
        if ( index( $data, ',processRipples,' ) >= 0) {
1077
            $opt_processRipples = 1;
1078
        }
1079
 
3967 dpurdie 1080
        if ( index( $data, ',NoProcessRipples,' ) >= 0) {
1081
            $opt_processRipples = 0;
1082
            Message ("Disable Processing of ripples");
1083
        }
1084
 
2931 dpurdie 1085
        if ( index( $data, ',SetProjectBase,' ) >= 0) {
1197 dpurdie 1086
            $opt_preserveProjectBase = 1;
1087
            $opt_ignoreProjectBaseErrors = 1;
1088
            Message ("Preserving ProjectBase");
1089
        }
1090
 
2931 dpurdie 1091
        if ( index( $data, ',AllowMultiPath,' ) >= 0) {
2764 dpurdie 1092
            $opt_AllowMuliplePaths = 1;
1093
            Message ("Allowing Multiple Paths");
1094
        }
1095
 
3967 dpurdie 1096
        if ( index( $data, ',IgnoreBadSourcePath,' ) >= 0) {
1097
            $opt_IgnoreBadSourcePath = 1;
1098
            Message ("Ignore Source Paths tagged as Bad");
2931 dpurdie 1099
        }
1100
 
2764 dpurdie 1101
        if ( $data =~ m~,ForceProjectBase=(.*?),~ ) {
1102
            $opt_forceProjectBase = $1;
1103
            $opt_AllowMuliplePaths = 1;
1104
            Message ("Force Project Base: $opt_forceProjectBase");
1105
        }
1106
 
3967 dpurdie 1107
 
2931 dpurdie 1108
        if ( $data =~ m~,LimitProjectBase=(.*?),~ ) {
2764 dpurdie 1109
            $opt_AllowMuliplePaths = 1;
1110
            @opt_limitProjectBase = split(':', $1);
1111
            Message ("Limit Project Base: @opt_limitProjectBase");
1112
        }
2931 dpurdie 1113
 
3967 dpurdie 1114
        if ( $data =~ m~,SelectProjectBase=(.*?),~ ) {
1115
            $opt_AllowMuliplePaths = 1;
1116
            @opt_selectProjectBase = split(':', $1);
1117
            Message ("Select Project Base from: @opt_selectProjectBase");
1118
        }
1119
 
2931 dpurdie 1120
        if ( $data =~ m~,mergePaths=(.*?),~ ) {
1121
            @opt_mergePaths = split(':', $1);
1122
            Message ("Merge Paths: @opt_mergePaths");
1123
        }
1124
 
1125
        if ( $data =~ m~,DeleteFiles=(.*?),~ ) {
1126
            @opt_deleteFiles = split(':', $1);
1127
            Message ("Delete Files: @opt_deleteFiles");
1128
        }
3967 dpurdie 1129
 
1130
        if ( $data =~ m~,DeleteLinks,~ ) {
1131
            $opt_deleteLinks = 1;
1132
            Message ("Delete soft links");
1133
        }
1134
 
1135
        if ( index( $data, ',ForceSuck,' ) >= 0) {
1136
            $opt_forceSuck = 1;
1137
            Message ("Force sucking empty directories");
1138
        }
1139
 
2931 dpurdie 1140
        if ( index( $data, ',IgnoreProjectBase,' ) >= 0) {
1197 dpurdie 1141
            $opt_ignoreProjectBaseErrors = 1;
1142
            Message ("Ignore ProjectBase Errors");
1143
        }
1144
 
2931 dpurdie 1145
        if ( index( $data, ',IgnoreMakeProject,' ) >= 0) {
2429 dpurdie 1146
            $opt_ignoreMakeProjectErrors = 1;
1147
            Message ("Ignore MakeProject Usage");
1148
        }
2764 dpurdie 1149
 
3967 dpurdie 1150
        if ( index( $data, ',NoBuildFileCheck,' ) >= 0) {
1151
            $opt_ignoreBuildFileClashes = 1;
1152
            Message ("Ignoring Build File Clashes");
1153
        }
1154
 
1155
        if ( index( $data, ',SkipBuildFileCheck,' ) >= 0) {
1156
            $opt_skipBuildNameCheck = 1;
1157
            Message ("Skip Build File Clashes Testing");
1158
        }
1159
 
2931 dpurdie 1160
        if ( index( $data, ',IgnoreBadPath,' ) >= 0) {
2764 dpurdie 1161
            $opt_ignoreBadPaths = 1;
1162
            Message ("Ignore Bad Paths in makefile Usage");
1163
        }
2429 dpurdie 1164
 
2931 dpurdie 1165
        if ( index( $data, ',utf8,' ) >= 0) {
2429 dpurdie 1166
            $mustConvertFileNames = 1;
1167
            Message ("Convert filenames to UTF8");
1168
        }
3967 dpurdie 1169
 
1170
        if ( index( $data, ',NoRetain,' ) >= 0) {
1171
            $opt_reuse = 2;
1172
            Message ("Package Versions not Retained");
1173
        }
1174
 
1175
        if ( index( $data, ',RetainCompressed,' ) >= 0) {
1176
            $opt_saveCompressed = 1;
1177
            Message ("Package Versions will be retained as compressed images");
1178
        }
1179
 
1180
 
1181
        if ( $data =~ m~,Trunk=(.*?),~ ) {
1182
            my $tt = $1;
1183
            $Projects{$tt}{Trunk} = 1;
1184
            Message ("Force project to trunk: $tt");
1185
        }
392 dpurdie 1186
    }
1187
 
1188
    Message("Package Type: $packageType, $pruneModeString");
1189
}
1190
 
1191
 
1192
#-------------------------------------------------------------------------------
1193
# Function        : massageData
1194
#
1195
# Description     : Massage all the data to create a tree of package versions
1196
#                   that can be used to create images as well as an import order
1197
#
1198
# Inputs          : 
1199
#
1200
# Returns         : 
1201
#
1202
my $reprocess=0;
1203
sub calcLinks
1204
{
1205
    #
1206
    #   Process the 'versions' hash and:
1207
    #   Add back references
1208
    #   Find starts and ends
1209
    #       Entry with no previous
1210
    #       Entry with no next
1211
    #
1212
    $reprocess = 0;
1213
    foreach my $entry ( keys(%versions) )
1214
    {
1215
        foreach ( @{ $versions{$entry}{next}} )
1216
        {
1217
            $versions{$_}{last} = $entry;
1218
        }
1219
    }
1220
    @allStartPoints = ();
1221
    @startPoints = ();
1222
    @endPoints = ();
1223
    foreach my $entry ( keys(%versions) )
1224
    {
1225
        push @startPoints, $entry
1226
            unless ( exists $versions{$entry}{last} || $versions{$entry}{badSingleton} );
1227
 
1228
        push @allStartPoints, $entry
1229
            unless ( exists $versions{$entry}{last} );
1230
 
1231
        push @endPoints, $entry
1232
            unless ( @{$versions{$entry}{next}} > 0  )
1233
    }
1234
}
1235
 
1236
sub massageData
1237
{
1238
    #
1239
    #   Report unknown suffixes
1240
    #   Handle bad, or little known project suffixes by creating them
1241
    #
1242
    foreach my $suffix ( keys %suffixes )
1243
    {
1244
        if ( exists $Projects{$suffix} )
1245
        {
1246
            next;
1247
        }
1248
        Message ("Unknown project suffix: '$suffix'");
1249
        push @unknownProjects, $suffix;
1250
        my $cleanSuffix = ucfirst(lc(substr( $suffix, 1)));
1251
        $Projects{$suffix}{Name} = 'Project_' . $cleanSuffix;
1252
    }
1253
 
1254
    calcLinks();
1255
 
1256
    $initialTrees = scalar @allStartPoints;
1257
    Message ('Total RM versions: ' . $totalVersions );
1258
    Message ('Initial trees: ' . $initialTrees );
1259
    #
1260
    #   Attempt to glue all the start points into one chain.
1261
    #   This should allow us to track projects that branch from each other
1262
    #   in cases where the RM data is incorrect/incomplete
1263
    #       Strays are those that have no next or last
1264
    #
1265
    #   Glue based on Name, then PVID (Creation Order)
1266
    #
1267
    {
1268
        #
1269
        #   Examine threads. If it is a single entry thats bad then drop it
1270
        #   This is simple to do. Should examine all entries, but thats a
1271
        #   bit harder. Perhaps later.
1272
        #
1273
        if (1) {
1274
            Message ("Dropping Bad Singletons");
1275
            my $badSingletons;
1276
            foreach my $entry ( sort {$a <=> $b} @startPoints )
1277
            {
1278
                my $ep = $versions{$entry};
1279
                unless ( $ep->{last} || $ep->{next}[0] )
1280
                {
1281
#                    if (  $ep->{isaWip}  )
3967 dpurdie 1282
                    if ( (!$opt_IgnoreBadSourcePath  && (exists $ep->{badVcsTag}  && $ep->{badVcsTag})) || $ep->{isaWip} )
392 dpurdie 1283
                    {
1284
                        $ep->{badSingleton} = 1;
1285
                        $reprocess = 1;
1286
                        $badSingletonCount++;
1287
 
1288
                        # Add to a list of its own.
1289
                        if ( $badSingletons )
1290
                        {
1291
                            push @{$versions{$badSingletons}{next}}, $entry;
1292
                        }
1293
                        $badSingletons = $entry;
1294
                    }
1295
                }
1296
            }
1297
            calcLinks()
1298
                if ( $reprocess );
1299
        }
1300
 
1301
        #
3967 dpurdie 1302
        #   True Patches show up as singletons - they have no parent
1303
        #   Need to create strands of patches to be glued onto the base
1304
        #
1305
        {
1306
            my %patchTree;
1307
            my $patchSeen;
1308
            Message ("Creating patch threads");
1309
            foreach my $entry ( sort {$versions{$a}{version} cmp $versions{$b}{version}} @startPoints )
1310
            {
1311
                my $ep = $versions{$entry};
1312
                next unless ( defined $ep->{buildVersion} );
1313
 
1314
                my $suffix = $ep->{name} . $ep->{suffix};
1315
 
1316
                my ($major, $minor, $patch, $build) = @{$ep->{buildVersion}};
1317
 
1318
                my $patchBase = sprintf ("%3.3d.%3.3d.%3.3d.$suffix", $major, $minor, $patch);
1319
 
1320
                if ( defined $ep->{buildVersion} )
1321
                {
1322
                    if ( $ep->{isaPatch} )
1323
                    {
1324
                        push @{$patchTree{$patchBase}}, $entry;
1325
                        $ep->{patchRoot} = $patchBase;
1326
                        $patchSeen++;
1327
                    }
1328
                }
1329
            }
1330
 
1331
            my %patchRoot;
1332
            if ($patchSeen)
1333
            {
1334
                foreach my $entry ( sort {$versions{$a}{version} cmp $versions{$b}{version}} keys %versions )
1335
                {
1336
                    my $ep = $versions{$entry};
1337
                    next if ( $ep->{isaPatch} );
1338
                    next unless ( defined $ep->{buildVersion} );
1339
 
1340
                    my $suffix = $ep->{name} . $ep->{suffix};
1341
                    my ($major, $minor, $patch, $build) = @{$ep->{buildVersion}};
1342
                    my $patchBase = sprintf ("%3.3d.%3.3d.%3.3d.$suffix", $major, $minor, $patch);
1343
 
1344
                    if ( defined $patchRoot{$patchBase})
1345
                    {
1346
                        Warning ("Multiple Patch Roots identified", $versions{$patchRoot{$patchBase}}{vname},$ep->{vname}, "Both hash to: " . $patchBase );
1347
                    }
1348
                    else
1349
                    {
1350
                        $patchRoot{$patchBase} = $entry;
1351
                    }
1352
                }
1353
 
1354
#DebugDumpData('%patchRoot', \%patchRoot );
1355
                foreach  ( keys %patchTree )
1356
                {
1357
                    my $last;
1358
                    foreach my $entry ( sort {$versions{$a}{version} cmp $versions{$b}{version}} @{$patchTree{$_}} )
1359
                    {
1360
                        if ( $last )
1361
                        {
1362
                            $versions{$last}{MakeTree} = 1;
1363
                            push @{$versions{$last}{next}}, $entry;
1364
                            $reprocess = 1;
1365
                        }
1366
                        else
1367
                        {
1368
                            # First entry in thread.
1369
 
1370
# print "--- Patch Branch $versions{$entry}{vname}\n";
1371
                            $versions{$entry}{branchPoint} = 2;
1372
 
1373
 
1374
                            my $patchBase = $versions{$entry}{patchRoot};
1375
                            my $patchBaseEntry = $patchRoot{$patchBase};
1376
                            if ( $patchBase )
1377
                            {
1378
 
1379
                                if ( defined($patchBaseEntry) && exists ($versions{$patchBaseEntry}) )
1380
                                {
1381
                                    push @{$versions{$patchBaseEntry}{next}}, $entry;
1382
#    Message( "Attaching ",$versions{$entry}{version}," to $patchBase");
1383
                                }
1384
                                else
1385
                                {
1386
    Message( "Cannot Attach ",$versions{$entry}{version}," to $patchBase" );
1387
                                    Warning ("Cannot attach thread. No base version");
1388
                                }
1389
                            }
1390
                        }
1391
                        $last = $entry;
1392
                    }
1393
                }
1394
            }
1395
            calcLinks()
1396
                if ( $reprocess );
1397
        }
1398
#DebugDumpData('$verions', \%versions );
1399
 
1400
        #
392 dpurdie 1401
        #   Create simple trees out of the chains
1402
        #   Tree is based on suffix (project) and version
1403
        #
1404
        {
1405
            my %trees;
1406
            Message ("Entries into trees");
1407
            foreach my $single ( @startPoints )
1408
            {
1409
                my $suffix = $versions{$single}{suffix} || '';
1410
                push @{$trees{$suffix}}, $single;
1411
            }
1412
 
1413
            foreach  ( keys %trees )
1414
            {
1415
                my $last;
3967 dpurdie 1416
                foreach my $entry ( sort {$versions{$a}{version} cmp $versions{$b}{version}} @{$trees{$_}} )
392 dpurdie 1417
                {
1418
                    if ( $last )
1419
                    {
1420
                        $versions{$last}{MakeTree} = 1;
1421
                        push @{$versions{$last}{next}}, $entry;
1422
                        $reprocess = 1;
1423
                    }
1424
                    $last = $entry;
1425
                }
1426
            }
1427
            calcLinks()
1428
                if ( $reprocess );
1429
        }
1430
 
1431
        #
1432
        #   Have a number of trees that are project related
1433
        #   Attempt to create a single tree by inserting
1434
        #   Secondary trees into the main line at suitable points
1435
        #
1436
        my @AllVersions = sort { $a <=> $b } @startPoints;
1437
        my $lastEntry = shift @AllVersions;
1438
        Error ("Oldest entry has a previous version") if ( $versions{$lastEntry}{last}  );
1439
#print "Oldest: $lastEntry\n";
1440
        #
1441
        #   Insert remaining entries into out list, which is now sorted
1442
        #
1443
        my @completeList;
1444
        foreach my $base ( @AllVersions  )
1445
        {
1446
            push @completeList, recurseList($lastEntry);
1447
            @completeList = sort {$a <=> $b} @completeList;
1448
#            Message("Complete List: ", @completeList);
1449
#            Message("Complete List($completeList[0]) Length: " . scalar @completeList);
1450
            $lastEntry = $base;
1451
 
1452
            my $last;
1453
            foreach my $entry ( @completeList )
1454
            {
1455
                if ( $entry > $base )
1456
                {
1457
                    Error ("Not expecting last to be empty. $base, $entry") unless ( $last );
1458
                    last;
1459
                }
1460
                $last = $entry;
1461
            }
1462
 
1463
            #
1464
            #   Insert at end if point not yet found
1465
            #
1466
#print "Inserting $base at $last\n";
1467
            push @{$versions{$last}{next}}, $base;
1468
            $versions{$base}{GluedIn} = 1;
1469
            $reprocess = 1;
1470
        }
1471
 
1472
        #
1473
        #   Recalc basic links if any processing done
1474
        #
1475
        calcLinks()
1476
            if ( $reprocess );
1477
 
1478
    }
1479
 
1480
 
1481
    #
1482
    #   Remove Dead Ends
1483
    #   Packages that were never released
1484
    #       Not locked, unless essential or a branchpoint
1485
    #   Won't consider these to be mainline path.
1486
    #
1487
    {
1488
        Message ("Remove Dead Ends");
1489
        foreach my $entry ( @endPoints )
1490
        {
1491
            my $deadWood;
1492
            while ( $entry )
1493
            {
1494
                last if ( $versions{$entry}{Essential} );
1495
 
1496
                my @next = @{$versions{$entry}{next}};
1497
                my $count = @next;
1498
                last if ( $count > 1 );
1499
 
1500
                last unless ( $versions{$entry}{locked} eq 'N' || $versions{$entry}{isaWip} );
1501
 
1502
                $versions{$entry}{DeadWood} = 1;
1503
                $trimCount++;
1504
            } continue {
1505
                $entry = $versions{$entry}{last};
1506
            }
1507
        }
1508
    }
1509
 
1510
    #
1511
    #   Walk each starting point list and determine new Projects
1512
    #   branchpoints.
1513
    #
1514
    Message ("Locate Projects branch points");
1515
    foreach my $bentry ( keys(%versions) )
1516
    {
1517
        my $baseSuffix = $versions{$bentry}{suffix};
1518
        foreach my $entry ( @{$versions{$bentry}{next}} )
1519
        {
1520
            if ( $baseSuffix ne $versions{$entry}{suffix})
1521
            {
1522
                unless ( exists $versions{$entry}{DeadWood} || $versions{$entry}{badSingleton} )
1523
                {
1524
#print "--- Project Branch $versions{$entry}{vname}\n";
1525
                    $versions{$entry}{branchPoint} = 1;
1526
                    $versions{$entry}{newSuffix} = 1;
1527
                }
1528
            }
1529
        }
1530
    }
2429 dpurdie 1531
 
1532
    #
1533
    #   Mark UkHops special points
1534
    #
1535
    foreach my $entry ( keys(%versions) ) {
1536
        foreach my $rtag_id ( keys %{$versions{$entry}{Releases}}  ) {
1537
            next unless ( exists $ukHopsReleases{$rtag_id} );
1538
            next unless ( $svnRepo =~ m~/ITSO_TRACS$~ );
1539
 
1540
            #
1541
            #   This package is current in a special ukHops release
1542
            #   Need to handle the differently
1543
            #
1544
            my $ukData =  $ukHopsReleases{$rtag_id};
1545
 
1546
            # Mark version we want on the trunk
1547
            # Will calculate tip later
1548
            if ( $ukData->{trunk} )
1549
            {
1550
                #
1551
                #   Can only place on trunk IFF its a tip
1552
                #   May have a WIP.
1553
                #   Solution. Walk to the tip, but only if there is one
1554
                #             path.
1555
                #
1556
                my $end = $entry;
1557
                my $last;
1558
                while ( $end )
1559
                {
1560
                    $last = $end;
1561
                    if ( @{$versions{$end}{next}} > 1)
1562
                    {
1563
                        Warning ("Uk Release. Preferred trunk is not a tip: $versions{$entry}{vname}");
1564
                        last;
1565
                    }
1566
 
1567
                    $end = @{$versions{$end}{next}}[0];
1568
                }
1569
                $versions{$last}{ukTrunk} = 1 ;
1570
            }
1571
 
1572
            #
1573
            #   What to do if the version is in more than one release
1574
            #
1575
            $versions{$entry}{ukBranch}++;
1576
            if ( $versions{$entry}{ukBranch} > 1 )
1577
            {
1578
                Warning ("Version found in multiple Uk Releases - don't know what to do");
1579
            }
1580
 
1581
            #
1582
            #   What to do if the package has multiple version in a release
1583
            #
1584
            $ukData->{count}++;
1585
            if ( $ukData->{count} > 1 )
1586
            {
1587
                Warning ("Package has multiple versions in the one Uk Release: $versions{$entry}{Releases}{$rtag_id}{rname}");
1588
            }
1589
        }
1590
    }
392 dpurdie 1591
 
1592
    #
1593
    #   Prune
2764 dpurdie 1594
    #       Marks paths to root for all essential packages
1595
    #       Marks the last-N from all essential packages
392 dpurdie 1596
    #
1597
    if ( $pruneMode )
1598
    {
1599
        Message ("Prune Tree: $pruneModeString");
1600
        foreach ( @EssentialPackages )
1601
        {
1602
            #next unless ( exists $versions{$_} );      # Aleady deleted
1603
 
1604
            # Mark previous-N to be retained as well
1605
            my $entry = $_;
1606
            my $count = 0;
1607
            while ( $entry )
1608
            {
1609
                last if ( $versions{$entry}{KeepMe} );
2429 dpurdie 1610
#                unless ( $versions{$entry}{isaRipple} )
392 dpurdie 1611
                {
1612
                    my $keepFlag = ($count++ < $opt_retaincount);
1613
                    last unless ( $keepFlag );
1614
                    $versions{$entry}{KeepMe} = $keepFlag;
1615
                }
1616
                $entry = $versions{$entry}{last}
1617
            }
1618
        }
1619
 
1620
        #
1272 dpurdie 1621
        #   Keep recent versions
1341 dpurdie 1622
        #       Keep versions created in the last N days
1623
        #       Will keep recent ripples too
1272 dpurdie 1624
        #
2764 dpurdie 1625
        if ( $pruneMode == 1 )                      # 1 == ripple
1272 dpurdie 1626
        {
1627
            foreach my $entry ( keys(%versions) )
1628
            {
1341 dpurdie 1629
                next unless ( $versions{$entry}{Age} <= $opt_recentAge  );
1630
                $versions{$entry}{keepRecent} = 1;
1631
                $recentCount++;
1632
#print "--- Recent version $versions{$entry}{vname}, $versions{$entry}{Age} <= $opt_recentAge\n";
1272 dpurdie 1633
            }
1634
 
2764 dpurdie 1635
            #
1636
            #   Keep the tip of each branch
1637
            #
1638
            foreach my $entry ( @endPoints )
1639
            {
1640
#print "--- Tip version $versions{$entry}{vname}\n";
1641
                my $count = 0;
1642
                while ( $entry && $count < 2)
1643
                {
1644
                    last if ( $versions{$entry}{Essential} );
1645
                    last if ( $versions{$entry}{keepRecent} );
1646
 
1647
                    next if ( $versions{$entry}{locked} eq 'N'  );
1648
                    next if ( $versions{$entry}{DeadWood} );
1649
 
1650
#print "--- Keeping Tip version $versions{$entry}{vname}\n";
1651
                    $versions{$entry}{keepRecent} = 1;
1652
                    $count++;
1653
 
1654
                } continue {
1655
                    $entry = $versions{$entry}{last};
1656
                }
1657
            }
1272 dpurdie 1658
        }
1659
 
1660
        #
392 dpurdie 1661
        #   Keep versions that are common parents to Essential Versions
1662
        #       Mark paths through the tree to essential versions
1663
        #       Mark nodes with the number of essential versions that they sprout
1664
        #   Don't do it if we are ripple pruning
1665
        #
1666
        Message ("Prune Tree keep common parents");
1667
        if ( $pruneMode != 1 )
1668
        {
1669
            foreach my $entry ( @endPoints )
1670
            {
1671
                my $hasEssential = 0;
1672
                $visitId++;
1673
                while ( $entry )
1674
                {
1675
                    $hasEssential = 1 if ( exists ($versions{$entry}{Essential}) && $versions{$entry}{Essential} );
1676
                    if ( $hasEssential )
1677
                    {
1678
                        if ( @{$versions{$entry}{next}} > 1 )
1679
                        {
1680
                            $versions{$entry}{EssentialSplitPoint}++;
1681
                        }
1682
                        last if ( exists $versions{$entry}{EssentialPath} );
1683
                        $versions{$entry}{EssentialPath} = 1;
1684
                    }
1685
 
1686
                    if ( ($versions{$entry}{visitId} || 0) == $visitId )
1687
                    {
1688
                        DebugDumpData ("Versions", \%versions );
1689
                        Warning ("Circular dependency");
1690
                        last;
1691
                    }
1692
                    $versions{$entry}{visitId} = $visitId;
1693
 
1694
                    $entry = $versions{$entry}{last};
1695
                }
1696
            }
1697
        }
1698
 
1699
        #
1700
        #   Keep first version of each ripple. Must keep first
1701
        #   Group ripples together so that they can be proccessed at the same time
1702
        #
1703
        calcRippleGroups()
1704
            if ( $pruneMode == 1);
1705
 
1706
        #
1707
        #   Delete all nodes that are not marked for retention
1708
        #   This is rough on the tree
1709
        #
1710
        Message ("Prune Tree Deleting");
1711
 
1712
        # 0 - Keep me
1713
        # 1 - Prune me
1714
        sub pruneMe
1715
        {
1716
            my ($entry) = @_;
1717
 
1718
            return 0 unless ( exists $versions{$entry} );
1719
            return 0 unless ( $versions{$entry}{last} );
2429 dpurdie 1720
#            return 0 if ( ($pruneMode == 2) && exists $versions{$entry}{KeepMe} );
1721
            return 0 if ( exists $versions{$entry}{KeepMe} );
392 dpurdie 1722
            return 0 if ( exists $versions{$entry}{Essential} );
1723
            return 0 if ( $versions{$entry}{newSuffix} );
1724
            return 0 if ( $versions{$entry}{newSuffix} && (exists $versions{$entry}{EssentialPath}) );
1725
#            return 1 if ( exists $versions{$entry}{DeadWood} );
1726
            return 0 if ( exists $versions{$entry}{EssentialSplitPoint} && $versions{$entry}{EssentialSplitPoint} > 1 );
1727
            return 0 if ( exists $versions{$entry}{keepLowestRipple} &&  $versions{$entry}{keepLowestRipple} );
1728
            return 0 if ( ($pruneMode == 1) && ! $versions{$entry}{isaRipple} );
1272 dpurdie 1729
            return 0 if ( exists $versions{$entry}{keepRecent} && $versions{$entry}{keepRecent} );
392 dpurdie 1730
            return 1;
1731
        }
1732
 
2764 dpurdie 1733
 
1734
        #
1735
        #   Determine a list of entries to be pruned
1736
        #   Done in two steps so that we can skip the pruning if its only a small number
1737
        #
1738
        my @pruneList;
392 dpurdie 1739
        foreach my $entry ( keys(%versions) )
1740
        {
2764 dpurdie 1741
            push ( @pruneList, $entry ) if ( pruneMe($entry) );
1742
        }
1743
 
1744
 
1745
        #
1746
        #   If the list is very small then just import all of them
1747
        #
1748
        if ( scalar @pruneList < 10 )
1749
        {
1750
            Message ("Retaining pruned entries - low count:" . scalar @pruneList );
1751
            @pruneList = ();
1752
        } else {
1753
            my $total = scalar keys %versions;
1754
 
1755
            if ( scalar @pruneList < ($total / 15))
1756
            {
1757
                Message ("Retaining pruned entries - low percentage of $total:" . scalar @pruneList );
1758
                @pruneList = ();
1759
            }
1760
        }
1761
 
1762
 
1763
        foreach my $entry (@pruneList )
1764
        {
392 dpurdie 1765
#print "--- Prune: $versions{$entry}{vname}\n";
1766
 
1767
            # Delete the current node
1768
            #
1769
            my @newNext;
1770
            $pruneCount++;
1771
            my $last = $versions{$entry}{last};
1772
            foreach ( @{$versions{$last}{next}} )
1773
            {
1774
                next if ( $_ == $entry );
1775
                push @newNext, $_;
1776
            }
1777
            foreach ( @{$versions{$entry}{next}} )
1778
            {
1779
                push @newNext, $_;
1780
                $versions{$_}{last} = $last;
1781
            }
1782
 
1783
            @{$versions{$last}{next}} = @newNext;
1784
            delete $versions{$entry};
1785
        }
1786
 
1787
        # Recalculate endpoints
1788
        calcLinks();
1789
    }
1790
    else
1791
    {
1792
        #   No rippling happening
1793
        #   Some process still need to happen
1794
        #
1795
        calcRippleGroups();
1796
    }
1797
 
1798
    #
2429 dpurdie 1799
    #   Want some versions to be forced to tip trunk
1800
    #
1801
    foreach my $name ( keys %ukHopsTip )
1802
    {
1803
        foreach my $entry ( keys(%versions) )
1804
        {
1805
            next unless ( $versions{$entry}{name} eq $name  );
1806
            next unless ( exists $versions{$entry}{Releases}{$ukHopsTip{$name}} );
1807
 
1808
            #
1809
            #   Force this suffix to be the trunk
1810
            #   Remove all others
1811
            #
1812
            foreach my $suffix ( keys %Projects )
1813
            {
1814
                delete $Projects{$suffix}{Trunk};
1815
            }
1816
            my $suffix = $versions{$entry}{suffix};
1817
            $Projects{$suffix}{Trunk} = 1;
1818
        }
1819
    }
1820
 
1821
    #
392 dpurdie 1822
    #   Calculate best through-path for branches in the tree
1823
    #   Attempt to keep that 'max' version on the mainline
1824
    #   May be modified by -tip=nnnn
1825
    #
1826
    #   For each leaf (end point), walk backwards and mark each node with the
1827
    #   max version see. If we get to a node which already has been marked then
1828
    #   stop if our version is greater. We want the value to be the max version
1829
    #   to a leaf
1830
    #
1831
    #   Account for 'suffix'. When suffix changes, then the 'max' version must
1832
    #   be recalculated
1833
    #
1834
 
1835
    Message ("Calculate Max Version");
1836
    my $maxVersion;
1837
    foreach my $entry ( @endPoints )
1838
    {
1839
        my $lastSuffix;
1840
        my $forceTip;
1841
        while ( $entry )
1842
        {
1843
            if (!defined($lastSuffix) || ($versions{$entry}{suffix} ne $lastSuffix) )
1844
            {
1845
                $maxVersion = '0';
1846
                $visitId++;
1847
                $forceTip = ( exists $tipVersions{$versions{$entry}{vname}} );
2429 dpurdie 1848
                $forceTip = 1 if $versions{$entry}{ukTrunk};
392 dpurdie 1849
                delete $tipVersions{$versions{$entry}{vname}};
1850
                $maxVersion = '999.999.999.999.zzz' if ( $forceTip );
1851
                $lastSuffix = $versions{$entry}{suffix};
1852
#print "---Tip Found\n" if $forceTip;
1853
            }
1854
 
1855
            # Detect circular dependencies
1856
            if ( ($versions{$entry}{visitId} || 0) == $visitId )
1857
            {
1858
                DebugDumpData ("Circular dependency: Versions", \%versions );
1859
                Warning ("Circular dependency");
1860
                last;
1861
            }
1862
            $versions{$entry}{visitId} = $visitId;
1863
 
1864
            my $thisVersion = $versions{$entry}{version} || '';
1865
            if ( $thisVersion gt $maxVersion )
1866
            {
1867
                $maxVersion = $thisVersion;
1868
            }
1869
 
1870
            if ( exists $versions{$entry}{maxVersion} )
1871
            {
1872
                if ( $versions{$entry}{maxVersion} gt $maxVersion )
1873
                {
1874
                    last;
1875
                }
1876
            }
1877
 
1878
            $versions{$entry}{maxVersion} = $maxVersion;
1879
            $entry = $versions{$entry}{last};
1880
        }
1881
    }
1882
 
1883
 
1884
    #
1885
    #   Locate all instances where a package-version branches
1886
    #   Determine the version that should be on the non-branching path
1887
    #
1888
    #   Reorder the 'next' list so that the first item is the non-branching
1889
    #   path. This will be used in the data-insertion phase to simplify the
1890
    #   processing.
1891
    #
1892
    Message ("Calculate package version branches");
1893
    foreach my $entry ( sort {$a <=> $b} keys(%versions) )
1894
    {
1895
        calculateWalkOrder($entry);
1896
    }
1897
 
1898
    #
1899
    #   Mark Project Branch Tips as they will be in the Repository
1900
    #   Find each project head and walk primary entry to the end.
1901
    #
1902
    foreach my $entry ( keys(%versions) )
1903
    {
1904
        #
1905
        #   Root of each tree is 'new'
1906
        #
1907
        unless ( defined $versions{$entry}{last})
1908
        {
1909
            unless ( $versions{$entry}{badSingleton} )
1910
            {
1911
                $versions{$entry}{newSuffix} = 1;
1912
            }
1913
        }
1914
 
1915
        #
1916
        #   Update stats
1917
        #
1918
        $badVcsCount++ if ( $versions{$entry}{badVcsTag} );
1919
        $ProjectCount++ if ( $versions{$entry}{newSuffix} );
1920
        next if ( $opt_flat );
1921
 
1922
        next unless ($versions{$entry}{newSuffix} );
1923
#print "--- Project new Suffix $versions{$entry}{vname}\n";
1924
 
1925
 
1926
        my $suffix = $versions{$entry}{suffix};
1927
        $knownProjects{$suffix}{count}++;
1928
 
1929
        my $next = $versions{$entry}{next}[0];
1930
        my $tip;
1931
        while ( $next )
1932
        {
1933
            last if ( $suffix ne $versions{$next}{suffix} );
1934
            $tip = $next unless (exists ($versions{$next}{DeadWood}) || $versions{$next}{badSingleton});
1935
            $next = $versions{$next}{next}[0];
1936
        }
1937
 
1938
        $versions{$tip}{Tip} = 1 if $tip;
1939
    }
1940
 
1941
    unless ( $opt_flat )
1942
    {
1943
        my $finalTrees = scalar @startPoints;
1944
        Warning ("Still have multiple trees: $finalTrees") unless ( $finalTrees == 1 );
1945
    }
1946
 
1947
    #
1948
    #   Display warnings about multiple
1949
    #
1950
    foreach ( sort keys %knownProjects )
1951
    {
1952
        my $count = $knownProjects{$_}{count} || 0;
1953
        Warning ("Multiple Project Roots: $_ ($count)" )
1954
            if ( $count > 1 );
1955
    }
1956
 
1957
    #
1958
    #   Display warnings about Bad Essential Packages
1959
    #
1960
    $allSvn = 1;
1961
    foreach my $entry ( keys(%versions) )
1962
    {
3967 dpurdie 1963
        markDpkgArchive($entry);
392 dpurdie 1964
        $rippleCount++ if ( exists($versions{$entry}{isaRipple}) && $versions{$entry}{isaRipple} );
1965
        $allSvn = 0 unless ( $versions{$entry}{isSvn} );
1966
        next unless ( exists $versions{$entry}{Essential}  );
1967
        next unless ( $versions{$entry}{badVcsTag}  );
1968
        push @badEssentials, $entry;
3967 dpurdie 1969
        Warning ("BadVCS Essential: " . GetVname($entry));
392 dpurdie 1970
    }
1971
 
1972
    #
1973
    #   All done
1974
    #
1270 dpurdie 1975
    $processTotal = scalar keys %versions;
1976
    Message("Retained entries: $processTotal" );
392 dpurdie 1977
    Message("Pruned entries: $pruneCount");
1978
    Message("Deadwood entries: $trimCount");
1979
    Message("Bad Singletons: $badSingletonCount");
1980
    Message("Ripples: $rippleCount");
1341 dpurdie 1981
    Message("Recent entries: $recentCount");
392 dpurdie 1982
}
1983
 
1984
sub calculateWalkOrder
1985
{
1986
    my ($entry) = @_;
1987
    my @next = @{$versions{$entry}{next}};
1988
    my $count = @next;
1989
    my @ordered;
1990
    my $main;
1991
 
1992
    if ( $count > 1 )
1993
    {
1994
        # Array to hash to simplify removal
1995
        my %nexts = map { $_ => 1 } @next;
1996
        foreach my $e ( @next )
1997
        {
1998
 
1999
            #
2000
            #   Locate branch points that are not a part of a new project
2001
            #   These will not be preferred paths for walking
2002
            #
2003
            if ( !defined($versions{$e}{branchPoint}) && $versions{$entry}{suffix} ne $versions{$e}{suffix} )
2004
            {
2005
                unless ( exists $versions{$e}{DeadWood} || $versions{$e}{badSingleton}  )
2006
                {
2007
#print "--- Project Branch (1) $versions{$e}{vname}\n";
2008
                    $versions{$e}{branchPoint} = 1;
2009
                    $versions{$e}{newSuffix} = 1;
2010
                }
2011
            }
2012
 
2013
            #
2014
            #   Remove those that already have a branch,
2015
            #
2016
            if ( $versions{$e}{branchPoint} || $versions{$e}{newSuffix} || $versions{$e}{DeadWood}  )
2017
            {
2018
                push @ordered, $e;
2019
                delete $nexts{$e};
2020
            }
2021
        }
2022
        #
2023
        #   Select longest arm as the non-branching path
2024
        #   Note: Reverse sort order
2025
        #         Done so that 'newest' item is given preference
2026
        #         to the main trunk in cases where all subtrees are
2027
        #         the same length
2028
        #
2029
        my $maxData = '';
2030
        my $countEntry;
2031
        foreach my $e ( sort {$b <=> $a} keys %nexts )
2032
        {
2033
            if ( $versions{$e}{maxVersion} gt $maxData )
2034
            {
2035
                $maxData = $versions{$e}{maxVersion};
2036
                $countEntry = $e;
2037
            }
2038
        }
2039
        if ($countEntry)
2040
        {
2041
            $main = $countEntry;
2042
            delete $nexts{$countEntry};
2043
        }
2044
 
2045
        #
2046
        #   Append the remaining
2047
        #
2048
        push @ordered, keys %nexts;
2049
 
2050
        #
2051
        #   Re-order 'next' so that the main path is first
2052
        #   Sort (non main) by number
2053
        #
2054
        @ordered = sort {$a <=> $b} @ordered;
2055
        unshift @ordered, $main if ( $main );
2056
        @{$versions{$entry}{next}} = @ordered;
2057
 
2058
        #
2059
        #   Ensure all except the first are a branch point
2060
        #   First may still be a branch point
2061
        #
2062
        shift @ordered;
2063
        foreach my $e ( @ordered )
2064
        {
2065
            $versions{$e}{branchPoint} = 1;
2066
        }
2067
    }
2068
}
2069
 
2070
#-------------------------------------------------------------------------------
2071
# Function        : calcRippleGroups
2072
#
2073
# Description     : Locate and mark ripple groups
1272 dpurdie 2074
#                   packages that are ripples of each other
392 dpurdie 2075
#                       Keep first version of each ripple. Must keep first
2076
#                       Group ripples together so that they can be
2077
#                       proccessed at the same time
2078
#
2079
# Inputs          : 
2080
#
2081
# Returns         : 
2082
#
2083
sub calcRippleGroups
2084
{
2085
    my %rippleVersions;
2086
    foreach my $entry ( keys(%versions) )
2087
    {
2088
        my $ep = $versions{$entry};
2089
        if ( defined $ep->{buildVersion} )
2090
        {
2091
            my $suffix = $ep->{suffix};
2931 dpurdie 2092
            my $pname = $ep->{name};
2093
            $suffix = $pname . $suffix;
2094
 
392 dpurdie 2095
            my ($major, $minor, $patch, $build) = @{$ep->{buildVersion}};
2096
#print "--- $major, $minor, $patch, $build, $suffix\n";
2097
 
2931 dpurdie 2098
            my $key;
2099
            my $type = 'patch';
2100
            $type = $packageRippleControl{$pname} if ( exists  $packageRippleControl{$pname});
2101
            if ( $type eq 'patch' ) {
2102
                $key = "$major.$minor.$patch";
2103
#                $build = $build;
2104
 
2105
            } elsif ( $type eq 'minor' ) {
2106
                $key = "$major.$minor";
2107
#                $build = ($patch * 1000) + $build;
2108
 
2109
            } elsif ( $type eq 'major' ) {
2110
                $key = "$major";
2111
#                $build = ($minor * 1000000) + ($patch * 1000) + $build;
2112
            } else {
2113
                Error ("Invalid type in packageRippleControl for package $pname: $type");
392 dpurdie 2114
            }
2931 dpurdie 2115
 
2116
            $rippleVersions{$suffix}{$key}{count}++;
2117
            my $rp = $rippleVersions{$suffix}{$key};
2118
            $rp->{list}{$entry} = $versions{$entry}{version};
2119
 
2120
#            next if ( $ep->{badVcsTag} );
2121
#            next if ( $ep->{locked} eq 'N');
2122
 
2123
#            if (!defined ($rp->{min}) || $rp->{min} > $build )
2124
#            {
2125
#                $rp->{pvid} = $entry;
2126
#                $rp->{min} = $build;
2127
#            }
392 dpurdie 2128
        }
2129
    }
2130
#            DebugDumpData("rippleVersions", \%rippleVersions );
2131
 
2132
    while ( my($suffix, $e1) = each %rippleVersions )
2133
    {
2931 dpurdie 2134
#DebugDumpData("rippleVersions. Suffix , e1", $suffix, $e1 );
2135
 
392 dpurdie 2136
        while ( my( $mmp, $e2) = each %{$e1} )
2137
        {
2931 dpurdie 2138
#            next unless ( exists  $e2->{pvid} );
2139
#            my $entry = $e2->{pvid};
2140
#            if ( !exists $versions{$entry} )
2141
#            {
2142
#                Error ("Internal: Expected entry not found: $entry, $mmp");
2143
#            }
2144
#
2145
#            $versions{$entry}{keepLowestRipple} = 1;
2146
#print "--- Keep Ripple: $versions{$entry}{name} $versions{$entry}{vname}\n";
392 dpurdie 2147
 
2148
            #
2149
            #   Update entry with list of associated ripples, removing lowest
2150
            #
2931 dpurdie 2151
            my @rippleList = sort {$e2->{list}{$a} cmp $e2->{list}{$b}} keys %{$e2->{list}};
2152
            my $firstEntry = shift @rippleList;
2153
            $versions{$firstEntry}{keepLowestRipple} = 1;
2154
#print "--- Keep Lowest: $versions{$firstEntry}{name} $versions{$firstEntry}{vname}\n";
2155
 
392 dpurdie 2156
            if ( @rippleList)
2157
            {
2158
#DebugDumpData("LIST: $entry", $e2->{list}, \@rippleList  );
2931 dpurdie 2159
                @{$versions{$firstEntry}{rippleList}} = @rippleList;
2160
 
2161
#                foreach my $pvid ( @rippleList )
2162
#                {
2163
#                    print "----- $versions{$pvid}{name} $versions{$pvid}{vname}\n";
2164
#                }
392 dpurdie 2165
            }
2166
        }
2167
    }
2931 dpurdie 2168
#    Error ("Just Testing");
392 dpurdie 2169
}
2170
 
2171
#-------------------------------------------------------------------------------
2172
# Function        : processBranch
2173
#
2174
# Description     : Process one complete branch within the tree of versions
2175
#                   May be called recursivly to walk the tree
2176
#
2177
# Inputs          : Array of package-version ID to process
2178
#
2179
# Returns         : Nothing
2180
#
2181
 
2182
sub processBranch
2183
{
2184
    foreach my $entry ( @_ )
2185
    {
2186
        #
2187
        #   Do we need to create a branch before we can process this package
2188
        #
2189
        if ( $versions{$entry}{newSuffix} || $versions{$entry}{branchPoint} )
2190
        {
2191
            newProject();
2192
            $createBranch = 1;
2193
            $createSuffix = 1 if $versions{$entry}{newSuffix};
2194
        }
2931 dpurdie 2195
        newPackageVersion( $entry );
392 dpurdie 2196
 
2197
no warnings "recursion";
2198
        processBranch (@{$versions{$entry}{next}});
2199
    }
2200
}
2201
 
2202
#-------------------------------------------------------------------------------
2203
# Function        : newPackageVersion
2204
#
2205
# Description     : Create a package version
2206
#
2207
# Inputs          : $entry              - Ref to entry being proccessed
2208
#
2209
# Returns         :
2210
#
2211
sub newPackageVersion
2212
{
2213
    my ($entry) = @_;
2214
    my %data;
2215
    my $flags = 'e';
2216
    my $rv = 1;
2217
    my $startTime = time();
2218
    my $timestamp = localtime;
2219
 
2220
    $data{rmRef} = 'ERROR';
2221
    $data{tag} = 'ERROR';
2222
 
2223
    #
2224
    #   If its been processed then fake that its been done
2225
    #   May have been a ripple that we processed
2226
    #
1270 dpurdie 2227
    return if ($versions{$entry}{Processed});
2228
    $processCount++;
392 dpurdie 2229
    Message ("------------------------------------------------------------------" );
1270 dpurdie 2230
    Message ("Package $processCount of $processTotal");
2231
 
392 dpurdie 2232
    Message ("New package-version: " . GetVname($entry) . " Tag: " . $versions{$entry}{vcsTag} );
2233
 
1341 dpurdie 2234
    #
2235
    #   Detect user abort
2236
    #
2237
    if ( -f $cwd . '/stopfile' )
2238
    {
2239
        $globalError = 1;
2240
        Message ("Stop file located");
2241
    }
392 dpurdie 2242
 
2243
    #
2244
    #   If we have a global error,then we pretend to process, but we
2245
    #   report errors for the logging system
2246
    #
1356 dpurdie 2247
    if ( $globalError )
392 dpurdie 2248
    {
1356 dpurdie 2249
        Message ("Global error prevents futher importation");
2250
    }
2251
    else
2252
    {
392 dpurdie 2253
        #
2254
        #   Call worker function
3967 dpurdie 2255
        #   It will exit on any error so that it can be logged
392 dpurdie 2256
        #
2257
        $rv = newPackageVersionBody( \%data, @_ );
2258
        $globalError = 1 if ( $rv >= 10 );
2259
    }
2260
 
2261
    #
2262
    #   Highlight essential packages that failed to transfer
2263
    #
2264
    if ( $globalError ) {
2265
        $flags = 'e';
2266
    } elsif ( $rv && ( exists $versions{$entry}{Essential} ) ) {
2267
        $flags = 'X';
2268
    } elsif ( $rv ) {
2269
        $flags = 'E';
2270
    } else {
2271
        $flags = 'G';
2272
    }
2273
 
2274
    #
2275
    #   Always log results to a file
2276
    #   Flags:
2277
    #       e - Error: Global Fatal causes other versions to be ignored
2278
    #       X - Essential Package NOT proccessed
2279
    #       E - Error processing package
2280
    #       G - Good
2281
    #
2282
    my $duration = time() - $startTime;
2283
    my $line = join(';',
2284
            $flags,
2285
            $entry,
2286
            $packageNames,
2287
            $versions{$entry}{vname},
2288
            $data{rmRef},
2289
            $data{tag},
2290
            $timestamp,
2291
            $duration,
2292
            $data{errStr} || ''
2293
            );
2294
    logToFile( $cwd . '/importsummary.txt', ";$line;");
2450 dpurdie 2295
 
392 dpurdie 2296
    #
2297
    #   Sava data
2298
    #
2764 dpurdie 2299
    if ( $rv != 6 )
2300
    {
2301
        $data{errFlags} = $flags;
2302
        $data{duration} = $duration;
2303
    }
392 dpurdie 2304
    $versions{$entry}{rmRef} = $data{rmRef};
1272 dpurdie 2305
    delete $data{rmRef};
2306
    delete $data{tag};
1341 dpurdie 2307
    ##delete $data{ViewRoot};
1272 dpurdie 2308
    $versions{$entry}{data} = \%data;
2309
 
392 dpurdie 2310
    #
2311
    #   Delete the created view
2312
    #   Its just a directory, so delete it
2313
    #
2314
    if ( $data{ViewRoot} && -d $data{ViewRoot})
2315
    {
3967 dpurdie 2316
        my $cfile = saneLabel($entry) . '.tgz';
2931 dpurdie 2317
        if ( $opt_reuse == 0 || $opt_reuse == 2 || ($rv && ($rv != 4 && $rv != 12 && $rv != 5 )) )
1341 dpurdie 2318
        {
2319
            Message ("Delete View: $data{ViewRoot}");
2320
            RmDirTree ($data{ViewRoot} );
3967 dpurdie 2321
            unlink $cfile;
1341 dpurdie 2322
        }
2323
        else
2324
        {
2325
            Message ("Retaining View: $data{ViewRoot}");
3967 dpurdie 2326
            if ( $opt_saveCompressed )
2327
            {
2328
                Message ("Compressing the retained directory");
2329
                unless ( -f $cfile )
2330
                {
2331
                    my $rv = System ('tar', '-czf', $cfile, $data{ViewRoot} );
2332
                    if ( $rv )
2333
                    {
2334
                        Warning("Failed to compress directory");
2335
                    }
2336
                }
2337
                else
2338
                {
2339
                    Message ("Reusing compressed file");
2340
                }
2341
                RmDirTree ($data{ViewRoot} );
2342
            }
1341 dpurdie 2343
        }
2344
 
392 dpurdie 2345
    }
1341 dpurdie 2346
    else
2347
    {
2348
        Message ("No view to delete");
2349
    }
392 dpurdie 2350
 
2351
    #
2931 dpurdie 2352
    #   Create pretty pictures
392 dpurdie 2353
    #
2931 dpurdie 2354
    unless ( $rv )
392 dpurdie 2355
    {
2931 dpurdie 2356
        getSvnData();
2357
        createImages();
2358
    }
392 dpurdie 2359
 
2931 dpurdie 2360
 
2361
    if($opt_processRipples)
2362
    {
2363
        #
2364
        #   If this version has any 'ripples' then process them while we have the
2365
        #   main view. Note the ripple list may contain entries that do not
2366
        #   exist - they will have been pruned.
2367
        #
2368
        foreach my $rentry ( @{$versions{$entry}{rippleList}} )
392 dpurdie 2369
        {
2931 dpurdie 2370
            next unless( exists $versions{$rentry} );
2371
 
2372
            if ($versions{$rentry}{Processed})
2373
            {
2374
                Warning ("Ripple Processed before main entry");
2375
                $versions{$rentry}{rippleProcessed} = 1;
2376
            }
2377
 
2378
            Message ("Proccessing associated Ripple: " . GetVname($rentry));
2379
            newPackageVersion($rentry);
392 dpurdie 2380
        }
2931 dpurdie 2381
    }
392 dpurdie 2382
 
2383
}
2384
 
2385
#-------------------------------------------------------------------------------
2386
# Function        : newPackageVersionBody
2387
#
2388
# Description     : Perform the bulk of the work in creating a new PackageVersion
2389
#                   Designed to return on error and have error processing
2390
#                   performed by caller
2391
#
2392
# Inputs          : $data               - Shared data
2393
#                   $entry              - Package entry to process
2394
#
2395
# Returns         : Error Code
2396
#                         0 - All is well
1272 dpurdie 2397
#                       <10 - Recoverable error
2450 dpurdie 2398
#                               1 - Bad VCS Tag
2399
#                               2 - No Files in the extracted view
2400
#                                   Label not found
2401
#                                   Failed to extract files from CC
2402
#                                   No Files in the extracted view after labeling dirs
2403
#                               3 - Deadwood
2404
#                               4 - Bad usage of ProjectBase detected
2405
#                                   Use of MakeProject detected
2406
#                               5  - Subversion Import disabled
2764 dpurdie 2407
#                               6  - Restored via resume
392 dpurdie 2408
#                       >10 - Fatal error
2409
#
2410
sub newPackageVersionBody
2411
{
2412
    my ($data, $entry) = @_;
2413
    my $rv;
2764 dpurdie 2414
    my $vcs_type;
392 dpurdie 2415
    my $cc_label;
2416
    my $cc_path;
2429 dpurdie 2417
    my $cc_path_original;
3967 dpurdie 2418
    my $selectDir;
392 dpurdie 2419
 
2420
    #
2421
    #   Init Data
2422
    #
2423
    $data->{rmRef} = 'ERROR';
2424
    $data->{tag} = '';
2425
    $data->{ViewRoot} = undef;
2426
    $data->{ViewPath} = undef;
2427
    $data->{errStr} = '';
2428
    $versions{$entry}{Processed} = 1;
2429
 
2430
 
2431
    SystemConfig ('ExitOnError' => 0);
2432
 
2433
    push @processOrder, $entry;
2434
    return 0 if ( $opt_test );
2435
 
2764 dpurdie 2436
    #
2437
    #   Calculate the label for the target package
2438
    #   Use format <packageName>_<PackageVersion>
2439
    #   Need to handle WIPs too.
2440
    #
2441
    my $import_label = saneLabel($entry);
2442
 
2443
    #
2444
    #   If resuming - then test existence
2445
    #
2446
    if ( $opt_resume )
2447
    {
2448
        if ( exists $restoreData{$entry}  )
2449
        {
2450
 
2451
            #
2452
            #   May be able to test existence by looking at $versions{$entry}{svnVersion}
2453
            #   The hard work may have been done
2454
            #
2455
            my $isInSvn = 0;
2456
            if ( exists $versions{$entry}{svnVersion} && $versions{$entry}{svnVersion}  )
2457
            {
2458
                $isInSvn = 1;
2459
            }
2460
            Message("SvnVersion check: $isInSvn");
2461
 
2462
            $rv = testSvnLabel( "$svnRepo/$packageNames", $import_label );
2463
            unless ( $rv )
2464
            {
2465
                Message ("Skip import - resume detected presense");
2466
                $firstVersionCreated = $entry unless ( $firstVersionCreated );
2467
                $versions{$entry}{TagCreated} = 2;
2468
                foreach  ( keys %{$restoreData{$entry}} )
2469
                {
2470
                    $data->{$_} = $restoreData{$entry}{$_};
2471
                }
2472
                $forceImportFlush = 1;
2473
DebugDumpData('Data', $data );
2474
                return 6;
2475
            }
2476
        }
2477
        else
2478
        {
2479
            Warning ("Resume data missing");
2480
        }
2481
    }
2482
 
392 dpurdie 2483
#   Keep DeadWood. May be a WIP
2484
#    if ( exists $versions{$entry}{DeadWood} && $versions{$entry}{DeadWood} )
2485
#    {
2486
#        $data->{errStr} = 'Package is DeadWood';
2487
#        return 3;
2488
#    }
2489
 
2490
    #
3967 dpurdie 2491
    #   Check for a handcrafted substitute package
2492
    #       May have been created with gen_cots
392 dpurdie 2493
    #
3967 dpurdie 2494
    testDpkgArchive($entry);
2495
    if (extractFilesFromStore($data, $entry) )
392 dpurdie 2496
    {
3967 dpurdie 2497
        Message ("Using package from store");
392 dpurdie 2498
    }
3967 dpurdie 2499
    else
2500
    {
2501
        #
2502
        #   Determine version information
2503
        #
2504
        if ($opt_IgnoreBadSourcePath)
2505
        {
2506
            # Ignore versions tagged with a bad source path
2507
            #   Will expect that the Vob will be forced
2508
            #   Hope that we have a label
2509
            delete $versions{$entry}{badVcsTag};
2510
        }
392 dpurdie 2511
 
3967 dpurdie 2512
        $data->{tag} = $versions{$entry}{vcsTag} || '';
2513
        if ( $versions{$entry}{badVcsTag} )
2514
        {
2515
            Warning ("Error: Bad VcsTag for: " . GetVname($entry),
2516
                     "Tag: $data->{tag}" );
2517
            $data->{errStr} = 'VCS Tag Marked as Bad';
2518
            return 1;
392 dpurdie 2519
 
3967 dpurdie 2520
        }
392 dpurdie 2521
 
2522
 
3967 dpurdie 2523
        $data->{tag} =~ m~^(.+?)::(.*?)(::(.+))?$~;
2524
        $vcs_type = $1;
2525
        $cc_label = $4;
2526
        $cc_path = $2;
2527
        $cc_path = '/' . $cc_path;
2528
        $cc_path =~ tr~\\/~/~s;
2529
        $cc_path_original = $cc_path;
1270 dpurdie 2530
 
3967 dpurdie 2531
        #
2532
        #   Process IgnoreBadSourcePath
2533
        #
2534
        if ($opt_IgnoreBadSourcePath)
392 dpurdie 2535
        {
3967 dpurdie 2536
            if (($vcs_type eq 'UC') || (length($cc_label) < 1))
2537
            {
2538
                $versions{$entry}{badVcsTag} = 98;
2539
                Warning ("Error: Bad VcsTag for: " . GetVname($entry),
2540
                         "Tag: $data->{tag}" );
2541
                $data->{errStr} = 'VCS Tag Marked as Bad - and has no label';
2542
                return 1;
2543
            }
392 dpurdie 2544
        }
2545
 
3967 dpurdie 2546
        #
2547
        #   Correct well known path mistakes in CC paths
2548
        #
2549
        if ( $vcs_type eq 'CC' )
2764 dpurdie 2550
        {
3967 dpurdie 2551
            $cc_path =~ s~/build.pl$~~i;
2552
            $cc_path =~ s~/src$~~i;
2553
            $cc_path =~ s~/cpp$~~i;
2554
            $cc_path =~ s~/MASS_Dev/Infra/~/MASS_Dev_Infra/~i;
2555
            $cc_path =~ s~/MASS_Dev/Tools/~/MASS_Dev_Tools/~i;
2556
            $cc_path =~ s~/MASS_Dev/Bus/~/MASS_Dev_Bus/~i;
2557
            $cc_path =~ s~/MASS_Dev_Bus/Cbp/~/MASS_Dev_Bus/CBP/~i;
2558
            $cc_path =~ s~/MREF_Package/ergpostmongui$~/MREF_Package/ergpostmongui~i;
2559
            $cc_path =~ s~/MREF_../MREF_Package/~/MREF_Package/~i;
2560
            $cc_path =~ s~/MREF_Package/mass_ergocdp/~/MREF_Package/ergocdp/~i;
2561
            $cc_path =~ s~/MASS_Dev_Bus/CBP/systemCD.ejb~/MASS_Dev_Bus/CBP/systemCD/ejb~i;
2562
            $cc_path =~ s~/MASS_Dev_Bus/Financial/cpp/paymentmanager~/MASS_Dev_Bus/Financial/cpp/paymentmanager~i;
2563
            $cc_path =~ s~/MASS_Dev_Bus/WebServices~/MASS_Dev_Bus/WebServices~i;
2564
            $cc_path =~ s~/MASS_Dev_Bus/CBP/nullAdapter~//MASS_Dev_Bus/CBP/nullAdaptor~i;
2565
            $cc_path =~ s~/DPG_SWBase/Services~/DPG_SWBase/services~i;
2566
 
2567
 
2568
            $cc_path = '/MASS_Dev_Bus/Application' if ( $versions{$entry}{name} eq 'application');
2569
            $cc_path = '/MASS_Dev_Bus/Product'     if ( $versions{$entry}{name} eq 'product');
2570
            $cc_path = '/MASS_Dev_Bus/Financial'   if ( $versions{$entry}{name} eq 'FinRun');
2571
 
2572
            $cc_path = '/MASS_Dev_Bus' if ( $cc_path =~ m~/MASS_Dev_Bus/ImageCapture(/|$)~i );
2573
            $cc_path = '/MASS_Dev_Bus' if ( $cc_path =~ m~/MASS_Dev_Bus/ImageCapture(/|$)~i );
2574
            $cc_path = '/MASS_Dev_Bus/CBP/enquiry' if ( $versions{$entry}{name} eq 'EJBEnqPxyConnector');
2575
            $cc_path = '/MASS_Dev_Bus/CBP/enquiry' if ( $versions{$entry}{name} eq 'proxyif4j');
2576
            $cc_path = '/MASS_Dev_Bus' if ( $versions{$entry}{name} eq 'ImageCaptureTomcatDeployment');
2577
            $cc_path = '/MASS_Dev_Bus/WebServices/MassWS' if ( $versions{$entry}{name} eq 'MassWebServicesImpl');
2578
 
2579
            if (   $versions{$entry}{name} =~ m/^ERGagency$/i
2580
                || $versions{$entry}{name} =~ m/^ERGavm$/i
2581
                || $versions{$entry}{name} =~ m/^ERGboi$/i
2582
                || $versions{$entry}{name} =~ m/^ERGcallcenter$/i
2583
                || $versions{$entry}{name} =~ m/^ERGcardholder$/i
2584
                || $versions{$entry}{name} =~ m/^ERGcdaimports$/i
2585
                || $versions{$entry}{name} =~ m/^ERGcda$/i
2586
                || $versions{$entry}{name} =~ m/^ERGcscedit$/i
2587
                || $versions{$entry}{name} =~ m/^ERGcs$/i
2588
                || $versions{$entry}{name} =~ m/^ERGofs$/i
2589
                || $versions{$entry}{name} =~ m/^ERGols$/i
2590
                || $versions{$entry}{name} =~ m/^ERGtpf$/i
2591
                || $versions{$entry}{name} =~ m/^ERGorasys$/i
2592
                || $versions{$entry}{name} =~ m/^ERGoracs$/i
2593
                || $versions{$entry}{name} =~ m/^ERGpxyif$/i
2594
                || $versions{$entry}{name} =~ m/^ERGtp5upg$/i
2595
                || $versions{$entry}{name} =~ m/^ERGinstitutional$/i
2596
                || $versions{$entry}{name} =~ m/^ERGinfra$/i
2597
                || $versions{$entry}{name} =~ m/^ERGcrrpts$/i
2598
                || $versions{$entry}{name} =~ m/^ERGmiddle$/i
2599
                || $versions{$entry}{name} =~ m/^ERGmiddleapi$/i
2600
                || $versions{$entry}{name} =~ m/^ERGwebapi$/i
2601
                || $versions{$entry}{name} =~ m/^ERGwebtestui$/i
2602
                || $versions{$entry}{name} =~ m/^ERGwebesbui$/i
2603
                || $versions{$entry}{name} =~ m/^ERGwspiv$/i
2604
                || $versions{$entry}{name} =~ m/^ERGwscst$/i
2605
                || $versions{$entry}{name} =~ m/^sposMUG$/i
2606
                || $versions{$entry}{name} =~ m/^ERGfinman$/i
2607
                || $versions{$entry}{name} =~ m/^ERGkm$/i
2608
                || $versions{$entry}{name} =~ m/^ERGxml$/i
2609
                || $versions{$entry}{name} =~ m/^ERGoradacw$/i
2610
                || $versions{$entry}{name} =~ m/^ERGtru$/i
2611
                )
2764 dpurdie 2612
            {
2613
                $cc_path = '/MREF_Package';
2614
            }
2615
 
3967 dpurdie 2616
            if (   $versions{$entry}{name} =~ m/^tp5000_MUG$/i )
2617
            {
2618
                if ( $versions{$entry}{version} =~ m~vtk$~ )
2619
                {
2620
                    $cc_path = '/MREF_Package';
2621
                }
2622
            }
2764 dpurdie 2623
 
3967 dpurdie 2624
            $cc_path = $opt_forceProjectBase
2625
                if ( $opt_forceProjectBase );
2626
 
2627
            foreach ( @opt_limitProjectBase )
2764 dpurdie 2628
            {
3967 dpurdie 2629
                if ( $cc_path =~ m~$_~ )
2630
                {
2631
                    $cc_path = $_;
2632
                    last;
2633
                }
2764 dpurdie 2634
            }
3967 dpurdie 2635
 
2636
            if ( $cc_path_original ne $cc_path )
2637
            {
2638
                    Message ("Package: $versions{$entry}{name}. Forcing CC path to: $cc_path" );
2639
            }
2764 dpurdie 2640
        }
3967 dpurdie 2641
 
2642
    #print "--- Path: $cc_path, Label: $cc_label\n";
2643
 
2644
        if ( $vcs_type eq 'SVN' )
2764 dpurdie 2645
        {
3967 dpurdie 2646
            $rv = extractFilesFromSubversion( $data, $entry );
2647
            return $rv if ( $rv );
2764 dpurdie 2648
        }
3967 dpurdie 2649
        else
2650
        {
2651
            #
2652
            #   Create CC view
2653
            #   Import into Subversion View
2654
            #
2655
            $rv = extractFilesFromClearCase( $data, $cc_path, $cc_label, $entry );
2656
            return $rv if ( $rv );
1197 dpurdie 2657
 
3967 dpurdie 2658
            #
2659
            #   May need to limit the extracted source tree
2660
            #   Use the first selected directory that we have
2661
            #
2662
            if ( @opt_selectProjectBase )
2663
            {
2664
                foreach ( @opt_selectProjectBase )
2665
                {
2666
                    my $testDir = join('/', $data->{ViewRoot}, $_);
2667
                    if ( -d $testDir )
2668
                    {
2669
                        $selectDir = $_;
2670
                        $data->{ViewPath} = $testDir;
2671
                        last;
2672
                    }
2673
                }
2674
 
2675
                unless ( $selectDir )
2676
                {
2677
                    Warning ("No directory selected from list");
2678
                }
2679
                else
2680
                {
2681
                    Message ("Selecting Dir: /$selectDir");
2682
                }
2683
            }
2684
        }
2764 dpurdie 2685
    }
1197 dpurdie 2686
 
2687
    #
2931 dpurdie 2688
    #   Delete specified files from the source tree
2689
    #
2690
    if ( @opt_deleteFiles )
2691
    {
2692
        my @args;
2693
        foreach my $delFileSpec ( @opt_deleteFiles )
2694
        {
2695
            Message ("Deleting files that match: $delFileSpec");
2696
            push @args, "--FilterIn=$delFileSpec";
2697
        }
2698
        my $search = JatsLocateFiles->new("--Recurse=1", @args );
2699
        my @rmFiles = $search->search($data->{ViewRoot});
2700
        foreach my $rmFile ( @rmFiles )
2701
        {
2702
            Information("Deleting: $rmFile");
2703
            unlink ( join ('/', $data->{ViewRoot}, $rmFile) )|| Warning "Cannot delete: $rmFile";
2704
        }
2705
    }
2706
 
2707
    #
3967 dpurdie 2708
    #   Some packages contain softlinks - that break the file scanner
2709
    #
2710
    if ( $opt_deleteLinks )
2711
    {
2712
        # Not doing anything yet - fixed the JATS find bit
2713
    }
2714
 
2715
    #
1272 dpurdie 2716
    #   Developers have been slack
2717
    #       Sometime the mark the source path as 'GMTPE2005'
2718
    #       Sometimes as 'GMTPE2005/Package/Fred/Jill/Harry'
2719
    #
2720
    #   Attempt to suck up empty directories below the specified
2721
    #   source path
2722
    #
3967 dpurdie 2723
    unless (($opt_preserveProjectBase || $opt_forceProjectBase || @opt_limitProjectBase || $selectDir) && ! $opt_forceSuck)
1272 dpurdie 2724
    {
2725
        #
2726
        #   Look in ViewPath
2727
        #   If it contains only ONE directory then we can suck it up
2728
        #
2729
        my $testDir = findDirWithStuff( $data->{ViewPath} );
1341 dpurdie 2730
 
1272 dpurdie 2731
        unless ( $data->{ViewPath} eq $testDir  )
2732
        {
2733
            Message ("Adjust Base Dir: $testDir");
2734
            $data->{adjustedPath} = $data->{ViewPath};
2735
            $data->{ViewPath} = $testDir;
2764 dpurdie 2736
            $adjustedPath++;
1272 dpurdie 2737
        }
2738
    }
2450 dpurdie 2739
    Message ("BaseDir: $data->{ViewPath}");
2764 dpurdie 2740
 
2429 dpurdie 2741
    #
2764 dpurdie 2742
    #   Check for bad source paths
2743
    #
2744
    if (detectBadMakePaths($data) )
2745
    {
3967 dpurdie 2746
        $count_BadPaths++;
2764 dpurdie 2747
        unless ( $opt_ignoreBadPaths )
2748
        {
2749
            $data->{BadPath}++;
2750
            $data->{errStr} = 'Bad Paths in Makefile';
2751
            return 4;           # Lets see what the others look like too
2752
#            return 14;
2753
        }
2754
    }
2755
 
2756
    #
2429 dpurdie 2757
    #   Some really ugly packages make use of a Jats feature called 'SetProjectBase'
2758
    #   Detect such packages as we will need to handle them differently
2759
    #   Can't really handle it on the fly
2760
    #   All we can do is detect it and report it - at the moment
2761
    #
2450 dpurdie 2762
    if (detectProjectBaseUsage($data) )
2429 dpurdie 2763
    {
2764
        unless ( $opt_ignoreProjectBaseErrors )
2765
        {
2766
            $data->{BadProjectBase}++;
2767
            $data->{errStr} = 'Bad usage of ProjectBase detected';
2764 dpurdie 2768
            Warning ("ProjectBase Error");
2429 dpurdie 2769
            return 4;           # Lets see what the others look like too
2770
#            return 14;
2771
        }
2772
    }
1272 dpurdie 2773
 
2774
    #
2429 dpurdie 2775
    #   Some really really ugly packgaes make use of the MakeProject directive
2776
    #   and then use an 'include.txt file to access paths all over the VOB
2777
    #   The problem is with lines like
2778
    #           /I ..\..\..\..\..\..\DPG_SWCode\projects\seattle\ddu\component\DTIApp\dsi\inc
2779
    #   Two problems:
2780
    #       Vob Name is not a part of the migration
2781
    #       If we 'SuckUp' empty directories then this may break
2782
    #       the pathing.
2783
    #   All we can do is detect it and report it - at the moment
2784
    #
2764 dpurdie 2785
    if (detectMakeProjectUsage($data) )
2429 dpurdie 2786
    {
2787
        unless ( $opt_ignoreMakeProjectErrors )
2788
        {
2789
            $data->{BadMakeProject}++;
2790
            $data->{errStr} = 'Use of MakeProject detected';
2791
            return 4;           # Lets see what the others look like too
2792
#            return 14;
2793
        }
2794
    }
2795
 
2796
    #
2797
    #   Some packages have filenames that are need to be converted
2798
    #
2799
    if ( $mustConvertFileNames  )
2800
    {
2801
        $rv = system ( '/home/dpurdie/svn/tools/convmv-1.15/convmv',
2802
                 '-fiso-8859-1',
2803
                 '-tutf8',
2804
                 '-r',
2805
                 '--notest',
2806
                 $data->{ViewPath} );
2807
 
2808
        if ( $rv )
2809
        {
2810
            $data->{errStr} = 'Failed to convert filenames to UTF8';
2811
            return 14;
2812
        }
2813
 
2814
        #
2815
        #   Check to see if our ViewPath has been changed
2816
        #   If so, then try to fix it
2817
        #
2818
        unless ( -d $data->{ViewPath} )
2819
        {
2820
            Message ("Correct UTF-8 change to ViewPath");
2821
            $data->{ViewPath} = encode('UTF-8', $data->{ViewPath}, Encode::FB_DEFAULT);
2822
            Warning ("Correct UTF-8 change to ViewPath - FAILED") unless ( -d $data->{ViewPath} );
2823
        }
2824
    }
2825
 
2826
    #
392 dpurdie 2827
    #   Have a CC view
2828
    #   Now we can create the SVN package and branching point before we
2829
    #   import the CC data into SVN
2830
    #
2450 dpurdie 2831
    if ( !$opt_useSvn )
2832
    {
2764 dpurdie 2833
            $data->{errStr} = 'Subversion Import disabled' unless $data->{errStr};
2450 dpurdie 2834
            return 5;
2835
    }
2836
 
392 dpurdie 2837
    my @args;
2838
 
2839
    #
2840
    #   Calculate args for functions
2841
    #
2842
    my $author = $versions{$entry}{created_id};
2843
    if ( $author )
2844
    {
2845
        push @args, '-author', $author;
2846
    }
2847
    my $created = $versions{$entry}{created};
2848
    if ( $created )
2849
    {
2850
        $created =~ s~ ~T~;
2851
        $created .= '00000Z';
2852
        push @args, '-date', $created;
2853
    }
2854
 
2855
    my $log = $versions{$entry}{comment};
2856
    if ( $log )
2857
    {
2858
        push @args, '-log', $log;
2859
    }
2860
 
2861
    #
2862
    #   Create package skeleton if needed
2863
    #
2864
    $rv = createPackage( $author, $created);
2865
    if ( $rv )
2866
    {
2867
        $data->{errStr} = 'Failed to create Package';
2868
        return 10;
2869
    }
2870
 
2871
    #
2872
    #   May need to create the branchpoint
2873
    #   The process is delayed until its needed so avoid creating unneeded
2874
    #   branch points
2875
    #
2876
    if ( $createBranch )
2877
    {
2878
        $rv = createBranchPoint ($entry, $author, $created);
2879
        $createBranch = 0;
2880
        $createSuffix = 0;
2881
        if ( $rv )
2882
        {
2883
            $data->{errStr} = 'Failed to create Branch Point';
2884
            return 11;
2885
        }
2886
    }
2764 dpurdie 2887
 
2888
    #
2889
    #   If we are in resume mode then we MUST kill the import directory
2890
    #   if we have skipped anything
2891
    #
2892
    if ( $forceImportFlush )
2893
    {
2894
        $forceImportFlush = 0;
2895
        RmDirTree ('SvnImportDir');
2896
    }
2897
 
392 dpurdie 2898
    push @args, "-branch=$currentBranchName" if ( defined $currentBranchName );
2764 dpurdie 2899
    my $datafile = "importdata.$import_label.properties";
392 dpurdie 2900
 
2931 dpurdie 2901
    my @mergeArg;
2902
    push (@mergeArg, "-mergePaths", join(',', @opt_mergePaths) ) if ( @opt_mergePaths );
2903
 
2904
    if ( exists $mergePathExtended{$packageNames}  )
2905
    {
2906
        my $eentry = $mergePathExtended{$packageNames};
2907
        if ( exists $eentry->{$import_label} )
2908
        {
2909
            @opt_mergePaths = split(':', $eentry->{$import_label});
2910
            Message("New MergePath Info: @opt_mergePaths");
2911
 
2912
            #
2913
            #   Args take effect next version
2914
            #   In this version have no merging - reset the image
2915
            #
2916
            @mergeArg = ();
2917
        }
2918
    }
2919
 
392 dpurdie 2920
    $rv = JatsToolPrint ( 'jats_svn', 'import', '-reuse' ,
2921
                    "-package=$svnRepo/$packageNames",
2922
                    "-dir=$data->{ViewPath}",
2923
                    "-label=$import_label",
2924
                    "-datafile=$datafile",
2925
                    @args,
2931 dpurdie 2926
                    @mergeArg,
392 dpurdie 2927
                     );
2928
 
2929
    if ( $rv )
2930
    {
2931
        $data->{errStr} = 'Failed to import to SVN';
2932
        return 12;
2933
    }
2934
 
3967 dpurdie 2935
    #
2936
    #   Some packages generate multiple packages
2937
    #   Some of these are the result of merging several packages
2938
    #   so we can only do this detection After the import
2939
    #
2940
    #   Detect potential build problems where multiple buildfiles
2941
    #   exists and cannot be resolved by our build system
2942
    #
2943
    #   This is not a show stopper (yet)
2944
    #
2945
    unless ( $opt_skipBuildNameCheck )
2946
    {
2947
        if (detectBuildFileClashes($data, 'SvnImportDir'))
2948
        {
2949
            unless ( $opt_ignoreBuildFileClashes )
2950
            {
2951
                $data->{BuildFileClash}++;
2952
                Message ("Build File Clash detected");
2953
            }
2954
        }
2955
    }
2956
    else
2957
    {
2958
        Message ('Detect Build File Clashes - skipped');
2959
    }
2960
 
392 dpurdie 2961
    $versions{$entry}{TagCreated} = 1;
2962
    $firstVersionCreated = $entry unless ( $firstVersionCreated );
2963
 
2964
    #
2965
    #   Read in the Rm Reference
2966
    #   Retain entries in a global file
2967
    #
2968
    if ( -f $datafile  )
2969
    {
2970
        my $rmData = JatsProperties::New($datafile);
2764 dpurdie 2971
        if ( $rmData->getProperty('subversion.tag') )
2972
        {
2973
            $data->{rmRef} = 'SVN::' . $rmData->getProperty('subversion.tag');
2974
        }
2975
        else
2976
        {
2977
            Warning ("Property files has no subversion.tag");
2978
        }
2979
        $data->{fileCount}    = $rmData->getProperty('files.base', 0);
2980
        $data->{filesRemoved} = $rmData->getProperty('files.removed',0);
2981
        $data->{filesAdded}   = $rmData->getProperty('files.added',0);
392 dpurdie 2982
    }
2983
 
2984
    unless ( $data->{rmRef}  )
2985
    {
1272 dpurdie 2986
        $data->{errStr} = 'Failed to determine Rm Reference';
392 dpurdie 2987
        return 13;
2988
    }
2989
 
2429 dpurdie 2990
######################## Deleted ###############################################
2991
#
2992
#
2993
#    #
2994
#    #   Add supplemental tags if this version is in a 'Release'
2995
#    #   But only for some packages - else looks like a mess
2996
#    #   Just a solution for the ITSO guys
2997
#    #
2998
#    foreach my $rtag_id ( keys %{$versions{$entry}{Releases}}  )
2999
#    {
3000
#        next unless ( $svnRepo =~ m~/ITSO_TRACS(/|$)~);
3001
#
3002
#        my $prog_id = $versions{$entry}{Releases}{$rtag_id}{proj_id};
3003
#        Message ("Adding Release Tag:$prog_id:$rtag_id");
3004
#
3005
#        my $rtext = 'Release_' . saneString($versions{$entry}{Releases}{$rtag_id}{rname});
3006
#        my @comment;
3007
#        push @comment, "Tagged by ClearCase to Subversion import";
3008
#        push @comment, "Project:$prog_id:$versions{$entry}{Releases}{$rtag_id}{pname}";
3009
#        push @comment, "Release:$rtag_id:$versions{$entry}{Releases}{$rtag_id}{rname}";
3010
#
3011
#        $data->{ReleaseTag}{$prog_id}{$rtag_id}{name} = $rtext;
3012
#
3013
#        $rv = JatsToolPrint ( 'jats_svnlabel' ,
3014
#                    '-comment', encode('UTF-8', join("\n", @comment), Encode::FB_DEFAULT),
3015
#                    $data->{rmRef},
3016
#                    '-clone',
3017
#                    $rtext,
3018
##                    @args,
3019
#                    '-author=buildadm',
3020
#                     );
3021
#        $data->{ReleaseTag}{$prog_id}{$rtag_id}{eState} = $rv;
3022
#        $data->{ReleaseTag}{tCount}++;
3023
#
3024
#        if ( $rv )
3025
#        {
3026
#            $data->{ReleaseTag}{eCount}++;
3027
#            Warning("Failed to add Release Tag: $rtext");
3028
#        }
3029
#    }
3030
#
3031
######################## Deleted ###############################################
1356 dpurdie 3032
 
392 dpurdie 3033
    Message ("RM Ref: $data->{rmRef}");
3034
    unlink $datafile;
3035
 
3036
    #
3037
    #   All is good
3038
    #
3039
    $data->{errStr} = '';
3040
    return 0;
3041
}
3042
 
3043
 
3044
#-------------------------------------------------------------------------------
3045
# Function        : newProject
3046
#
3047
# Description     : Start a new project within a package
3048
#
3049
# Inputs          : 
3050
#
3051
# Returns         : 
3052
#
3053
sub newProject
3054
{
3055
#    Message ("---- New Project");
3056
    $createSuffix = 0;
3057
 
3058
    #
3059
    #   New project
3060
    #   Kill the running import directory
3061
    #
3062
    RmDirTree ('SvnImportDir');
3063
}
3064
 
3065
#-------------------------------------------------------------------------------
3066
# Function        : newPackage
3067
#
3068
# Description     : Start processing a new package
3069
#
3070
# Inputs          : 
3071
#
3072
# Returns         : 
3073
#
3074
my $createPackageDone;
3075
sub newPackage
3076
{
3077
#    Message( "---- New Package");
3078
 
3079
    #
3080
    #   Create a package specific log file
3081
    #
3082
    $logSummary = $packageNames . ".summary.log";
3083
    unlink $logSummary;
3084
    Message( "PackageName: $packageNames");
3085
    $createPackageDone = 1;
3086
    $createBranch = 0;
3087
    $createSuffix = 0;
3088
 
3089
    #
3090
    #   First entry being created
3091
    #   Prime the work area
3092
    #
3093
    RmDirTree ('SvnImportDir');
3094
}
3095
 
3096
#-------------------------------------------------------------------------------
3097
# Function        : createPackage
3098
#
3099
# Description     : Create a new Package in SVN
3100
#                   Called before any serious SVN operation to ensure that the
3101
#                   package has been created. Don't create a package until
3102
#                   we expect to put something into it.
3103
#
3104
#                   Will only create a package once
3105
 
3106
#
3107
# Inputs          : $author         - Who done it
3108
#                   $date           - When
3109
#
3110
# Returns         : 
3111
#
3112
sub createPackage
3113
{
3114
    my ($author, $date) = @_;
3115
    my @opts;
3116
    push (@opts, '-date', $date) if ( $date );
3117
    push (@opts, '-author', $author) if ( $author );
3118
    #
3119
    #   Only do once
3120
    #
3121
    return unless ( $createPackageDone );
2764 dpurdie 3122
    return if ( $opt_resume );
392 dpurdie 3123
    $createPackageDone = 0;
3124
 
1270 dpurdie 3125
    #
3126
    #   Real import
3127
    #       Do not Delete package if it exists
3128
    #       Package must NOT exist
3129
    #
392 dpurdie 3130
    Message ("Creating new SVN package: $packageNames");
1270 dpurdie 3131
    if ( $opt_delete )
3132
    {
3133
        Message ("Delete existing version of package: $packageNames");
3134
        JatsToolPrint ( 'jats_svn', 'delete-package', '-noerror',  "$svnRepo/$packageNames" );
3135
    }
3136
    JatsToolPrint ( 'jats_svn', 'create', "$svnRepo/$packageNames", '-new', @opts );
392 dpurdie 3137
}
3138
 
3139
 
3140
#-------------------------------------------------------------------------------
3141
# Function        : createBranchPoint
3142
#
3143
# Description     : Create a branch point for the current work
3144
#                   Perform the calculation to determine the details of
3145
#                   the branch point. The work will only be done when its
3146
#                   needed. This will avoid the creation of branchpoints
3147
#                   that are not used.
3148
#
3967 dpurdie 3149
# Inputs          : $entry          - Entry being processed
392 dpurdie 3150
#                   $author         - Who done it
3151
#                   $date           - When
3152
#
3153
# Returns         : 
3154
#
3155
sub createBranchPoint
3156
{
3157
    my ($entry, $author, $date) = @_;
3158
    my $forceNewProject;
3159
 
3160
#    Message ("---- Create Branch Point");
3161
 
3162
    #
3163
    #   Find previous good tag
3164
    #   We are walking a tree so something should have been created, but
3165
    #   the one we want may have had an error
3166
    #
3167
    #   Walk backwards looking for one that has been created
3168
    #
3169
    my $last = $versions{$entry}{last};
3170
    while ( $last )
3171
    {
3172
        unless ( $versions{$last}{TagCreated} )
3173
        {
3174
            $last = $versions{$last}{last};
3175
        }
3176
        else
3177
        {
3178
            last;
3179
        }
3180
    }
3181
 
3182
    #
3183
    #   If we have walked back to the base of the tree
3184
    #   If we transferred any software at all, then use the first
3185
    #   version as the base for this disconnected version
3186
    #
3187
    #   Otherwise we create a new, and empty, view
3188
    #
3189
    unless ( $last )
3190
    {
3191
        if ( $firstVersionCreated )
3192
        {
3193
            Warning ("Cannot find previous version to branch. Use first version");
3194
            $last = $firstVersionCreated;
3195
        }
3196
        else
3197
        {
3198
            Warning ("Forcing First instance of a Project");
3199
            $forceNewProject = 1;
3200
        }
3201
    }
3202
 
3203
    #
3204
    #   Determine source name
3205
    #   This MUST have been created before we can branch
3206
    #
3207
    my $src_label;
3208
    $src_label = saneLabel($last) if $last;
3209
 
3210
    #
3211
    #   Create target name
3212
    #
3213
    my $tgt_label;
3967 dpurdie 3214
    if ($versions{$entry}{isaPatch} )
392 dpurdie 3215
    {
3967 dpurdie 3216
        my $parent = $versions{$entry}{last};
3217
        my $pver = $versions{$parent}{vname};
3218
        $tgt_label = 'Patching_' . $pver;
3219
    }
3220
    elsif ( $forceNewProject || $versions{$entry}{newSuffix} || $createSuffix || !defined $src_label )
3221
    {
392 dpurdie 3222
        #
3223
        #   Create target name based on project
3224
        #
3225
        return if ( $singleProject );
3226
 
3227
        my $suffix = $versions{$entry}{suffix};
3228
        if ( $suffix )
3229
        {
3230
            Error ("Unknown Project: $suffix") unless ( defined $Projects{$suffix} );
3231
 
3232
            #
3233
            #   If this project can be considered to be a truck, then 'claim' the
3234
            #   truck for the first created element.
3235
            #
3236
            if ( $Projects{$suffix}{Trunk} )
3237
            {
3238
                # This project can use the trunk, if it has not been allocated.
3239
                $ProjectTrunk = $suffix unless ( defined $ProjectTrunk );
3240
 
3241
                #
3242
                #   If this package has multiple instances of the potential
3243
                #   trunk, then don't place either of them on the trunk as it
3244
                #   may cause confusion
3245
                #
3246
                if ($knownProjects{$suffix}{count} < 2 )
3247
                {
3248
                    if ( $suffix eq $ProjectTrunk )
3249
                    {
3250
                        return unless $currentBranchName;
3251
                    }
3252
                }
3253
            }
3254
 
3255
            $tgt_label = $Projects{$suffix}{Name};
3256
            $tgt_label = $versions{$entry}{name} . '_' . $tgt_label if ($multiPackages);
3257
            if ( !exists $ProjectsBaseCreated{$tgt_label}  )
3258
            {
3259
                $ProjectsBaseCreated{$tgt_label} = 1;
3260
            }
3261
            else
3262
            {
3263
                #   Project Base Already taken
3264
                #   Have disjoint starting points
3265
                $tgt_label .= '.' . $ProjectsBaseCreated{$tgt_label} ++;
3266
            }
3267
        }
3268
        else
3269
        {
3270
            #
3271
            #   No suffix in use
3272
            #
3273
            #   Currently not handled
3274
            #   May have to force the use of the trunk
3275
            #
3276
            Error ("INTERNAL ERROR: No suffix present");
3277
        }
3278
    }
3279
    else
3280
    {
3281
        $tgt_label = saneLabel($entry, $src_label . '_for_');
3282
    }
3283
 
3284
    #
3285
    #   Save branch name for use when populating sandbox
3286
    #
3287
    $currentBranchName = $tgt_label;
3288
 
3289
    #
3290
    #   Perform the branch
3291
    #
3292
    if ( defined $src_label )
3293
    {
2764 dpurdie 3294
        if ( $opt_resume )
3295
        {
3296
            my $rv = JatsToolPrint ( 'jats_svnlabel',
3297
                        '-check',
3298
                        '-packagebase', "$svnRepo/$packageNames",
3299
                        '-branch',
3300
                        $tgt_label );
3301
            return unless ( $rv );
3302
        }
3303
 
1341 dpurdie 3304
        #
1356 dpurdie 3305
        #   The 'clone' operation will backtrack the branch point
3306
        #   to the source of the label. This will make the output version
3307
        #   tree much prettier
1341 dpurdie 3308
        #
392 dpurdie 3309
        my @opts;
3310
        push (@opts, '-date', $date) if ( $date );
3311
        push (@opts, '-author', $author) if ( $author );
3312
 
3313
        JatsToolPrint ( 'jats_svnlabel',
3314
                        '-packagebase', "$svnRepo/$packageNames",
1356 dpurdie 3315
                        'tags/' . $src_label,
392 dpurdie 3316
                        '-branch',
3317
                        '-clone', $tgt_label,
3318
                        @opts
3319
                      );
3320
    }
3321
}
3322
 
3323
 
3324
#-------------------------------------------------------------------------------
3325
# Function        : endPackage
3326
#
3327
# Description     : End of package processing
3328
#                   Clean up and display problems
3329
#
3330
# Inputs          : 
3331
#
3332
# Returns         : 
3333
#
3334
sub endPackage
3335
{
2429 dpurdie 3336
    Message ("-- Import Summary ------------------------------------------------" );
392 dpurdie 3337
    RmDirTree ('SvnImportDir');
2764 dpurdie 3338
    my $processedCount = 0;
3339
    my $inernalErrorCount = 0;
3340
    my $notProcessedCount = 0;
3341
    my $badPathCount = 0;
3342
    my $badProjectBaseCount = 0;
3343
    my $badMakeProjectCount = 0;
3967 dpurdie 3344
    my $buildFileClashes = 0;
392 dpurdie 3345
 
3346
    #
3347
    #   Display versions that did get captured
3348
    #
3349
    foreach my $entry ( @processOrder )
3350
    {
3351
        $versions{$entry}{Scanned} = 1;
3352
        next unless ( $versions{$entry}{TagCreated} );
2764 dpurdie 3353
        my $eflag = $versions{$entry}{Essential} ? 'E' : ' ';
3354
        Warning ("Processed:$eflag:" . GetVname($entry) . ' :: ' . $versions{$entry}{rmRef} || $versions{$entry}{errStr} || '???' );
392 dpurdie 3355
    }
3356
 
3357
    #
3358
    #   Display versions that did not get created
3359
    #
3360
    foreach my $entry ( @processOrder )
3361
    {
3362
        $versions{$entry}{Scanned} = 1;
2764 dpurdie 3363
        if ( $versions{$entry}{TagCreated} )
3364
        {
3365
            $processedCount++;
3366
            $badPathCount++ if ($versions{$entry}{data}{BadPath} );
3367
            $badProjectBaseCount++ if ($versions{$entry}{data}{BadProjectBase} );
3368
            $badMakeProjectCount++ if ($versions{$entry}{data}{BadMakeProject} );
3967 dpurdie 3369
            $buildFileClashes++ if ($versions{$entry}{data}{BuildFileClash} );
2764 dpurdie 3370
            next;
3371
        }
3372
 
2429 dpurdie 3373
        my $reason = $versions{$entry}{data}{errStr} || '';
3374
        my $tag = $versions{$entry}{vcsTag}|| 'No Tag';
2764 dpurdie 3375
        my $eflag = $versions{$entry}{Essential} ? 'E' : ' ';
3376
        Warning ("Not Processed:$eflag: " . GetVname($entry) . ':' . $tag . ' : ' . $reason );
3377
        $notProcessedCount++;
392 dpurdie 3378
    }
3379
 
3380
    foreach my $entry ( keys(%versions) )
3381
    {
3382
        next if ( $versions{$entry}{Scanned} );
3383
        Warning ("(E) INTERNAL ERROR. Package Not Processed: " . GetVname($entry) );
2764 dpurdie 3384
        $inernalErrorCount++;
392 dpurdie 3385
    }
3386
 
2764 dpurdie 3387
    if ( $adjustedPath || 1 )
3388
    {
3389
        Information ("Package Info: Files, Removed, Added, Version, ViewPath");
3390
        foreach my $entry ( @processOrder )
3391
        {
3392
            my $viewPath = $versions{$entry}{data}{ViewPath} || '';
3393
            Information (sprintf "%4s, %4s, %4s, %20s : %s",
3394
                        $versions{$entry}{data}{fileCount} || '-',
3395
                        $versions{$entry}{data}{filesRemoved} || '-',
3396
                        $versions{$entry}{data}{filesAdded} || '-',
3397
                        GetVname($entry), $viewPath);
3398
        }
3399
    }
3400
 
3401
    Message ("Packages processed: $processedCount");
3402
    Warning ("Packages not processed: $notProcessedCount") if ( $notProcessedCount );
3403
    Warning ("Internal Errors: $inernalErrorCount") if ( $inernalErrorCount );
3404
    Warning ("Multiple source paths", @multiplePaths ) if ( scalar @multiplePaths > 1 );
2429 dpurdie 3405
    Message ("Packages Relabled: $packageReLabelCount") if ( $packageReLabelCount );
2764 dpurdie 3406
    Warning ("Packages with Bad Paths: $badPathCount") if ( $badPathCount );
3967 dpurdie 3407
    Warning ("Packages with Ignored Bad Paths: $badPathCount") if ( $count_BadPaths );
3408
 
2764 dpurdie 3409
    Warning ("Packages with Bad ProjectBase: $badProjectBaseCount") if ( $badProjectBaseCount );
3410
    Warning ("Packages with MakeProjects: $badMakeProjectCount") if ( $badMakeProjectCount );
3967 dpurdie 3411
    Warning ("Build File Clashes Found: $buildFileClashes") if ( $buildFileClashes );
2764 dpurdie 3412
    Warning ("Global Error Detected") if ( $globalError );
3413
    Message ("---- All Done -----");
392 dpurdie 3414
}
3415
 
1197 dpurdie 3416
#-------------------------------------------------------------------------------
2429 dpurdie 3417
# Function        : extractFilesFromClearCase
3418
#
3419
# Description     : Extract files from ClearCase
3420
#                   May take a while as we handle nasty errors
3421
#
3422
# Inputs          : $data           - Hash of good stuff from newPackageVersionBody
3423
#                   $cc_path
3424
#                   $cc_label
3967 dpurdie 3425
#                   $entry          - original PV entry
2429 dpurdie 3426
#
3427
# Returns         : exit code
3428
#                   Sets up
3429
#                       $data->{errStr}
3430
#                       $data->{errCode}
3431
#                   As per newPackageVersionBody
3432
#
3433
sub extractFilesFromClearCase
3434
{
3967 dpurdie 3435
    my ($data, $cc_path, $cc_label, $entry) = @_;
2429 dpurdie 3436
    my $tryCount = 0;
3437
    my $rv = 99;
3438
 
2931 dpurdie 3439
    $data->{ViewRoot} = ( defined $opt_name && ! defined $opt_mergePackages )? $opt_name : "$cc_label";
2429 dpurdie 3440
    $data->{ViewPath} =  $data->{ViewRoot} . $cc_path;
3441
 
2764 dpurdie 3442
    if ( $opt_preserveProjectBase && !$opt_forceProjectBase )
2429 dpurdie 3443
    {
3444
        my $cc_vob = $cc_path;
3445
        $cc_vob =~ s~^/~~;
3446
        $cc_vob =~ s~/.*~~;
3447
        $data->{ViewPath} =  $data->{ViewRoot} . '/' . $cc_vob;
3448
        Message ("Preserving Project Base");
3449
    }
3450
    $data->{ViewPath} =~  tr~/~/~s;
3451
 
3967 dpurdie 3452
    #
3453
    #   Some versions are bad and have been manually marked as bad
3454
    #   Use touch cc2svn_ignore - to create file
3455
    #
3456
    if ( $opt_reuse && -f "$data->{ViewRoot}/cc2svn_ignore" )
3457
    {
3458
        Message ("View specifically ignored");
3459
        $data->{errStr} = 'View specifically ignored';
3460
        $data->{errCode} = '0';
3461
        return 4;               # Will Retain view
3462
    }
3463
 
3464
    #
3465
    #   Attempt to reuse compressed file
3466
    #
3467
    if ( $opt_reuse )
3468
    {
3469
        my $cfile = saneLabel($entry) . '.tgz';
3470
        if ( -f $cfile )
3471
        {
3472
            Message ("Restoring compressed image");
3473
            my $rv = System ('tar', '-xzf', $cfile );
3474
            if ( $rv )
3475
            {
3476
                Warning("Failed to decompress directory");
3477
                $data->{errStr} = 'Failed to de-tar compressed image';
3478
                return 2;
3479
            }
3480
            else
3481
            {
3482
                my $cc_vob = $cc_path;
3483
                $cc_vob =~ s~^/~~;
3484
                $cc_vob =~ s~/.*~~;
3485
                my $detarPath =  $data->{ViewRoot} . '/' . $cc_vob;
3486
 
3487
                Error ("Logic error: Did not de-tar into expected location", $detarPath)
3488
                    unless ( -d $detarPath  );
3489
 
3490
                if ( -d $data->{ViewPath}  )
3491
                {
3492
                    # All is good
3493
                    return 0;
3494
                }
3495
 
3496
                # Recalc ViewPath to the root of the VOB
3497
                $cc_path =~ s~^/~~;
3498
                $cc_path =~ s~/.*~~;
3499
                $cc_path = '/' . $cc_path;
3500
                $data->{ViewPath} =  $data->{ViewRoot} . $cc_path;
3501
 
3502
                return 0;
3503
            }
3504
        }
3505
    }
3506
 
2429 dpurdie 3507
    if ( $opt_reuse && -d $data->{ViewPath}  )
3508
    {
3509
        Message ("Reusing view: $cc_label");
3967 dpurdie 3510
 
3511
        #
3512
        #   Br applet kludge - can be removed later
3513
        #   Add some nice data to each view
3514
#        open (FH, '>' , $data->{ViewRoot} . '/cc2svn_tag' ) || Error ("Cannot open '$data->{ViewRoot}/cc2svn_tag'");
3515
#        print FH $versions{$entry}{name},' ',$versions{$entry}{vname},"\n";
3516
#        close FH;
2429 dpurdie 3517
        return 0;
3518
    }
3519
 
3520
    while ( $rv == 99 ) {
3521
        my @args;
2931 dpurdie 3522
        push (@args, '-view', $opt_name ) if ( defined $opt_name && ! defined $opt_mergePackages );
2429 dpurdie 3523
        $rv = JatsToolPrint ( 'jats_ccrelease', '-extractfiles', '-root=.' , '-noprefix',
3524
                    "-label=$cc_label" ,
3525
                    "-path=$cc_path",
3526
                    @args
3527
                    );
3528
 
3529
        if ( $rv == 10 ) {
3530
 
3531
            #
3532
            #   No files found
3533
            #   If this is the first time then try really hard to find them
3534
            #
3535
            unless ( $tryCount++ )
3536
            {
3537
                if ( $opt_relabel )
3538
                {
3539
                    $packageReLabelCount++;
3540
                    $rv = JatsToolPrint('cc2svn_labeldirs',
3541
                                            '-vob', $cc_path,
3542
                                            $cc_label,
3543
                                            );
3544
                    $data->{DirsLabled} = 100 + $rv;
3545
                }
3546
 
3547
                #
3548
                #   Second attempt - massage the users path
3549
                #   We should have labled up to the VOB root so lets
3550
                #   just use the VOB and not the path
3551
                #
3552
                #   If we are not relabeling then we can still do this
3553
                #   in an attempt to fix user stupidity
3554
                #
3555
                $cc_path =~ s~^/~~;
3556
                $cc_path =~ s~/.*~~;
3557
                $cc_path = '/' . $cc_path;
3558
                $data->{ViewPath} =  $data->{ViewRoot} . $cc_path;
3559
                redo;
3560
            }
3561
 
3562
            $data->{errStr}  = 'No Files in the extracted view';
3563
            $data->{errCode} = '0';
3564
            return 2;
3565
        }
3566
        elsif ( $rv == 11 ) {
3567
            $data->{errStr} = 'Label not found';
3568
            $data->{errCode} = 'L';
3569
            return 2;
3570
        }
3571
 
3572
        unless ( -d $data->{ViewPath}  )
3573
        {
3574
            $data->{errStr} = 'Failed to extract files from CC';
3575
            return 2;
3576
        }
3577
 
3578
        #
3579
        #   Looks good
3580
        #
3581
        return 0;
3582
    };
3583
 
3584
    $data->{errStr}  = 'No Files in the extracted view after labeling dirs';
3585
    $data->{errCode} = '0';
3586
    return 2;
3587
 
3588
}
3589
 
3590
#-------------------------------------------------------------------------------
2764 dpurdie 3591
# Function        : extractFilesFromSubversion
3592
#
3593
# Description     : Extract files from Subversion
3594
#                   May take a while as we handle nasty errors
3595
#
3596
# Inputs          : $data           - Hash of good stuff from newPackageVersionBody
3597
#                   $entry          - All the PV information
3598
#
3599
# Returns         : exit code
3600
#                   Sets up
3601
#                       $data->{errStr}
3602
#                       $data->{errCode}
3603
#                   As per newPackageVersionBody
3604
#
3605
sub extractFilesFromSubversion
3606
{
3607
    my ($data, $entry ) = @_;
3608
    my $tryCount = 0;
3609
    my $rv = 99;
3610
 
3611
    #
3612
    #   Create a nice name for the import
3613
    #
3614
    my $import_label = saneLabel($entry);
3615
 
3967 dpurdie 3616
    $data->{ViewRoot} = ( defined $opt_name && ! defined $opt_mergePackages )? $opt_name : $import_label;
2764 dpurdie 3617
    $data->{ViewPath} =  $data->{ViewRoot};
3618
    $data->{ViewPath} =~  tr~/~/~s;
3967 dpurdie 3619
 
2764 dpurdie 3620
    if ( $opt_reuse && -d $data->{ViewPath}  )
3621
    {
3967 dpurdie 3622
        #
3623
        #   Br applet kludge - can be removed later
3624
        #   Add some nice data to each view
3625
#        open (FH, '>' , $data->{ViewRoot} . '/cc2svn_tag' ) || Error ("Cannot open '$data->{ViewRoot}/cc2svn_tag'");
3626
#        print FH $versions{$entry}{name},' ',$versions{$entry}{vname},"\n";
3627
#        close FH;
3628
 
2764 dpurdie 3629
        Message ("Reusing view: $import_label");
3630
        return 0;
3631
    }
3632
 
3633
    #
3634
    #   Only allow import from SVN if asked nicely
3635
    #   May be used if we are correcting a package - and some have been
3636
    #   placed in SVN
3637
    #
3638
    unless ( $opt_extractFromSvn )
3639
    {
3640
        $data->{errStr} = 'Some Packages are in SVN';
3641
        return 15;
3642
    }
3643
 
3644
 
3645
#print "--- ViewRoot: $data->{ViewPath}\n";
3646
    $rv = JatsToolPrint ( 'jats_svnrelease',
3647
                          '-extractfiles',
3648
                          '-root=.' ,
3649
                          '-noprefix',
3650
                          '-DevMode=escrow',
3651
                          '-label', $data->{tag},
3652
                          '-view', $data->{ViewPath},
3653
                );
3654
 
3655
    if ( $rv == 10 ) {
3656
        $data->{errStr}  = 'No Files in the extracted view';
3657
        $data->{errCode} = '0';
3658
        return 2;
3659
 
3660
    } elsif ( $rv == 11 ) {
3661
        $data->{errStr} = 'Label not found';
3662
        $data->{errCode} = 'L';
3663
        return 2;
3664
    } elsif ( $rv ) {
3665
        $data->{errStr} = 'Subversion reported error';
3666
        return 2;
3667
    }
3668
 
3669
    unless ( -d $data->{ViewPath}  )
3670
    {
3671
        $data->{errStr} = 'Failed to extract files from Subversion';
3672
        return 2;
3673
    }
3674
 
3675
    #
3676
    #   Looks good
3677
    #
3678
    return 0;
3679
}
3680
 
3681
#-------------------------------------------------------------------------------
3967 dpurdie 3682
# Function        : extractFilesFromStore
3683
#
3684
# Description     : Extract files from Store
3685
#                   Locaal directory under dpkgExtract
3686
#
3687
# Inputs          : $data           - Hash of good stuff from newPackageVersionBody
3688
#                   $entry          - All the PV information
3689
#
3690
# Returns         : exit code
3691
#                       1 - Files found
3692
#                       0 - Not found
3693
#
3694
sub extractFilesFromStore
3695
{
3696
    my ($data, $entry ) = @_;
3697
    #
3698
    #   Create a nice name for the import
3699
    #
3700
    my $import_label = saneLabel($entry);
3701
 
3702
    $data->{ViewRoot} = ( defined $opt_name && ! defined $opt_mergePackages )? $opt_name : $import_label;
3703
    $data->{ViewPath} =  'dpkgExtract/' . $data->{ViewRoot};
3704
    $data->{ViewPath} =~  tr~/~/~s;
3705
 
3706
    if ( -d $data->{ViewPath}  )
3707
    {
3708
        $data->{fromStore} = 1;
3709
        Message ("Reusing Stored view: $import_label");
3710
        return 1;
3711
    }
3712
 
3713
    #
3714
    #   Not found in store
3715
    #
3716
    delete $data->{ViewRoot};
3717
    delete $data->{ViewPath};
3718
    return 0;
3719
}
3720
 
3721
#-------------------------------------------------------------------------------
3722
# Function        : testDpkgArchive
3723
#
3724
# Description     : Indicate if the package exists in dpkg_archive
3725
#
3726
# Inputs          : 
3727
#
3728
# Returns         : 
3729
#
3730
sub testDpkgArchive
3731
{
3732
    my ($entry) = @_;
3733
    my $vname = $versions{$entry}{vname};
3734
 
3735
    if ( -d join('/', $ENV{GBE_DPKG}, $packageNames, $vname )) {
3736
        Message ("Version found in dpkg_archive");
3737
    } else {
3738
        Message ("Version NOT found in dpkg_archive");
3739
    }
3740
}
3741
 
3742
#-------------------------------------------------------------------------------
3743
# Function        : markDpkgArchive
3744
#
3745
# Description     : Indicate if the package exists in dpkg_archive
3746
#
3747
# Inputs          : 
3748
#
3749
# Returns         : 
3750
#
3751
sub markDpkgArchive
3752
{
3753
    my ($entry) = @_;
3754
    my $vname = $versions{$entry}{vname};
3755
    my $path = join('/', $ENV{GBE_DPKG}, $packageNames, $vname );
3756
    delete $versions{$entry}{dpkgArchive};
3757
    if ( -d $path ) {
3758
        $versions{$entry}{dpkgArchive} = $path;
3759
    }
3760
}
3761
 
3762
#-------------------------------------------------------------------------------
2429 dpurdie 3763
# Function        : detectMakeProjectUsage
3764
#
3765
# Description     : etect and report usage of the MakeProject directive
3766
#
3767
# Inputs          : $data               - Ref to a hash of bits
3768
#
3769
# Returns         : true    - Bad usage (Really good usage not detected)
3770
#                   false   - Good usage detected
3771
#
3772
sub detectMakeProjectUsage
3773
{
2764 dpurdie 3774
    my ($data) = @_;
2429 dpurdie 3775
    my $retval = 0;
3776
    my $eSuf = $opt_ignoreMakeProjectErrors ? '' : 'Error';
3777
 
3778
    #
3779
    #   Find makefile.pl
3780
    #
2764 dpurdie 3781
    Message ("Detect MakeProject Usage");
2429 dpurdie 3782
    my $usesMakeProject = 0;
3783
    my $badIncludeFile = 0;
3784
 
3785
    my $search = JatsLocateFiles->new("--Recurse=1",
3786
                                       "--FilterIn=makefile.pl",
3787
                                       );
3788
    my @makefiles = $search->search($data->{ViewRoot});
3789
    foreach my $file ( @makefiles )
3790
    {
3791
#print "---Reading: $workDir/$data->{ViewRoot}/$file\n";
3792
        if ( open( my $fh, '<', "$data->{ViewRoot}/$file" ) )
3793
        {
3794
            my $eof = 0;
3795
            my $line = '';
3796
            until ( $eof )
3797
            {
3798
                my $in = <$fh>;
3799
                unless ( defined $in )
3800
                {
3801
                    $eof = 1;
3802
                }
3803
                else
3804
                {
3805
                $in =~ s~\s+$~~;
3806
                $in =~ s~^\s+~~;
3807
                $in =~ s~^#.*$~~;
3808
                $in =~ s~\s*[^\$]#.*$~~;
3809
                $line .= ' ' if ( $line );
3810
                $line .= $in;
3811
                $line =~ s~\s+~ ~g;
3812
#print "====== '$line'\n";
3813
                redo unless ( $line =~ m~;$~  );
3814
                }
3815
#print "---- $line\n";
3816
                if ( $line =~ m~^MakeProject~ )
3817
                {
3818
                    $usesMakeProject++;
3819
                    $data->{UsesMakeProject}++;
3820
                    Warning ("Package uses MakeProject:",
3821
                             "Line: " . $line,
3822
                             "Root: " . "$data->{ViewRoot}",
3823
                             "File: " . "$data->{ViewRoot}/$file",
3824
                            );
3825
 
3826
                    #
3827
                    #   Extract out the project name
3828
                    #
3829
                    my @myArgs;
3830
                    my $myProjectDir;
3831
                    my $myProject = "$data->{ViewRoot}/$file";
3832
                    $myProject =~ s~/[^/]+$~~;
2764 dpurdie 3833
 
3834
                    unless ($line =~ m~\s*(\w+)\s*\((.*)\)\s*;\s*$~ )
3835
                    {
3836
                        Error("Could not detect arguments: $line");
3837
                    }
3838
                    my $args = $2;
3839
                    $args =~ tr~'" ~ ~s;
3840
                    @myArgs = split (/\s*,\s*/, $args);
2429 dpurdie 3841
                    shift @myArgs;
3842
                    foreach ( @myArgs )
3843
                    {
3844
                        next if ( m~^--~ );
3845
                        $myProject .= '/' . $_;
3846
                        $myProjectDir = $myProject;
3847
                        $myProjectDir =~ s~/[^/]+$~~;
3848
                        last;
3849
                    }
3850
                    Error ("No project Found") unless ( defined $myProjectDir);
2764 dpurdie 3851
 
3852
                    #
3853
                    #   Look for 'include.txt' that may be bwteen the makefile and the project
3854
                    #
3855
 
3856
 
2429 dpurdie 3857
                    if ( -f "$myProjectDir/include.txt" )
3858
                    {
3859
                        Warning ("Co-located 'include.txt' file also found");
3860
                    }
3861
 
3862
                    # The only problem is if the include.txt file
3863
                    # escapes from the VOB - or even uses the vob root
3864
                    #
3865
                    # Examine the include file
3866
                    # Expect it to look like
3867
                    #   /I Path
3868
                    #
3869
 
3870
                    #
3871
                    #   Determine safe level
3872
                    #   Relative to the include file
3873
                    #
3874
                    my $depthPath = $myProjectDir;
3875
                    my $depth = 0;
3876
                    Error ("Expect this to work") unless ( $depthPath =~ s~^$data->{ViewRoot}/~~ );
3877
                    foreach ( split('/', $depthPath) )
3878
                    {
3879
                        if ( $_ eq '..' ) {
3880
                            $depth--;
3881
                        } else {
3882
                            $depth++;
3883
                        }
3884
                    }
3885
#print "Depth: $depth, $depthPath\n";
3886
 
3887
                    if ( open( my $if, '<', "$myProjectDir/include.txt" ) )
3888
                    {
3889
                        while ( <$if> )
3890
                        {
3891
                            s~\s+$~~;
3892
                            s~^\s+~~;
3893
                            next unless ( $_ );
3894
                            if ( m~/I\s+(.*)~ )
3895
                            {
3896
                                my $path = $1;
3897
                                $path =~ tr~\\/~/~s;
3898
                                $path =~ s~\\~/~g;
3899
#print "Examine: $path\n";
3900
                                my $minLevel = 0;
3901
                                my $level = 0;
3902
                                foreach ( split('/', $path) )
3903
                                {
3904
                                    if ( $_ eq '..' )
3905
                                    {
3906
                                        $level--;
3907
                                        $minLevel = $level if ($level < $minLevel);
3908
                                    }
3909
                                    else
3910
                                    {
3911
                                        $level++;
3912
                                    }
3913
                                }
3914
#print "Min: $minLevel, $level, ($depth + $minLevel)\n";
3915
                                if ( $depth + $minLevel <= 0)
3916
                                {
3917
                                    $badIncludeFile++;
3918
                                    Warning ("Included path escapes package:",
3919
                                             "Line: " . $_,
3920
                                             "File: " . "$myProjectDir/include.txt",
3921
                                            );
3922
                                    last;
3923
                                }
3924
                            }
3925
                        }
3926
                        close $if;
3927
                    }
3928
 
3929
                }
3930
                $line = '';
3931
            }
3932
            close $fh;
3933
        }
3934
        else
3935
        {
3936
            Warning ("MakeProject$eSuf - Cannot open makefile: $file");
3937
            $retval = 1;
3938
        }
3939
    }
3940
 
3941
    #
3942
    #   Used
3943
    #   May be improved latter
3944
    #
3945
    if ( $usesMakeProject && $badIncludeFile)
3946
    {
3947
        Warning ("MakeProject$eSuf - Problem detected");
3948
        $retval = 1;
3949
    }
3950
 
3951
    #
3952
    #   Until we have more faith in the detection algorithm
3953
    #
3954
    if ( $usesMakeProject )
3955
    {
3956
        Warning ("MakeProject$eSuf - Makeproject used. Must check manually");
3957
        $retval = 1;
3958
    }
3959
 
3960
    return $retval;
3961
}
3962
 
3963
#-------------------------------------------------------------------------------
2764 dpurdie 3964
# Function        : detectBadMakePaths
3965
#
3966
# Description     : Detect and report bad usage of some directives
3967
#
3968
# Inputs          : $data               - Ref to a hash of bits
3969
#
3970
# Returns         : true    - Bad usage (Really good usage not detected)
3971
#                   false   - Good usage detected
3972
#
3973
sub detectBadMakePaths
3974
{
3975
    my ($data) = @_;
3976
    my $retval = 0;
3977
    my $eSuf = $opt_ignoreBadPaths ? '' : 'Error';
3978
 
3979
    #
3980
    #   Find makefile.pl
3981
    #
3982
    Message ("Detect Bad Source Paths");
3983
    my $badPath = 0;
3984
 
3985
    my $search = JatsLocateFiles->new("--Recurse=1",
3986
                                       "--FilterIn=makefile.pl",
3987
                                       );
3988
    my @makefiles = $search->search($data->{ViewPath});
3989
    foreach my $file ( @makefiles )
3990
    {
3991
        $file =~ tr~/~/~s;
3992
        my $max_up = ($file =~ tr~/~/~);
3993
        my $shownPath;
3994
#print "---Reading: $workDir/$data->{ViewPath}/$file\n";
3995
        if ( open( my $fh, '<', "$data->{ViewPath}/$file" ) )
3996
        {
3997
            my $eof = 0;
3998
            my $line = '';
3999
 
4000
            until ( $eof )
4001
            {
4002
                my $in = <$fh>;
4003
                unless ( defined $in )
4004
                {
4005
                    $eof = 1;
4006
                }
4007
                else
4008
                {
4009
                $in =~ s~\s+$~~;
4010
                $in =~ s~^\s+~~;
4011
                $in =~ s~^#.*$~~;
4012
                $in =~ s~\s*[^\$]#.*$~~;
4013
                $line .= ' ' if ( $line );
4014
                $line .= $in;
4015
                $line =~ s~\s+~ ~g;
4016
#print "====== '$line'\n";
4017
                redo unless ( $line =~ m~;$~  );
4018
                }
4019
                if ( $line =~ m~^AddDir~ || $line =~ m~^AddSrcDir~ || $line =~ m~^AddIncDir~ || $line =~ m~^Src~ )
4020
                {
4021
                    #
4022
                    #   Extract out the arguments
4023
                    #
4024
                    my @myArgs;
4025
                    my $myProjectDir;
4026
                    my $myProject = "$data->{ViewRoot}/$file";
4027
                    $myProject =~ s~/[^/]+$~~;
4028
 
4029
                    unless ($line =~ m~\s*(\w+)\s*\((.*)\)\s*;\s*$~ )
4030
                    {
4031
                        Error("Could not detect arguments: $line");
4032
                    }
4033
                    my $args = $2;
4034
                    $args =~ tr~'" ~ ~s;
4035
                    @myArgs = split (/\s*,\s*/, $args);
4036
                    shift @myArgs;
4037
                    foreach ( @myArgs )
4038
                    {
4039
                        next if ( m~^--~ );
4040
                        next unless ( m~^\.\./~ );
4041
                        my $tmp = $_;
4042
                        $tmp =~ s~Z~z~g;
4043
                        $tmp =~ s~\.\./~Z~g;
4044
                        my $upCount = ( $tmp =~ tr~Z~Z~ );
4045
                        if ( $upCount > $max_up )
4046
                        {
4047
                            Warning ("Makefile Path: $file ") unless $shownPath;
4048
                            Warning ("Path escapes view: $max_up, $upCount, $_");
4049
                            $badPath++;
4050
                            $shownPath = 1;
4051
                        }
4052
#print "---x Path : $max_up, $upCount, $_\n";
4053
                    }
4054
                }
4055
                $line = '';
4056
            }
4057
            close $fh;
4058
        }
4059
        else
4060
        {
4061
            Warning ("detectBadMakePaths$eSuf - Cannot open makefile: $file");
4062
            $retval = 1;
4063
        }
4064
    }
4065
 
4066
    #
4067
    #   Used
4068
    #   May be improved latter
4069
    #
4070
    if ( $badPath )
4071
    {
4072
        Warning ("detectBadMakePaths$eSuf - Bad Path seen. Must check manually");
4073
        $retval = 1;
4074
    }
4075
 
4076
    return $retval;
4077
}
4078
 
4079
 
4080
#-------------------------------------------------------------------------------
1197 dpurdie 4081
# Function        : detectProjectBaseUsage
4082
#
4083
# Description     : Detect and report usage of the SetProjectBase directive
4084
#
4085
# Inputs          : $data               - Ref to a hash of bits
4086
#
4087
# Returns         : true    - Bad usage (Really good usage not detected)
4088
#                   false   - Good usage detected
4089
#
4090
sub detectProjectBaseUsage
4091
{
2450 dpurdie 4092
    my ($data) = @_;
1197 dpurdie 4093
    my $retval = 0;
4094
    my $eSuf = $opt_ignoreProjectBaseErrors ? '' : 'Error';
4095
 
4096
    #
4097
    #   Find makefile.pl
4098
    #
2764 dpurdie 4099
    Message ("Detect ProjectBase Usage");
1197 dpurdie 4100
    my $usesProjectBase = 0;
4101
    my $definesProjectBase = 0;
4102
    my $definitionError = 0;
4103
 
4104
    my $search = JatsLocateFiles->new("--Recurse=1",
4105
                                       "--FilterIn=makefile.pl",
4106
                                       );
2450 dpurdie 4107
    my @makefiles = $search->search($data->{ViewPath});
1197 dpurdie 4108
    foreach my $file ( @makefiles )
4109
    {
2450 dpurdie 4110
        if ( open( my $fh, '<', "$data->{ViewPath}/$file" ) )
1197 dpurdie 4111
        {
4112
            while ( <$fh> )
4113
            {
4114
                s~\s+$~~;
4115
                s~^\s+~~;
4116
                next if ( m~^#~ );
4117
 
4118
                if ( m~\$ProjectBase~ )
4119
                {
4120
                    $usesProjectBase++;
4121
                    Message ("Project Base Use: $_");
4122
                    $data->{UsesProjectBase}++;
4123
                }
4124
 
4125
                if ( m~^SetProjectBase~ )
4126
                {
4127
                    $definesProjectBase++;
4128
                    $data->{DefinesProjectBase}++;
2429 dpurdie 4129
                    Warning ("Package initialises SetProjectBase:",
2450 dpurdie 4130
                             "Line : " . $_,
4131
                             "Root : " . "$data->{ViewRoot}",
4132
                             "Path : " . "$data->{ViewPath}",
4133
                             "File : " . "$data->{ViewPath}/$file",
1197 dpurdie 4134
                            );
4135
 
4136
                    # The only problem is if the user attempts to escape
4137
                    # from the root of the view.
4138
                    #
4139
                    # Examine the depth of the makefile with the directive
4140
                    # Examine the depth of the view base
4141
                    #
4142
                    #
4143
                    # Locate the build.pl file
4144
                    # This is the basis for for the directive
4145
                    #
4146
                    my $blevel;
4147
                    my @bpaths = split ('/', $file );
2450 dpurdie 4148
                    my $buildFile;
1197 dpurdie 4149
                    while ( @bpaths )
4150
                    {
4151
                        $bpaths[-1] = 'build.pl';
4152
                        my $bfile = join '/', @bpaths ;
2450 dpurdie 4153
                        $buildFile = "$data->{ViewPath}/$bfile";
4154
                        if ( -f $buildFile )
1197 dpurdie 4155
                        {
4156
                            $blevel = scalar @bpaths;
4157
                            last;
4158
                        }
4159
                        pop @bpaths;
4160
                    }
4161
                    unless (defined $blevel)
4162
                    {
4163
                        Warning ("SetProjectBase$eSuf calculation failed - can't find build.pl");
2429 dpurdie 4164
#                        $retval = 1;
4165
                         $definitionError++;
1197 dpurdie 4166
                    }
4167
                    else
4168
                    {
3967 dpurdie 4169
                        Warning ("Build: $buildFile");
1197 dpurdie 4170
                        #
3967 dpurdie 4171
                        #   Whats the file for
4172
                        #
4173
                        if (open (BF, '<', $buildFile ))
4174
                        {
4175
                            while ( <BF> )
4176
                            {
4177
                                s~\s+$~~;
4178
                                if ( m~\s*BuildName~ )
4179
                                {
4180
                                    Warning ("BuildName: $_");
4181
                                    last;
4182
                                }
4183
                            }
4184
                            close BF;
4185
                        }
4186
 
4187
 
4188
                        #
1197 dpurdie 4189
                        #   Determine the depth of the view root
4190
                        #
2450 dpurdie 4191
                        my $countPath = ($data->{ViewPath} =~ tr~/~/~);
4192
                        my $countBuild = ($buildFile =~ tr~/~/~);
4193
                        my $max_up = $countBuild - $countPath -1;
1197 dpurdie 4194
 
4195
                        m~--Up=(\d+)~i;
4196
                        my $ulevel = $1;
4197
                        if ( defined $ulevel )
4198
                        {
4199
                            my @paths = split ('/', $file );
4200
                            my $plevel = scalar @paths;
4201
 
4202
#print "--- blevel: $blevel\n";
4203
#print "--- bpaths: @bpaths\n";
4204
#print "--- ulevel: $ulevel\n";
4205
#print "--- paths: @paths\n";
4206
#print "--- plevel: $plevel\n";
4207
#print "--- max_up: $max_up\n";
4208
 
4209
                            if ( $ulevel > $max_up )
4210
                            {
4211
                                Warning ("SetProjectBase escapes view. MaxUp: $max_up, Up: $ulevel");
4212
                                $definitionError++;
4213
                            }
4214
                        }
4215
                        else
4216
                        {
4217
                            $retval = 1;
4218
                            Warning ("SetProjectBase$eSuf MAY escape view - can't detect level")
4219
                        }
4220
                    }
4221
                }
4222
            }
4223
            close $fh;
4224
        }
4225
        else
4226
        {
4227
            Warning ("SetProjectBase$eSuf - Cannot open makefile: $file");
4228
            $retval = 1;
4229
        }
4230
    }
4231
 
4232
    #
4233
    #   Detect defined, but not used
4234
    #
4235
    if ( $usesProjectBase && ! $definesProjectBase )
4236
    {
3967 dpurdie 4237
        Warning ("SetProjectBase - Uses Default ProjectBase");
1197 dpurdie 4238
    }
4239
 
4240
    if ( ! $usesProjectBase && $definesProjectBase )
4241
    {
4242
        Warning ("SetProjectBase - Defines ProjectBase without using it");
4243
    }
4244
 
4245
    if ( $usesProjectBase && $definesProjectBase && $definitionError )
4246
    {
4247
        Warning ("SetProjectBase$eSuf - Problem detected");
4248
        $retval = 1;
4249
    }
4250
    return $retval;
4251
}
4252
 
1272 dpurdie 4253
#-------------------------------------------------------------------------------
3967 dpurdie 4254
# Function        : detectBuildFileClashes
4255
#
4256
# Description     : Scan a directory for multiple buildfiles and conflicts
4257
#                   Only works for Jats build.pl files - at the moment
4258
#
4259
# Inputs          : $data       - PackageVersion Data
4260
#                   $rootDir    - Directory to scan
4261
#
4262
# Returns         : 0                   - All is well
4263
#                   !0                  - Multiple build files found
4264
#
4265
sub detectBuildFileClashes
4266
{
4267
    my ($pvdata, $rootDir) = @_;
4268
    my %data;
4269
    my $rv = 0;
4270
Message ('Detect Build File Clashes');
4271
 
4272
    my $bscanner = BuildFileScanner ( $rootDir, 'build.pl' );
4273
    my $count = $bscanner->locate();
4274
 
4275
    #
4276
    #   None found - OK ( but not good )
4277
    #
4278
    return $rv unless ( $count );
4279
 
4280
    #
4281
    #   Process all the build files in the tree
4282
    #
4283
    $bscanner->scan();
4284
    my @buildfiles = $bscanner->getMatchList();
4285
#   DebugDumpData('$bscanner', $bscanner );
4286
#   DebugDumpData('@buildfiles', \@buildfiles );
4287
#   exit 99;
4288
 
4289
    foreach my $bf ( @buildfiles )
4290
    {
4291
        my $bdir = $bf->{dir};
4292
        my $bname = $bf->{name};
4293
        my $bversion = $bf->{version};
4294
        next unless ( defined($bname) );
4295
Information ("BuildFiles: $bname, $bversion : $bdir");
4296
 
4297
        if ( exists ($data{$bname}{count}) && ($data{$bname}{count} >= 1) )
4298
        {
4299
            Warning ("MultipleBuildFiles for $bname ($bversion)");
4300
            $rv = 1;
4301
        }
4302
        $data{$bname}{count}++;
4303
        push @{$data{$bname}{versions}}, $bversion;
4304
    }
4305
 
4306
    return $rv;
4307
}
4308
 
4309
#-------------------------------------------------------------------------------
1272 dpurdie 4310
# Function        : findDirWithStuff
4311
#
4312
# Description     : Find a directory that contains more than just another subdir
2429 dpurdie 4313
#                   Note: don't use 'glob' it doesn't work if the name has a space in it.
1272 dpurdie 4314
#
4315
# Inputs          : $base               - Start of the scan
4316
#
4317
# Returns         : Path to dir with more than just a single dir in it
4318
#
4319
sub findDirWithStuff
4320
{
4321
    my ($base) = @_;
1197 dpurdie 4322
 
1272 dpurdie 4323
    while ( $base )
4324
    {
4325
    my $fileCount = 0;
4326
    my $dirCount = 0;
1341 dpurdie 4327
    my $firstDir;
1272 dpurdie 4328
 
2429 dpurdie 4329
    opendir (my $dh, $base ) || Error ("Cannot opendir $base. $!");
4330
    my @list =readdir $dh;
4331
    closedir $dh;
1272 dpurdie 4332
    foreach ( @list )
4333
    {
4334
        next if ( $_ eq '.' );
4335
        next if ( $_ eq '..' );
2429 dpurdie 4336
 
4337
        $_ = $base . '/' . $_;
1272 dpurdie 4338
        if ( -d $_ )
4339
        {
4340
            $dirCount++;
1341 dpurdie 4341
            $firstDir = $_ unless ( defined $firstDir );
2429 dpurdie 4342
            return $base
4343
                if ( $dirCount > 1  )
1272 dpurdie 4344
        }
1341 dpurdie 4345
        elsif ( -e $_ )
1272 dpurdie 4346
        {
4347
            return $base;
4348
        }
1341 dpurdie 4349
 
4350
        # else its probably a dead symlink
1272 dpurdie 4351
    }
2429 dpurdie 4352
 
4353
    return $base
4354
        unless ( $dirCount == 1  );
1341 dpurdie 4355
    $base = $firstDir;
1272 dpurdie 4356
    }
4357
}
4358
 
1197 dpurdie 4359
#-------------------------------------------------------------------------------
4360
# Function        : JatsToolPrint
4361
#
4362
# Description     : Print and Execuate a JatsTool command
4363
#
4364
# Inputs          : 
4365
#
4366
# Returns         : 
4367
#
4368
 
392 dpurdie 4369
sub JatsToolPrint
4370
{
4371
    Information ("Command: @_");
4372
    JatsTool @_;
4373
}
4374
 
4375
sub GetVname
4376
{
4377
    my ($entry) = @_;
4378
    my $me = 'NONE';
4379
    if ( $entry )
4380
        {
4381
        $me = $versions{$entry}{vname};
4382
        unless ( $me )
4383
        {
4384
            $me = 'Unknown-' . $entry;
4385
        }
4386
    }
4387
    return $me;
4388
}
4389
 
2429 dpurdie 4390
#-------------------------------------------------------------------------------
4391
# Function        : saneLabel
4392
#
4393
# Description     : Generate a sane version label
3967 dpurdie 4394
#                   Handle duplicates (due to character squishing)
2429 dpurdie 4395
#                   Cache results for repeatability
4396
#
4397
# Inputs          : $entry          - Version info
4398
#                   $pkgname        - Alternate pkgname (branching)
4399
#
4400
# Returns         : Sane string
4401
#
392 dpurdie 4402
sub saneLabel
4403
{
4404
    my ($entry, $pkgname) = @_;
1272 dpurdie 4405
    my $me;
4406
    $me = $versions{$entry}{vname};
392 dpurdie 4407
    $pkgname = $versions{$entry}{name} unless ( defined $pkgname );
4408
 
2429 dpurdie 4409
    #
4410
    #   If we have calculated it, then reuse it.
4411
    #
4412
    if ( exists $versions{$entry}{saneLabel}{$pkgname} )
4413
    {
4414
        return $versions{$entry}{saneLabel}{$pkgname};
4415
    }
4416
 
4417
 
392 dpurdie 4418
    Error ("Package does have a version string: pvid: $entry")
4419
        unless ( defined $me );
4420
 
4421
    #
4422
    #   Convert Wip format (xxxx) into a string that can be used for a label
4423
    #
4424
    if ( $me =~ m~^(.*)\((.*)\)(.*)$~ )
4425
    {
4426
        $me = $1 . '_' . $2 . '_' . $3 . '.WIP';
4427
        $me =~ s~_\.~.~;
4428
        $me =~ s~^_~~;
4429
    }
4430
 
4431
    #
4432
    #   Allow for WIPS
4433
    #   Get rid of multiple '_'
4434
    #   Replace space with -
4435
    #
4436
    $me = $pkgname . '_' . $me;
4437
    $me =~ tr~ ~-~s;
4438
    $me =~ tr~-~-~s;
4439
    $me =~ tr~_~_~s;
4440
 
2429 dpurdie 4441
    #
4442
    #   Due to some sillyness ( package version starting with _ )
4443
    #   we may get duplicates. Detect and allocate different numbers
4444
    #
4445
    if ( exists $saneLabels{$me} )
4446
    {
4447
        $saneLabels{$me}++;
4448
        $me = $me . '.' . $saneLabels{$me};
4449
        Message ("Duplicate SaneLabel resolved as: $me");
4450
    }
4451
    else
4452
    {
4453
        $saneLabels{$me} = 0;
4454
    }
4455
 
4456
    #
4457
    #   Cache value
4458
    #
4459
    $versions{$entry}{saneLabel}{$pkgname} = $me;
392 dpurdie 4460
    return $me;
4461
}
4462
 
1356 dpurdie 4463
sub saneString
4464
{
4465
    my ($string) = @_;
4466
    #
4467
    #   Get rid of multiple '_'
4468
    #   Replace space with -
4469
    #
4470
    $string =~ s~\W~_~g;
4471
    $string =~ tr~ ~_~s;
4472
    $string =~ tr~_-~-~s;
4473
    $string =~ tr~-_~-~s;
4474
    $string =~ tr~-~-~s;
4475
    $string =~ tr~_~_~s;
4476
    $string =~ s~-$~~;
4477
    $string =~ s~_$~~;
392 dpurdie 4478
 
1356 dpurdie 4479
    return $string;
4480
}
4481
 
4482
 
392 dpurdie 4483
exit 0;
4484
 
4485
 
4486
#-------------------------------------------------------------------------------
4487
# Function        : GetPkgIdByName
4488
#
4489
# Description     :
4490
#
4491
# Inputs          : pkg_name
4492
#
4493
# Returns         : pkg_id
4494
#
4495
sub GetPkgIdByName
4496
{
4497
    my ( $pkg_name ) = @_;
4498
    my (@row);
4499
    my $pv_id;
4500
    my $pkg_id;
4501
 
4502
    #
4503
    #   Establish a connection to Release Manager
4504
    #
4505
    connectRM(\$RM_DB) unless ( $RM_DB );
4506
 
4507
    #
4508
    #   Extract data from Release Manager
4509
    #
4510
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pkg.PKG_ID" .
4511
                   " FROM RELEASE_MANAGER.PACKAGES pkg" .
4512
                   " WHERE pkg.PKG_NAME = \'$pkg_name\'";
4513
 
4514
    my $sth = $RM_DB->prepare($m_sqlstr);
4515
    if ( defined($sth) )
4516
    {
4517
        if ( $sth->execute( ) )
4518
        {
4519
            if ( $sth->rows )
4520
            {
4521
                while ( @row = $sth->fetchrow_array )
4522
                {
4523
                    Verbose( "DATA: " . join(',', @row) );
4524
                    $pkg_id = $row[1] || 0;
4525
                    last;
4526
                }
4527
            }
4528
            else
4529
            {
4530
                Error ("GetPkgIdByName:No Data for package: $pkg_name");
4531
            }
4532
            $sth->finish();
4533
        }
4534
    }
4535
    else
4536
    {
4537
        Error("GetPkgIdByName:Prepare failure" );
4538
    }
4539
 
4540
    return $pkg_id;
4541
}
4542
 
4543
#-------------------------------------------------------------------------------
4544
# Function        : GetData_by_pkg_id
4545
#
4546
# Description     :
4547
#
4548
# Inputs          : pv_id
4549
#
4550
# Returns         :
4551
#
4552
sub GetData_by_pkg_id
4553
{
4554
    my ( $pkg_id, $packageName ) = @_;
4555
    my (@row);
4556
 
4557
    #
4558
    #   Establish a connection to Release Manager
4559
    #
4560
    Message ("Extract package versions from Release Manager: $packageName");
4561
    connectRM(\$RM_DB) unless ( $RM_DB );
4562
 
4563
    #
4564
    #   Extract data from Release Manager
4565
    #
2429 dpurdie 4566
    my $m_sqlstr = "SELECT " .
4567
                       "pkg.PKG_NAME, " .                                       # row[0]
4568
                       "pv.PKG_VERSION, " .                                     # row[1]
4569
                       "pkg.PKG_ID, " .                                         # row[2]
4570
                       "pv.PV_ID, " .                                           # row[3]
4571
                       "pv.LAST_PV_ID, " .                                      # row[4]
4572
                       "pv.MODIFIED_STAMP, " .                                  # row[5]
4573
                       "release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID), " .  # row[6]
4574
                       "amu.USER_NAME, " .                                      # row[7]
4575
                       "pv.COMMENTS, " .                                        # row[8]
4576
                       "pv.DLOCKED, " .                                         # row[9]
4577
                       "pv.CREATOR_ID, ".                                       # row[10]
4578
                       "pv.BUILD_TYPE ".                                        # row[11]
4579
                   " FROM " .
4580
                        "RELEASE_MANAGER.PACKAGES pkg, " .
4581
                        "RELEASE_MANAGER.PACKAGE_VERSIONS pv, " .
4582
                        "ACCESS_MANAGER.USERS amu" .
4583
                   " WHERE " .
4584
                        "pv.PKG_ID = \'$pkg_id\' " .
4585
                        "AND pkg.PKG_ID = pv.PKG_ID " .
4586
                        "AND amu.USER_ID (+) = pv.CREATOR_ID";
4587
 
392 dpurdie 4588
    my $sth = $RM_DB->prepare($m_sqlstr);
4589
    if ( defined($sth) )
4590
    {
4591
        if ( $sth->execute( ) )
4592
        {
4593
            if ( $sth->rows )
4594
            {
4595
                while ( @row = $sth->fetchrow_array )
4596
                {
4597
                    Verbose( "DATA: " . join(',', @row) );
4598
                    my $pkg_name = $row[0] || 'Unknown';
4599
                    my $pkg_ver = $row[1] || 'Unknown';
4600
                       $pkg_ver =~ s~\s+$~~;
4601
                       $pkg_ver =~ s~^\s+~~;
4602
                    my $pv_id = $row[3] || 'Unknown';
4603
                    my $last_pv_id = $row[4];
4604
                    my $created =  $row[5] || 'Unknown';
4605
                    my $vcstag =  $row[6] || 'Unknown';
394 dpurdie 4606
 
392 dpurdie 4607
                    my $created_id =  $row[7] || ($row[10] ? "Userid_$row[10]" :'Unknown');
4608
                    my $comment =  $row[8] || '';
4609
                    my $locked =  $row[9] || 'N';
2429 dpurdie 4610
                    my $manual = $row[11] || 'M';
392 dpurdie 4611
 
4612
                    #
4613
                    #   Some developers have a 'special' package version
4614
                    #   We really need to ignore them
4615
                    #
4616
                    next if ( $pkg_ver eq '23.23.23.ssw' );
2931 dpurdie 4617
 
392 dpurdie 4618
                    #
4619
                    #   Add data to the hash
4620
                    #
4621
                    $versions{$pv_id}{name} = $pkg_name;
4622
                    $versions{$pv_id}{pvid} = $pv_id;
4623
                    $versions{$pv_id}{vname} = $pkg_ver;
4624
                    $versions{$pv_id}{vcsTag} = $vcstag;
4625
                    $versions{$pv_id}{created} = $created;
4626
                    $versions{$pv_id}{created_id} = $created_id;
4627
                    $versions{$pv_id}{comment} = $comment;
4628
                    $versions{$pv_id}{locked} = $locked;
4629
                    $versions{$pv_id}{TimeStamp} = str2time( $created );
4630
                    $versions{$pv_id}{Age} = ($now - $versions{$pv_id}{TimeStamp}) / (60 * 60 * 24);
4631
                    $versions{$pv_id}{TooOld} = 1 if ( $opt_age && $opt_age <= $versions{$pv_id}{Age} );
2429 dpurdie 4632
                    $versions{$pv_id}{BuildType} = $manual;
392 dpurdie 4633
                    examineVcsTag($pv_id);
4634
 
4635
                    #
4636
                    #   Process version number
4637
                    #
3967 dpurdie 4638
                    my ($suffix, $version, $isaR, $isaWip, $buildVersion, $isaPatch ) = massageVersion($pkg_ver, $pkg_name);
392 dpurdie 4639
 
4640
                    $versions{$pv_id}{version} = $version;
4641
                    $versions{$pv_id}{buildVersion} = $buildVersion;
4642
                    $versions{$pv_id}{isaWip} = 1 if ( $isaWip );
3967 dpurdie 4643
                    $versions{$pv_id}{isaPatch} = 1 if ( $isaPatch );
392 dpurdie 4644
 
3967 dpurdie 4645
                    # Remove entries that address themselves
4646
                    push (@{$versions{$last_pv_id}{next}}, $pv_id) unless ($pv_id == $last_pv_id || $last_pv_id == 0 || $isaPatch) ;
4647
 
4648
 
392 dpurdie 4649
                    #
2931 dpurdie 4650
                    #   New method for detecting a ripple
2429 dpurdie 4651
                    #       Don't look at the version number
4652
                    #       Use RM data
4653
                    #       Inlude the comment - there are some cases where the comment
4654
                    #       appears to have been user modified.
4655
                    #
4656
#                    $versions{$pv_id}{isaRipple} = 1 if ( $isaR );
4657
#                    $versions{$pv_id}{isaRipple} = 1 if ( uc($manual) eq 'Y' );
4658
                    $versions{$pv_id}{isaRipple} = ( $comment =~ m~^Rippled Build~i && ( uc($manual) eq 'Y' ));
4659
 
4660
                    #
392 dpurdie 4661
                    #   Process suffix
4662
                    #
4663
                    $suffix = 'Unknown' unless ( $suffix );
4664
                    $suffix = lc ($suffix);
4665
                    $versions{$pv_id}{suffix} = $suffix;
4666
                    push @{$suffixes{$suffix}}, $pv_id;
4667
 
4668
#                    print "$pkg_name, $pkg_ver, $pv_id, $last_pv_id, $locked, $created, $created_id, $suffix\n";
4669
                }
4670
            }
4671
            else
4672
            {
4673
                Error ("GetData_by_pkg_id: No Data: $m_sqlstr");
4674
            }
4675
            $sth->finish();
4676
        }
4677
        else
4678
        {
4679
                Error ("GetData_by_pkg_id: Execute: $m_sqlstr");
4680
        }
4681
    }
4682
    else
4683
    {
4684
        Error("GetData_by_pkg_id:Prepare failure" );
4685
    }
4686
}
4687
 
4688
#-------------------------------------------------------------------------------
4689
# Function        : massageVersion
4690
#
4691
# Description     : Process a version number and return usful bits
4692
#
4693
# Inputs          : Version Number
4694
#                   Package Name - debug only
4695
#
4696
# Returns         : An array
4697
#                       suffix
4698
#                       multipart version string useful for text comparisons
4699
#
4700
sub massageVersion
4701
{
4702
    my ($version, $name) = @_;
4703
    my ($major, $minor, $patch, $build, $suffix);
4704
    my $result;
4705
    my $buildVersion;
4706
    my $isaRipple;
4707
    my $isaWIP;
3967 dpurdie 4708
    my $isaPatch;
392 dpurdie 4709
    $build = 0;
4710
 
4711
#print "--- $name, $version\n";
4712
    $version =~ s~^_~~;
4713
    $version =~ s~^${name}_~~;
4714
 
4715
    #
4716
    #   xxxxxxxxx.nnnn.cots
4717
    #
4718
    if ( $version =~ m~(.*)\.cots$~ ) {
4719
        my $cots_base = $1;
4720
        $suffix = '.cots';
3967 dpurdie 4721
        if ( $version =~ m~(.*?)\.([0-9]{4,5})\.cots$~ )
392 dpurdie 4722
        {
4723
            $result = $1 . sprintf (".%4.4d", $2) . $suffix;
4724
        }
4725
        else
4726
        {
4727
            $result = $cots_base . '.0000.cots';
4728
        }
3967 dpurdie 4729
        if ( $result =~ m~(.*)\.(\d+)(\d\d\d)\.cots$~ )
4730
        {
4731
            $buildVersion = [$1, 0 , $2, $3 ];
4732
        }
392 dpurdie 4733
    }
4734
    #
4735
    #   Convert version into full form for comparisions
4736
    #       nnn.nnn.nnn.[p]nnn.xxx
4737
    #       nnn.nnn.nnn.[p]nnn-xxx
4738
    #       nnn.nnn.nnn-[p]nnn.xxx
4739
    #       nnn.nnn.nnn-[p]nnn-xxx
4740
    #       nnn.nnn.nnn[p]nnn-xxx
4741
    #   Don't flag as ripples - they are patches
4742
    #
4743
    elsif ( $version =~ m~^(\d+)\.(\d+)\.(\d+)[-.p][p]?(\d+)([-.](.*))?$~ ) {
4744
        $major = $1;
4745
        $minor = $2;
4746
        $patch = $3;
4747
        $build = $4;
4748
        $suffix = defined $6 ? ".$6" : '';
4749
        $isaRipple = 0;
3967 dpurdie 4750
        $isaPatch = 1;
392 dpurdie 4751
    }
4752
    #
4753
    #       nn.nnn.nnnnn.xxx
4754
    #       nn.nnn.nnnnn-xxx
4755
    #       nnn.nnn.nnnx.xxx
4756
    #   Don't flag as ripples - they are patches
4757
    #
4758
    elsif ( $version =~ m~^(\d+)\.(\d+)\.(\d+)\w?([-.](.*))?$~ ) {
4759
        $major = $1;
4760
        $minor = $2;
4761
        $patch = $3;
4762
        if ( length( $patch) >= 4 )
4763
        {
4764
            $build = substr( $patch, -3 ,3);
4765
            $patch = substr( $patch,  0 ,length($patch)-3);
4766
        }
4767
        $suffix = defined $5 ? ".$5" : '';
4768
    }
4769
 
4770
    #
4771
    #       nnn.nnn.nnn
4772
    #       nnn.nnn-nnn
4773
    #       nnn.nnn_nnn
4774
    #
4775
    elsif ( $version =~ m~^(\d+)\.(\d+)[-._](\d+)$~ ) {
4776
        $major = $1;
4777
        $minor = $2;
4778
        $patch = $3;
4779
        $suffix = '';
4780
    }
4781
 
4782
    #
4783
    #       nnn.nnn.nnn.nnn
4784
    #       nnn.nnn.nnn-nnn
4785
    #       nnn.nnn.nnn_nnn
4786
    #
4787
    elsif ( $version =~ m~^(\d+)\.(\d+)\.(\d+)[-._](\d+)$~ ) {
4788
        $major = $1;
4789
        $minor = $2;
4790
        $patch = $3;
4791
        $build = $4;
4792
        $suffix = '';
4793
        $isaRipple = 0;
4794
    }
4795
 
4796
 
4797
    #
4798
    #       nnn.nnn
4799
    #
4800
    elsif ( $version =~ m~^(\d+)\.(\d+)$~ ) {
4801
        $major = $1;
4802
        $minor = $2;
4803
        $patch = 0;
4804
        $suffix = '';
4805
    }
4806
    #
4807
    #       nnn.nnn.xxx
4808
    #
4809
    elsif ( $version =~ m~^(\d+)\.(\d+)(\.\w+)$~ ) {
4810
        $major = $1;
4811
        $minor = $2;
4812
        $patch = 0;
4813
        $suffix = $3;
4814
    }
3967 dpurdie 4815
 
4816
    #
4817
    #       nnn.nnn.c.xxx
4818
    #
4819
    elsif ( $version =~ m~^(\d+)\.(\d+)\.(\w)(\.\w+)$~ ) {
4820
        $major = $1;
4821
        $minor = $2;
4822
        $patch = ord($3);
4823
        $suffix = $4;
4824
    }
392 dpurdie 4825
 
3967 dpurdie 4826
 
392 dpurdie 4827
    #
4828
    #       nnn.nnn.nnnz
4829
    #
4830
    elsif ( $version =~ m~^(\d+)\.(\d+)\.(\d+)([a-z])$~ ) {
4831
        $major = $1;
4832
        $minor = $2;
4833
        $patch = $3;
4834
        $build = ord($4) - ord('a');
4835
        $suffix = '.cots';
4836
        $isaRipple = 0;
4837
    }
4838
    #
4839
    #       ???REV=???
4840
    #
4841
    elsif ( $version =~ m~REV=~ ) {
4842
        $suffix = '.cots';
3967 dpurdie 4843
        $result = $version . '.000000.cots';
392 dpurdie 4844
    }
4845
 
4846
    #
4847
    #   Wip Packages
4848
    #   (nnnnnn).xxx
4849
    #   Should be essential, but want to sort very low
4850
    #
4851
    elsif ($version =~ m~\((.*)\)(\..*)?~) {
4852
        $suffix = $2 || '';
3967 dpurdie 4853
        $result = "000.000.000.00000$suffix";
392 dpurdie 4854
        $isaWIP = 1;
4855
    }
4856
 
4857
    #
4858
    #   !current
4859
    #
4860
    elsif ($version eq '!current' || $version eq 'current_$USER' || $version eq 'current' || $version eq 'beta' || $version eq 'latest' || $version eq 'beta.cr' || $version eq 'CREATE') {
4861
        $suffix = '';
3967 dpurdie 4862
        $result = "000.000.000.00000$suffix";
392 dpurdie 4863
        $isaWIP = 1;
4864
    }
4865
 
4866
    #
4867
    #   Also WIP: FINRUN.103649.BEI.WIP
4868
    elsif ($version =~ m~(\.[a-zA-Z]+)\.WIP$~) {
4869
        $suffix = lc($1);
3967 dpurdie 4870
        $result = "000.000.000.00000$suffix";
392 dpurdie 4871
        $isaWIP = 1;
4872
    }
4873
 
4874
    #
4875
    #   Also ERGOFSSLS190100_015
4876
    #   Don't flag as a ripple
4877
    elsif ($version =~ m~^ERG[A-Z]+(\d\d)(\d\d)(\d\d)[-_](\d+)(\.\w+)?$~) {
4878
        $major = $1;
4879
        $minor = $2;
4880
        $patch = $3;
4881
        $build = $4;
4882
        $suffix = $5 || '.sls';
4883
        $isaRipple = 0;
4884
    }
4885
 
4886
    #
4887
    #   Stuff we don't yet handle
4888
    #
4889
    else  {
4890
        Warning ("Unknown version number: $name,$version");
4891
        $version =~ m~(\.\w+)$~;
4892
        $suffix = $1 || '';
4893
        $result = $version;
4894
    }
4895
 
4896
    $isaRipple = ($build > 0) unless defined $isaRipple;
4897
    unless ( $result )
4898
    {
4899
        # Major and minor of 99.99 are normally funy versions
4900
        # Don't make important desicions on them
4901
        #
4902
        if ( $major == 99 && $minor == 99 )
4903
        {
4904
            $major = 0;
4905
            $minor = 0;
4906
            $patch = 0;
4907
        }
4908
 
3967 dpurdie 4909
        $result = sprintf("%3.3d.%3.3d.%3.3d.%5.5d%s", $major,$minor,$patch,$build,$suffix || '.0000');
392 dpurdie 4910
        $buildVersion = [ $major, $minor, $patch, $build ];
4911
    }
4912
 
4913
    $suffix = lc( $suffix );
4914
    if ( exists $suffixFixup{$suffix} )
4915
    {
4916
        $suffix = $suffixFixup{$suffix} ;
4917
    }
4918
 
3967 dpurdie 4919
    return ($suffix, $result, $isaRipple, $isaWIP, $buildVersion, $isaPatch );
392 dpurdie 4920
}
4921
 
4922
#-------------------------------------------------------------------------------
394 dpurdie 4923
# Function        : vcsCleanup
4924
#
4925
# Description     : Cleanup and rewrite a vcstag
4926
#
4927
#                   DUPLICATED IN:
4928
#                       - cc2svn_procdata
395 dpurdie 4929
#                       - cc2svn_importpackage
394 dpurdie 4930
#
4931
# Inputs          : vcstag
4932
#
4933
# Returns         : Cleaned up vcs tag
4934
#
4935
sub vcsCleanup
4936
{
4937
    my ($tag) = @_;
2764 dpurdie 4938
    $tag =~ tr~\\/~/~;                              # Force use of /
4939
    $tag =~ s~/+$~~;                                # Trailing /
394 dpurdie 4940
    if ( $tag =~ m~^CC::~ )
4941
    {
2764 dpurdie 4942
        $tag =~ s~CC::/VOB:/~CC::/~;                # Kill stuff
2429 dpurdie 4943
        $tag =~ s~CC::load\s+~CC::~;                # Load rule
4944
        $tag =~ s~CC::\s+~CC::~;                    # Leading white space
4945
        $tag =~ s~CC::[A-Za-z]\:/~CC::/~;           # Leading driver letter
4946
        $tag =~ s~CC::/+~CC::/~;                    # Multiple initial /'s
4947
        $tag =~ s~/build.pl::~::~i;
4948
        $tag =~ s~/src::~::~i;
394 dpurdie 4949
        $tag =~ s~MASS_Dev_Bus/Cbp/~MASS_Dev_Bus/CBP/~i;
4950
        $tag =~ s~MASS_Dev_Bus~MASS_Dev_Bus~i;
4951
        $tag =~ s~/MASS_Dev/Infra~MASS_Dev_Infra~i;
4952
        $tag =~ s~/MASS_Dev/Bus/web~/MASS_Dev_Bus/web~i;
4953
 
4954
        $tag =~ s~/Vastraffik/~/Vasttrafik/~;
4955
        $tag =~ s~/MREF_Package/ergpostmongui$~/MREF_Package/ergpostmongui~i;
395 dpurdie 4956
        $tag =~ s~DPC_SWCode/~DPG_SWCode/~i;
394 dpurdie 4957
    }
4958
    return $tag;
4959
}
4960
 
4961
#-------------------------------------------------------------------------------
392 dpurdie 4962
# Function        : examineVcsTag
4963
#
4964
# Description     : Examine a VCS Tag and determine if it looks like rubbish
394 dpurdie 4965
#                   Give it a clean
392 dpurdie 4966
#
4967
# Inputs          : $entry
4968
#
4969
# Returns         : Will add Data to the $entry
4970
#
4971
sub examineVcsTag
4972
{
4973
    my ($entry) = @_;
4974
    my $bad = 0;
394 dpurdie 4975
 
395 dpurdie 4976
    $versions{$entry}{vcsTag} = vcsCleanup($versions{$entry}{vcsTag});
4977
    my $vcstag = $versions{$entry}{vcsTag};
394 dpurdie 4978
 
392 dpurdie 4979
    if ( $vcstag =~ m~^SVN::~ ) {
4980
        $versions{$entry}{isSvn} = 1;
4981
 
4982
    } elsif ( $vcstag =~ m~^CC::(.*?)(::(.+))?$~ ) {
4983
        my $path = $1  || '';
4984
        my $label = $2 || '';
4985
        $bad = 1 unless ( $label );
4986
        $bad = 1 if ( $label =~ m~^N/A$~i || $label  =~ m~^na$~i );
4987
 
4988
        $bad = 1 unless ( $path );
4989
        $bad = 1 if ( $path =~ m~^N/A$~i || $path  =~ m~^na$~i );
4990
        $bad = 1 if ( $path =~ m~^/dpkg_archive~ || $path  =~ m~^dpkg_archive~ );
4991
        $bad = 1 if ( $path =~ m~^/devl/~ || $path  =~ m~^devl/~ );
395 dpurdie 4992
        $bad = 1 if ( $path =~ m~^CVS~ );
392 dpurdie 4993
        $bad = 1 if ( $path =~ m~^http:~i );
4994
        $bad = 1 if ( $path =~ m~^[A-Za-z]\:~ );
4995
        $bad = 1 if ( $path =~ m~^//~ );
2764 dpurdie 4996
        $bad = 1 if ( $path =~ m~^/blade1/~ );
4997
        $bad = 1 if ( $path =~ m~^/devl/~ );
394 dpurdie 4998
        $bad = 1 if ( $path =~ m~^/*none~i );
4999
        $bad = 1 if ( $path =~ m~^/*NoWhere~i );
5000
        $bad = 1 if ( $path =~ m~^-$~i );
392 dpurdie 5001
        $bad = 1 if ( $path =~ m~^cvsserver:~ );
5002
        $bad = 1 if ( $path =~ m~,\s*module:~ );
2764 dpurdie 5003
        $bad = 1 if ( $path =~ m~[()]~ );
392 dpurdie 5004
#        $bad = 1 unless ( $path =~ m~^/~ );
5005
    }
5006
    else
5007
    {
5008
        $bad = 1;
5009
    }
5010
    $versions{$entry}{badVcsTag} = 1 if ( $bad );
5011
}
5012
 
5013
#-------------------------------------------------------------------------------
5014
# Function        : logToFile
5015
#
5016
# Description     : Log some data to a named file
5017
#                   Use file locking to allow multiple process to log
5018
#
5019
# Inputs          : $filename           - Name of file to log
5020
#                   ...                 - Data to log
5021
#
5022
# Returns         : Nothing
5023
#
5024
sub logToFile
5025
{
5026
    my ($file, @data) = @_;
5027
 
5028
    open  (LOGFILE, '>>', $file);
5029
    flock (LOGFILE, LOCK_EX);
5030
    print  LOGFILE "@data\n";
5031
    flock (LOGFILE, LOCK_UN);
5032
    close (LOGFILE);
5033
}
5034
 
5035
#-------------------------------------------------------------------------------
5036
# Function        : createImages
5037
#
5038
# Description     : Create nice images of the RM version tree
5039
#
5040
# Inputs          : 
5041
#
5042
# Returns         : 
5043
#
5044
sub createImages
5045
{
5046
 
5047
    my $filebase = "${packageNames}";
2931 dpurdie 5048
    my $openOk;
5049
    foreach my $ii ( 0 .. 5 )
5050
    {
5051
        if (open (FH, '>', $cwd . "/$filebase.dot" ))
5052
        {
5053
            $openOk = 1;
5054
            last;
5055
        }
5056
        sleep (2);
5057
    }
5058
    unless ( $openOk )
5059
    {
5060
        Warning ("Cannot open image output: $filebase.dot");
5061
        return;
5062
    }
5063
 
5064
 
392 dpurdie 5065
    print FH "digraph \"${packageNames}\" {\n";
5066
    #print FH "rankdir=LR;\n";
5067
    print FH "node[fontsize=16];\n";
5068
    print FH "node[target=_graphviz];\n";
5069
#    print FH "subgraph cluster_A {\n";
5070
#    print FH "node[fontsize=12];\n";
5071
 
5072
    {
5073
        my @text;
5074
        push @text, $packageNames;
5075
        push @text, 'HyperLinked to Release Manager';
5076
        push @text, 'Created:' . localtime();
5077
        push @text, '|';
5078
 
5079
        push @text, 'Total RM versions: ' . $totalVersions;
5080
        push @text, 'Essential Entries: ' . scalar @EssentialPackages;
5081
        push @text, 'Initial trees: ' . $initialTrees;
5082
 
1270 dpurdie 5083
        push @text, 'Number of Entries: ' . $processTotal;
392 dpurdie 5084
        push @text, 'Type : ' . $packageType;
5085
        push @text, 'All versions in Subversion' if ( $allSvn );
5086
 
5087
        push @text, '|';
5088
        push @text, 'Total Project Branches: ' . $ProjectCount;
5089
        foreach ( sort keys %knownProjects )
5090
        {
5091
            my $count = $knownProjects{$_}{count} || 0;
5092
            if ( $count )
5093
            {
5094
                my $text = 'Project Branch: ' . $_;
5095
                $text .= " (" . $count . ")" if ( $count > 1 );
5096
                push @text, $text;
5097
            }
5098
        }
5099
 
5100
        push @text, '|';
5101
        push @text, 'Bad VCS : ' . $badVcsCount;
5102
        push @text, 'Bad Singletions : ' . $badSingletonCount;
5103
        push @text, 'Deadwood entries : ' . $trimCount;
5104
        push @text, 'Walking Mode : Flat' if ($opt_flat);
5105
        push @text, 'Pruned Mode : ' . $pruneModeString;
5106
        push @text, 'Pruned entries : ' . $pruneCount;
1341 dpurdie 5107
        push @text, 'Recent entries : ' . $recentCount;
392 dpurdie 5108
 
5109
        if ( @unknownProjects )
5110
        {
5111
            push @text, '|';
5112
            push @text, 'Unknown Projects';
5113
            push @text, 'Unknown Project: ' . $_ foreach (sort @unknownProjects );
5114
        }
5115
 
5116
        #
5117
        #   Multiple Paths
5118
        #
5119
        if ( scalar @multiplePaths > 1 )
5120
        {
5121
            push @text, '|';
5122
            push @text, 'Multiple Paths';
3967 dpurdie 5123
            if ( $opt_AllowMuliplePaths )
5124
            {
5125
                push @text, 'Multiple Paths allowed:' . scalar @multiplePaths . ' found';
5126
            }
5127
            else
5128
            {
5129
                push @text, @multiplePaths;
5130
            }
392 dpurdie 5131
        }
5132
 
5133
        #
5134
        #   Bad essentials
5135
        #
5136
        if ( @badEssentials  )
5137
        {
5138
            push @text, '|';
5139
            push @text, 'Bad Essential Versions';
5140
            push @text, GetVname($_) foreach ( @badEssentials );
5141
        }
5142
 
5143
        #
5144
        #   Subversion Data
5145
        #
5146
        if ( %svnData )
5147
        {
5148
            push @text, '|';
5149
            push @text, 'Subversion';
5150
            push @text, 'Trunk used' if exists $svnData{branches}{trunk} ;
5151
            push @text, 'Labels: ' . scalar keys %{$svnData{tags}} ;
5152
            push @text, 'Branches: ' . scalar keys %{$svnData{branches}} ;
2429 dpurdie 5153
            push @text, 'Relabled Packages : ' . $packageReLabelCount;
392 dpurdie 5154
        }
5155
 
5156
        push @text, '';
5157
        my $text = join '\l', @text;
5158
        $text =~ s~\|\\l~|~g;
5159
 
5160
        my @attributes;
5161
        push @attributes, "shape=record";
5162
        push @attributes, "label=\"{$text}\"";
5163
        push @attributes, "tooltip=\"$packageNames\"";
1272 dpurdie 5164
        push (@attributes, "URL=\"" . $GBE_RM_URL . "/view_by_version.asp?pkg_id=$first_pkg_id" . "\"" )if $first_pkg_id;
392 dpurdie 5165
        push @attributes, "color=red";
5166
        my $attr = join( ' ', @attributes);
5167
 
5168
        my $tld_done = 'TitleBlock';
5169
        print FH "$tld_done [$attr]\n";
5170
    }
5171
 
5172
    #
5173
    #   Generate Legend
5174
    #
5175
    {
5176
        my @text;
5177
        push @text, 'Legend';
5178
        push @text, '|';
5179
        push @text, 'Node Content';
5180
        push @text, 'Package Version';
5181
#        push @text, 'Release Manager Ref (pvid)';
5182
        push @text, 'Creation Date: yyyy-mm-dd';
5183
        push @text, '(Coded information)';
5184
        push @text, '|{Code';
5185
        push @text, '|{N: Not Locked';
5186
        push @text, 'b: Bad Singleton';
5187
        push @text, 'B: Bad VCS Tag';
3967 dpurdie 5188
        push @text, 'd: Package in dpkg_archive';
392 dpurdie 5189
        push @text, 'D: DeadWood';
1272 dpurdie 5190
        push @text, 'E: Essential Release Version';
2429 dpurdie 5191
        push @text, 'F: Package directories labled';
392 dpurdie 5192
        push @text, 'G: Glued into Version Tree';
2429 dpurdie 5193
        push @text, 'L: Label not in VOB';
3967 dpurdie 5194
        push @text, 'p: Is a Patch';
1272 dpurdie 5195
        push @text, 'r: Recent version';
1341 dpurdie 5196
        push @text, 'R: Ripple';
392 dpurdie 5197
        push @text, 'S: Splitpoint';
5198
        push @text, 't: Glued into Project Tree';
5199
        push @text, 'T: Tip version';
5200
        push @text, 'V: In SVN';
5201
        push @text, '+: In Subversion';
2429 dpurdie 5202
        push @text, '0: Zero files extracted';
392 dpurdie 5203
        push @text, '}}';
5204
 
5205
        push @text, '|';
5206
        push @text, 'Outline';
5207
        push @text, 'Red: Dead or Bad VCS Tag';
5208
        push @text, 'Orange: Project Branch Root';
5209
        push @text, 'Green: Ripple Build Version';
5210
        push @text, 'Blue: Essential Version';
5211
        push @text, 'Darkmagenta: Entry Glued into tree';
5212
        push @text, 'Magenta: Entry added to project tree';
2429 dpurdie 5213
        push @text, 'DeepPink: Label not in VOB';
5214
        push @text, 'DarkViolet: Zero files extracted';
392 dpurdie 5215
 
5216
 
5217
        push @text, '|';
5218
        push @text, 'Fill';
5219
        push @text, 'PowderBlue: Essential Version';
5220
        push @text, 'Red: Bad Essential Version';
5221
        push @text, 'Light Green: Migrated to SVN';
5222
#        push @text, 'Red: Entry Glued into tree';
5223
#        push @text, 'Green: Entry added to project tree';
5224
 
5225
        push @text, '|';
5226
        push @text, 'Shape';
5227
        push @text, 'Oval: Normal Package Version';
5228
        push @text, 'Invhouse: Project Branch Root';
5229
        push @text, 'Octagon: Branch Point';
5230
        push @text, 'Box: Bad Single version with no history';
5231
        push @text, 'Doublecircle: Tip of a Project Branch';
5232
 
5233
        push @text, '';
5234
        my $text = join '\l', @text;
5235
        $text =~ s~\|\\l~|~g;
5236
        $text =~ s~\}\\l~}~g;
5237
 
5238
        my @attributes;
5239
        push @attributes, "shape=record";
5240
        push @attributes, "label=\"{$text}\"";
5241
        push @attributes, "color=red";
5242
        my $attr = join( ' ', @attributes);
5243
 
5244
        my $tld_done = 'LegendBlock';
5245
        print FH "$tld_done [$attr]\n";
5246
    }
5247
 
5248
#    print FH "\n}\n";
5249
    print FH "TitleBlock -> LegendBlock [style=invis]\n";
5250
 
5251
    sub genLabelText
5252
    {
5253
        my ($entry) = @_;
5254
        my @label;
5255
        push @label, $versions{$entry}{name} if ( $multiPackages );
5256
        push @label, $versions{$entry}{vname};
5257
#        push @label, $entry;       # Add PVID
5258
        push @label, substr( $versions{$entry}{created}, 0, 10); #  2008-02-19
5259
#        push @label, 'V=' . $versions{$entry}{maxVersion};
5260
#        push @label, 'B=' . $versions{$entry}{svnBranchTip} if ( exists $versions{$entry}{svnBranchTip} );
5261
 
5262
 
5263
        my $stateText = '';
5264
        $stateText .= 'N' if ($versions{$entry}{locked} eq 'N');
5265
        $stateText .= 'b' if (exists $versions{$entry}{badSingleton});
5266
        $stateText .= 'B' if (exists $versions{$entry}{badVcsTag});
5267
        $stateText .= 'G' if (exists $versions{$entry}{GluedIn});
5268
        $stateText .= 't' if (exists $versions{$entry}{MakeTree});
1197 dpurdie 5269
        $stateText .= 'E' if (exists $versions{$entry}{Essential});
3967 dpurdie 5270
        $stateText .= 'd' if (exists $versions{$entry}{dpkgArchive});
392 dpurdie 5271
        $stateText .= 'D' if (exists $versions{$entry}{DeadWood});
3967 dpurdie 5272
        $stateText .= 'p' if ( $versions{$entry}{isaPatch} );
1341 dpurdie 5273
        $stateText .= 'R' if ( $versions{$entry}{isaRipple} );
1272 dpurdie 5274
        $stateText .= 'r' if (exists $versions{$entry}{keepRecent} && $versions{$entry}{keepRecent} );
392 dpurdie 5275
        $stateText .= 'S' if (exists $versions{$entry}{EssentialSplitPoint} && $versions{$entry}{EssentialSplitPoint} > 1 );
5276
        $stateText .= 'T' if (exists $versions{$entry}{Tip} );
5277
        $stateText .= 'V' if (exists $versions{$entry}{isSvn} );
5278
        $stateText .= '+' if (exists $versions{$entry}{svnVersion} );
2429 dpurdie 5279
        $stateText .= '0' if (exists $versions{$entry}{data}{errCode} && $versions{$entry}{data}{errCode} eq '0');
5280
        $stateText .= 'L' if (exists $versions{$entry}{data}{errCode} && $versions{$entry}{data}{errCode} eq 'L');
5281
        $stateText .= 'F' if ($versions{$entry}{data}{DirsLabled});
5282
 
5283
 
392 dpurdie 5284
#        $stateText .= 's' if (exists $versions{$entry}{branchPoint} );
5285
#        $stateText .= ' T='. $versions{$entry}{threadId} if (exists $versions{$entry}{threadId});
5286
#        $stateText .= ' EssentalPath' if (exists $versions{$entry}{EssentialPath});
5287
#        $stateText .= ' Count='. $versions{$entry}{EssentialSplitPoint} if (exists $versions{$entry}{EssentialSplitPoint});
5288
#        $stateText .= ' M='. $versions{$entry}{maxVersion} if (exists $versions{$entry}{maxVersion});
5289
 
2429 dpurdie 5290
        push @label, "(${stateText})" if ( length($stateText) );
392 dpurdie 5291
 
1356 dpurdie 5292
##       Insert Release Names
2429 dpurdie 5293
        foreach my $rtag_id ( keys %{$versions{$entry}{Releases}}  ) {
5294
            next unless ( exists $ukHopsReleases{$rtag_id} );
5295
            push @label, "Release: $versions{$entry}{Releases}{$rtag_id}{rname}";
5296
        }
1356 dpurdie 5297
 
392 dpurdie 5298
        return join ('\n', @label );
5299
    }
5300
 
5301
    sub genAttributes
5302
    {
5303
        my ($entry) = @_;
5304
        my @attributes;
5305
        push @attributes, 'label="' . genLabelText($entry) . '"';
5306
        push @attributes, 'URL="' . dotUrl($entry) . '"';
5307
        push @attributes, 'tooltip="' . "Goto: $versions{$entry}{vname}, PVID=$entry" ,'"';
5308
        my $shape;
5309
            $shape = 'box' if ($versions{$entry}{badSingleton});
5310
            $shape = 'octagon'  if ($versions{$entry}{branchPoint});
5311
            $shape = 'invhouse' if ($versions{$entry}{newSuffix});
5312
            $shape = 'doublecircle' if ($versions{$entry}{Tip});
5313
 
5314
 
5315
        push @attributes, 'shape=' . $shape if ( $shape );
5316
 
5317
        my $color;
5318
        my $fill;
5319
           $color = 'color=green style=bold' if ( $versions{$entry}{isaRipple} );
5320
           $color = 'color=orange style=bold' if ( $versions{$entry}{newSuffix} );
5321
           $color = 'color=red style=bold' if ( $versions{$entry}{DeadWood} || $versions{$entry}{badVcsTag} );
5322
           $color = 'color=blue style=bold' if ( $versions{$entry}{Essential} );
5323
           $color = 'color=darkmagenta style=bold' if ( $versions{$entry}{GluedIn} );
5324
           $color = 'color=magenta style=bold' if ( $versions{$entry}{MakeTree} );
2429 dpurdie 5325
           $color = 'color=DeepPink style=bold' if (exists $versions{$entry}{data}{errCode} && $versions{$entry}{data}{errCode} eq 'L');
5326
           $color = 'color=DarkViolet style=bold' if (exists $versions{$entry}{data}{errCode} && $versions{$entry}{data}{errCode} eq '0');
392 dpurdie 5327
 
5328
           $fill = 'style=filled fillcolor=powderblue' if ( $versions{$entry}{Essential} );
5329
           $fill = 'style=filled fillcolor=red' if ( $versions{$entry}{Essential} && $versions{$entry}{badVcsTag} );
5330
           $fill = 'style=filled fillcolor="#99FF99"' if ( exists $versions{$entry}{svnVersion} );
5331
 
5332
 
5333
        push @attributes, $color if ( $color );
5334
        push @attributes, $fill if ( $fill );
5335
 
5336
        return '[' . join( ' ', @attributes) . ']';
5337
    }
5338
 
5339
    sub genArrowAttributes
5340
    {
5341
        my ($not_first, $entry) = @_;
5342
        my @attributes;
5343
 
5344
        push @attributes, 'arrowhead=empty' if ( $not_first );
5345
        push ( @attributes, 'label="' . $versions{$entry}{svnBranchTip} .'"' ) if ( exists $versions{$entry}{svnBranchTip} );
5346
 
5347
        return ('[' . join( ' ', @attributes) . ']') if ( @attributes ) ;
5348
        return '';
5349
    }
5350
 
5351
    #
5352
    #   Flat
5353
    #
5354
    if ( $opt_flat )
5355
    {
5356
        my $last = 0;
5357
        foreach my $entry (@flatOrder )
5358
        {
5359
            if ( $last )
5360
            {
5361
                my $me = dotTag($last);
5362
 
5363
                print FH pentry($me)  ,' -> ', pentry(dotTag($entry)), genArrowAttributes(0, $entry) ,";\n";
5364
                print FH pentry($me)  ,genAttributes($last) . ";\n";
5365
            }
5366
            $last = $entry;
5367
        }
5368
        print FH pentry(dotTag($last))  ,genAttributes($last) . ";\n";
5369
 
5370
    }
5371
    else
5372
    {
5373
        foreach my $entry ( sort {$a <=> $b} keys(%versions) )
5374
        {
5375
            my $me = dotTag($entry);
5376
            my @versions = @{ $versions{$entry}{next}};
5377
            my $ii = 0;
5378
            foreach ( @versions )
5379
            {
5380
                print FH pentry($me)  ," -> ",pentry(dotTag($_)), genArrowAttributes($ii++, $_), ";\n";
5381
            }
5382
 
5383
            print FH pentry($me)  ,genAttributes($entry) . ";\n";
5384
        }
5385
    }
5386
 
5387
    print FH "\n};\n";
5388
    close FH;
5389
 
5390
    #
5391
    #   Convert DOT to a SVG
5392
    #
5393
    unless ( $UNIX )
5394
    {
5395
    print "Generating graphical images\n";
5396
#    system( "dot $filebase.dot -Tjpg -o$filebase.jpg" );  # -v
5397
    system( "dot $filebase.dot -Tsvg -o$filebase.svg" );  # -v
5398
#    unlink("$filebase.dot");
5399
 
5400
    #
5401
    #   Display a list of terminal packages
5402
    #   These are packages that are not used by any other package
5403
    #
5404
    print "\n";
5405
#    print "Generated: $filebase.dot\n";
5406
#    print "Generated: $filebase.jpg\n";
5407
    print "Generated: $filebase.svg\n";
5408
    }
5409
    else
5410
    {
5411
        print "Generated: $filebase.dot\n";
5412
    }
5413
}
5414
 
5415
sub dotTag
5416
{
5417
    my ($entry) = @_;
5418
 
5419
    my $label = '';
5420
    $label .= $versions{$entry}{name} if $multiPackages;
5421
    $label .= $versions{$entry}{vname};
5422
    $label =~ s~[-() ]~_~g;
5423
    return $label;
5424
}
5425
 
5426
sub dotUrl
5427
{
5428
    my ($entry) = @_;
5429
 
5430
    my $pv_base = $GBE_RM_URL . "/fixed_issues.asp?pv_id=$entry";
5431
}
5432
 
5433
#-------------------------------------------------------------------------------
5434
# Function        : pentry
5435
#
5436
# Description     : Generate an entry list as text
5437
#                   Replace "." with "_" since DOT doesn't like .'s
5438
#                   Seperate the arguments
5439
#
5440
# Inputs          : @_          - An array of entries to process
5441
#
5442
# Returns         : A string
5443
#
5444
sub pentry
5445
{
5446
    my ($data) = @_;
5447
    $data =~ s~\.~_~g;
5448
    $result = '"' . $data . '"' ;
5449
    return $result;
5450
}
5451
 
5452
#-------------------------------------------------------------------------------
5453
# Function        : getVobMapping
5454
#
5455
# Description     : Read in Package to Repository Mapping
5456
#
5457
# Inputs          : 
5458
#
5459
# Returns         : Populates %VobMapping
5460
#                             Mapping of PackageName to RepoName[/Subdir]
5461
#
5462
our %ScmRepoMap;
5463
sub getVobMapping
5464
{
5465
    Message ("Read in Vob Mapping");
5466
 
5467
    my $fname = 'cc2svn.repo.dat';
5468
    Error "Cannot locate $fname" unless ( -f $fname );
5469
    require $fname;
5470
 
5471
    Error "Data in $fname is not valid\n"
5472
        unless ( keys(%ScmRepoMap) >= 0 );
5473
 
5474
    $opt_vobMap = $ScmRepoMap{$packageNames}{repo}
5475
        if (exists $ScmRepoMap{$packageNames});
5476
 
2450 dpurdie 5477
    $opt_protected = $ScmRepoMap{$packageNames}{protected}
5478
        if (exists $ScmRepoMap{$packageNames}{protected});
3967 dpurdie 5479
 
5480
    $opt_vobMap = '' if ( $opt_repoSubdir );
5481
 
392 dpurdie 5482
    #
5483
    #   Free the memory
5484
    #
5485
    %ScmRepoMap = ();
5486
 
5487
    #
5488
    #   Calculate Target Repo
5489
    #
5490
    Warning ("No VOB Mapping found")
3967 dpurdie 5491
        unless ($opt_vobMap || ($opt_repoSubdir && $opt_repo));
392 dpurdie 5492
    Error("No repository specified. ie -repo=DevTools or -repo=COTS")
5493
        unless ( $opt_repo || $opt_vobMap );
2931 dpurdie 5494
    my $r1 = ($opt_repo || '') . '/' . ($opt_vobMap || '') . '/' . ($opt_repoSubdir || '') ;
3967 dpurdie 5495
    $r1 = 'Import_test/' . $r1 if ( $opt_useTestRepo );
2931 dpurdie 5496
    $r1 =~ s~//~/~g;
392 dpurdie 5497
    $r1 =~ s~^/~~;
3967 dpurdie 5498
    $r1 =~ s~/\.$~~;
392 dpurdie 5499
    $r1 =~ s~/$~~;
5500
    $svnRepo = $opt_repo_base . $r1;
5501
 
2931 dpurdie 5502
    Message( "Repo URL: $svnRepo");
392 dpurdie 5503
}
5504
 
5505
 
5506
#-------------------------------------------------------------------------------
5507
# Function        : getEssenialPackageVersions
5508
#
5509
# Description     : Determine the 'Essental' Package Versions
5510
#                   Read the data in from an external file
5511
#
5512
# Inputs          : 
5513
#
5514
# Returns         : Populates @EssentialPackages
5515
#
5516
 
5517
our %ScmReleases;
5518
our %ScmPackages;
5519
our %ScmSuffixes;
5520
sub getEssenialPackageVersions
5521
{
5522
    Message ("Read in Essential Package Versions");
5523
 
5524
    my $fname = 'cc2svn.raw.txt';
5525
    Error "Cannot locate $fname" unless ( -f $fname );
5526
    require $fname;
5527
 
5528
    Error "Data in $fname is not valid\n"
5529
        unless ( keys(%ScmReleases) >= 0 );
5530
 
5531
#    DebugDumpData("ScmReleases", \%ScmReleases );
5532
#    DebugDumpData("ScmPackages", \%ScmPackages );
5533
#    DebugDumpData("ScmSuffixes", \%ScmSuffixes );
5534
 
5535
    #
5536
    #   Create a list of essential packages
5537
    #   Retain packages-versions used in this program
5538
    #
5539
    foreach ( keys %ScmPackages )
5540
    {
5541
        next unless ( exists  $pkg_ids{ $ScmPackages{$_}{pkgid} } );
5542
        push @EssentialPackages, $_;
5543
        Error ("Essential Package Version not in extracted Release Manager Data: $_")
5544
            unless ( exists $versions{$_} );
5545
        $versions{$_}{Essential} = 1;
1356 dpurdie 5546
 
5547
        # Retain which RM Release this package-version is the tip
5548
        # Release of
5549
        foreach my $rtag_id ( @{$ScmPackages{$_}{'release'}} )
5550
        {
5551
            $versions{$_}{Releases}{$rtag_id}{rname}   = $ScmReleases{$rtag_id}{name};
5552
            $versions{$_}{Releases}{$rtag_id}{pname}   = $ScmReleases{$rtag_id}{pName};
5553
            $versions{$_}{Releases}{$rtag_id}{proj_id} = $ScmReleases{$rtag_id}{proj_id};
5554
        }
5555
 
1197 dpurdie 5556
        #print "ESSENTIAL: $versions{$_}{name} $versions{$_}{vname}\n";
392 dpurdie 5557
    }
5558
 
5559
    #
5560
    #   Free memory
5561
    #
5562
    %ScmReleases = ();
5563
    %ScmPackages = ();
5564
    %ScmSuffixes = ();
5565
 
5566
#    DebugDumpData("Essential", \@EssentialPackages );
5567
    Message ("Essential Versions: " . scalar @EssentialPackages );
5568
}
5569
 
5570
#-------------------------------------------------------------------------------
5571
# Function        : ReportPathVariance
5572
#
5573
# Description     : Report variance in paths used by the versions
5574
#
5575
# Inputs          : 
5576
#
5577
# Returns         : 
5578
#
5579
my %VobPaths;
5580
sub ReportPathVariance
5581
{
5582
    Message ("Detect Multiple Paths");
5583
    foreach my $entry ( keys(%versions) )
5584
    {
5585
        my $e = $versions{$entry};
5586
        next if ( isSet ($e, 'DeadWood' ) );
5587
        next if ( isSet ($e, 'badVcsTag') );
5588
        next if ( isSet ($e, 'isSvn') );
5589
        my $tag = $e->{vcsTag};
5590
        next unless ( $tag );
5591
 
5592
        $tag =~ m~^(.+?)::(.*?)(::(.+))?$~;
5593
        my $vcsType = $1;
5594
        my $cc_label = $4;
5595
        my $cc_path = $2;
5596
        $cc_path = '/' . $cc_path;
5597
        $cc_path =~ tr~\\/~/~s;
2764 dpurdie 5598
        $cc_path =~ s~/+$~~;
392 dpurdie 5599
 
5600
        $VobPaths{$cc_path}++;
5601
    }
5602
 
5603
    @multiplePaths = sort keys %VobPaths;
5604
    if ( scalar @multiplePaths > 1 )
5605
    {
5606
        Warning ("Multiple Paths:" . $_ ) foreach (@multiplePaths);
2764 dpurdie 5607
 
5608
        # Kill SVN import
5609
        # User will need to configure one path
5610
        unless ( $opt_AllowMuliplePaths )
5611
        {
5612
            Warning ("Multiple Paths detected: Import supressed");
5613
            $opt_useSvn = 0
5614
        }
5615
        else
5616
        {
5617
            Message ("Multiple Paths detected: Allowed");
5618
        }
392 dpurdie 5619
    }
5620
}
5621
 
5622
sub isSet
5623
{
5624
    my ($base, $element) = @_;
5625
    return 0 unless ( exists $base->{$element} );
5626
    return $base->{$element};
5627
}
5628
 
5629
 
5630
#-------------------------------------------------------------------------------
5631
# Function        : recurseList
5632
#
5633
# Description     : Return a list of all element below a given head element
5634
#
5635
# Inputs          : $head               - Head element
5636
#
5637
# Returns         : A list, not in any particular order
5638
#
5639
 
5640
our @recurseList;
5641
sub recurseList
5642
{
5643
    @recurseList = ();
5644
    recurseListBody (@_);
5645
    return @recurseList;
5646
}
5647
sub recurseListBody
5648
{
5649
    foreach my $entry ( @_ )
5650
    {
5651
        push @recurseList, $entry;
5652
no warnings "recursion";
5653
        recurseListBody (@{$versions{$entry}{next}});
5654
    }
5655
}
5656
 
5657
#-------------------------------------------------------------------------------
5658
# Function        : getSvnData
5659
#
5660
# Description     : Read the SVN tree and see what we have
5661
#
5662
# Inputs          : 
5663
#
5664
# Returns         : 
5665
#
5666
my @svnDataItems;
5667
sub getSvnData
5668
{
5669
    Message ("Examine Subversion Tree");
5670
 
5671
    #
5672
    #   Re-init data
5673
    #
5674
    @svnDataItems = ();
5675
    %svnData = ();
5676
 
5677
    #
5678
    #   Create an SVN session
5679
    #
5680
    return unless ( $svnRepo );
5681
    my $svn = NewSessionByUrl ( "$svnRepo/$packageNames" );
5682
    return unless ( $svn );
5683
 
5684
    #
5685
    #   extract data
5686
    #
5687
#    DebugDumpData("SVN", $svn );
5688
    $svn->SvnCmd ( 'log', '-v', '--xml', '--stop-on-copy', $svn->Full()
5689
                    , { 'credentials' => 1,
5690
                        'process' => \&ProcessSvnLog,
5691
                         }
5692
                        );
5693
 
5694
    #
5695
    #   Process data
5696
    foreach my $entry ( @svnDataItems )
5697
    {
5698
        my $name;
3967 dpurdie 5699
        my $target = $entry->{'target'};
392 dpurdie 5700
        if ( $target =~ m~/tags/(.*)~ ) {
5701
            $name = $1;
5702
            $svnData{tags}{$name} = 1;
5703
        } elsif ( $target =~ m~/branches/(.*)~ )  {
5704
            $name = $1;
5705
    #        $branches{$1} = 1;
5706
        } else {
5707
            $svnData{nonTag}{$target} = 1;
5708
        }
5709
 
5710
        my $fromBranch;
3967 dpurdie 5711
        if ( $entry->{'copyfrom-path'} =~ m~/trunk$~  ) {
392 dpurdie 5712
            $fromBranch = 'trunk';
3967 dpurdie 5713
        } elsif ( $entry->{'copyfrom-path'} =~ m~/branches/(.*)~ ) {
392 dpurdie 5714
            $fromBranch = $1;
5715
        }
5716
 
1356 dpurdie 5717
        # largest Rev number on branch
3967 dpurdie 5718
        if ( exists $svnData{max} && exists $svnData{max}{$fromBranch} )
392 dpurdie 5719
        {
3967 dpurdie 5720
            if ( $svnData{max}{$fromBranch}{rev} <  $entry->{'copyfrom-rev'} )
392 dpurdie 5721
            {
3967 dpurdie 5722
                $svnData{max}{$fromBranch}{rev} =  $entry->{'copyfrom-rev'};
1356 dpurdie 5723
                $svnData{max}{$fromBranch}{name} = $name;
392 dpurdie 5724
            }
5725
        }
1356 dpurdie 5726
        else
5727
        {
3967 dpurdie 5728
            $svnData{max}{$fromBranch}{rev} =  $entry->{'copyfrom-rev'};
1356 dpurdie 5729
            $svnData{max}{$fromBranch}{name} = $name;
5730
        }
392 dpurdie 5731
    }
1356 dpurdie 5732
 
5733
    foreach my $branch ( keys %{$svnData{max}} )
5734
    {
5735
        $svnData{tips}{$svnData{max}{$branch}{name}} = $branch;
5736
    }
5737
#    DebugDumpData("svnDataItems", \@svnDataItems);
392 dpurdie 5738
#    DebugDumpData("SvnData", \%svnData);
5739
 
1356 dpurdie 5740
 
392 dpurdie 5741
    foreach my $entry ( keys(%versions) )
5742
    {
5743
        my $import_label = saneLabel($entry);
5744
        delete $versions{$entry}{svnVersion};
5745
        delete $versions{$entry}{svnBranchTip};
5746
 
5747
        if ( exists $svnData{tags}{$import_label} )
5748
        {
5749
            $versions{$entry}{svnVersion} = 1;
5750
        }
5751
 
5752
        if ( exists $svnData{tips}{$import_label} )
5753
        {
5754
            $versions{$entry}{svnBranchTip} = $svnData{tips}{$import_label};
5755
        }
5756
    }
5757
 
1356 dpurdie 5758
    Message ( 'Trunk used: ' . (exists $svnData{'max'}{trunk} ? 'Yes' : 'No') );
392 dpurdie 5759
    Message ( 'Labels    : ' . scalar keys %{$svnData{tags}} );
1356 dpurdie 5760
    Message ( 'Branches  : ' . scalar keys %{$svnData{'max'}} );
392 dpurdie 5761
}
5762
 
5763
#-------------------------------------------------------------------------------
5764
# Function        : ProcessSvnLog
5765
#
5766
# Description     :
5767
#                   Parse
5768
#                       <logentry
5769
#                          revision="24272">
5770
#                       <author>bivey</author>
5771
#                       <date>2005-07-25T15:45:35.000000Z</date>
5772
#                       <paths>
5773
#                       <path
5774
#                          prop-mods="false"
5775
#                          text-mods="false"
5776
#                          kind="dir"
5777
#                          copyfrom-path="/enqdef/branches/Stockholm"
5778
#                          copyfrom-rev="24271"
5779
#                          action="A">/enqdef/tags/enqdef_24.0.1.sls</path>
5780
#                       </paths>
5781
#                       <msg>COTS/enqdef: Tagged by Jats Svn Import</msg>
5782
#                       </logentry>
5783
#
5784
# Inputs          : 
5785
#
5786
# Returns         : 
5787
#
5788
my $entryData;
3967 dpurdie 5789
my $entryActive;
392 dpurdie 5790
sub  ProcessSvnLog
5791
{
5792
    my ($self, $line ) = @_;
3967 dpurdie 5793
    $entryActive = '' unless ( defined $entryActive );
5794
    return unless ( $line );
5795
#print "----- ($entryActive) $line\n";
5796
 
392 dpurdie 5797
    if ( $line =~ m~^<logentry~ ) {
5798
        $entryData = ();
3967 dpurdie 5799
        $entryActive = 'A';
392 dpurdie 5800
 
3967 dpurdie 5801
    } elsif ( ($line =~ s~\s*(.+?)="(.*)">(.*)</path>$~~) && ($entryActive eq 'A') ) {
5802
        #
5803
        #   Last entry has two items
5804
        #       Attribute
5805
        #       Data Item
5806
        #
5807
        $entryData->{$1} = $2;
5808
        $entryData->{target} = $3;
392 dpurdie 5809
 
3967 dpurdie 5810
    } elsif ( ($line =~ m~\s*(.*?)="(.*)"~) && ($entryActive eq 'A') ) {
5811
        #
5812
        #   Attribute
5813
        #
5814
        $entryData->{$1} = $2;
392 dpurdie 5815
 
5816
    } elsif ( $line =~ m~</logentry~ ) {
3967 dpurdie 5817
        $entryActive = '';
5818
        if ( exists $entryData->{'copyfrom-path'} )
392 dpurdie 5819
        {
5820
#            DebugDumpData("Data", $entryData);
5821
            push @svnDataItems, $entryData;
5822
        }
5823
    }
5824
 
5825
    #
5826
    #   Return 0 to keep on going
5827
    return 0;
5828
}
5829
 
1341 dpurdie 5830
#-------------------------------------------------------------------------------
392 dpurdie 5831
# Function        : saveData
5832
#
5833
# Description     : Save essential data
5834
#
5835
# Inputs          : 
5836
#
5837
# Returns         : 
5838
#
5839
sub saveData
5840
{
5841
    my $file = $cwd . "/${packageNames}.data";
5842
 
5843
    Message ("Create: $file");
5844
    my $fh = ConfigurationFile::New( $file );
5845
 
5846
    $fh->DumpData(
5847
        "\n# ScmVersions.\n#\n",
5848
        "ScmVersions", \%versions );
5849
 
5850
    #
5851
    #   Close out the file
5852
    #
5853
    $fh->Close();
5854
}
5855
 
2764 dpurdie 5856
#-------------------------------------------------------------------------------
5857
# Function        : restoreData
5858
#
5859
# Description     : Read in essential information
5860
#                   Used during a resume operation
5861
#
5862
# Inputs          : 
5863
#
5864
# Returns         : 
5865
#
5866
our %ScmVersions;
5867
sub restoreData
5868
{
5869
    my $file = $cwd . "/${packageNames}.data";
5870
    Message ("Restoring: $file");
5871
    Error "Cannot locate restoration file: $file" unless ( -f $file );
5872
    require $file;
392 dpurdie 5873
 
2764 dpurdie 5874
    Error "Resume Data in $file is not valid\n"
5875
        unless ( keys(%ScmVersions) >= 0 );
5876
 
5877
    foreach  ( keys %ScmVersions )
5878
    {
5879
        $restoreData{$_} = $ScmVersions{$_}{data};
5880
        $restoreData{$_}{rmRef} = $ScmVersions{$_}{rmRef};
5881
    }
5882
    %ScmVersions = ();
5883
}
5884
 
392 dpurdie 5885
#-------------------------------------------------------------------------------
2764 dpurdie 5886
# Function        : testSvnLabel
5887
#
5888
# Description     : Test existence of an SVN label
5889
#
5890
# Inputs          :     Package
5891
#                       Label to test
5892
#
5893
# Returns         : 0   - Tag in place
5894
#                   1   - Not in place
5895
#
5896
sub testSvnLabel
5897
{
5898
    my ($svnPkg, $svnTag) = @_;
5899
 
5900
    my $rv = JatsToolPrint ( 'jats_svnlabel',
5901
                    '-check',
5902
                    "-packagebase=$svnPkg",
5903
                    "$svnTag",
5904
                     );
5905
    Message ("testSvnLabel: $svnTag - $rv");
5906
    return $rv;
5907
}
5908
 
5909
 
5910
#-------------------------------------------------------------------------------
392 dpurdie 5911
#   Documentation
5912
#
5913
 
5914
=pod
5915
 
5916
=for htmltoc    SYSUTIL::cc2svn::
5917
 
5918
=head1 NAME
5919
 
5920
cc2svn_gendata - CC2SVN tool to import an entire package into SVN
5921
 
5922
=head1 SYNOPSIS
5923
 
5924
  jats cc2svn_importpackage [options] package_name
5925
 
5926
 Options:
5927
    -help              - brief help message
5928
    -help -help        - Detailed help message
5929
    -man               - Full documentation
5930
    -repository=name   - Specify target repository
5931
    -[no]flat          - Do not create project tree. Def: -noflat
5932
    -prunemode=mode    - Mode: none, ripple, retain, severe, Def=ripple
5933
    -retain=N          - Specify retain count for pruning. Def=2
5934
    -[no]test          - Do not create packages. Def:-notest
5935
    -[no]reuse         - Keep and reuse ClearCase views
5936
    -age=nnDays        - Only keep recent package
5937
    -dump[=n]          - Dump raw data. N=0,1,2
5938
    -images[=n]        - Create SVG of version tree. N=0,1,2
5939
    -name=aaa          - Alternate output package name. Test Only
5940
    -[no]log           - Write output to log file. Def: -nolog
5941
    -[no]postimage     - Create image after transger: Def: -post
5942
    -workdir=path      - Use for temp storage (def:/work)
1270 dpurdie 5943
    -delete            - Delete SVN package before test
2429 dpurdie 5944
    -[no]relabel       - Attempt to relabel dirs in packages that don't extract
2450 dpurdie 5945
    -testRmDatabase    - Use test database
2764 dpurdie 5946
    -[no]fromSvn       - Also extract packages from SVN
3967 dpurdie 5947
    -[no]testRepo      - Force use of a test repository.
5948
    -resume            - Resume aborted import (dangerous)
392 dpurdie 5949
 
5950
=head1 OPTIONS
5951
 
5952
=over 8
5953
 
5954
=item B<-help>
5955
 
5956
Print a brief help message and exits.
5957
 
5958
=item B<-help -help>
5959
 
5960
Print a detailed help message with an explanation for each option.
5961
 
5962
=item B<-man>
5963
 
5964
Prints the manual page and exits.
5965
 
5966
=item B<-prunemode=mode>
5967
 
5968
This option control the manner in which excess versions will be pruned. Valid
5969
modes are:
5970
 
5971
=over 8
5972
 
5973
=item   none
5974
 
5975
No pruning will be performed
5976
 
5977
=item   ripple
5978
 
5979
Non-Essential packages that are ripple builds will be removed.
5980
 
5981
=item   retain
5982
 
5983
Versions that preceed an Essential version will be retained.
5984
 
5985
=item   severe
5986
 
5987
Only Essential Versions, and Branching points will be retained.
5988
 
5989
=back
5990
 
5991
=back
5992
 
5993
=head1 DESCRIPTION
5994
 
5995
This program is a tool used in the conversion of ClearCase VOBS to subversion.
5996
It will take a complete package and all relevent versions from ClearCase and
5997
insert them into subversion in a sessible manner. It will attempt to retain
5998
file change order and history.
5999
 
6000
It will:
6001
 
6002
=over 8
6003
 
6004
=item *
6005
 
6006
Read in the Essential Package Version list.
6007
 
6008
=item *
6009
 
6010
Extract, from Release Manager, all known versions of the specified package.
6011
 
6012
=item *
6013
 
6014
It will attempt to determine the type of package: COTS, TOOL, CORE, PROJECT
6015
and alter the processing accordingly.
6016
 
6017
=item *
6018
 
6019
It will create a version dependency tree and determine 'new' project branch
6020
points. It will remove (prune) versions that are excess to requirements.
6021
 
6022
=item *
6023
 
6024
It will extract source from ClearCase and insert it into SVN, creating
6025
branches and tags as it goes.
6026
 
6027
=back
6028
 
6029
The program can also be used to create a SVG image of the version dependency
6030
tree. This does not work on Linux; only Windows with 'dot' installed.
6031
 
6032
=cut
6033