Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
814 mhunt 1
package com.erggroup.buildtool.ripple;
2
 
3
import java.io.File;
4
 
908 mhunt 5
import java.sql.SQLException;
814 mhunt 6
import java.util.Iterator;
7
import java.util.Vector;
8
 
9
import org.apache.log4j.Logger;
10
 
908 mhunt 11
import com.erggroup.buildtool.smtp.Smtpsend;
12
 
814 mhunt 13
public class Package
14
{
15
  /**name of package, must not contain spaces
16
   * @attribute
17
   */
18
  String mName = new String();
19
 
20
  /**package scope
21
   * @attribute
22
   */
23
  String mExtension = new String();
24
 
25
  /**instance identifier
26
   * @attribute
27
   */
28
  String mVersion = new String();
29
 
30
  /**unique identifier
31
   * for daemon builds = mName + mExtension
32
   * for escrow builds = mName + mVersion + mExtension
33
   * @attribute
34
   */
35
  String mAlias = new String();
36
 
37
  /**clearcase vob location, must not contain spaces
38
   * @attribute
39
   */
40
  String mLocation = new String();
41
 
42
  /**clearcase source file instance identifier
43
   * @attribute
44
   */
45
  String mLabel = new String();
46
 
47
  /**build standards
48
   * @attribute
49
   */
864 mhunt 50
  Vector<BuildStandard> mBuildStandardCollection = new Vector<BuildStandard>();
814 mhunt 51
 
52
  /**GBE_MACHTYPE used to build generic packages for this baseline
53
   * only has meaning in the daemon build, not the escrow build
54
   * accessed by BuildStandard::getPlatform, getBuildStandard
55
   * @attribute
56
   */
57
  public static final String mGenericMachtype = System.getenv("GBE_MACHTYPE");
58
 
59
  /**build dependencies by package alias
60
   * @attribute
61
   */
864 mhunt 62
  Vector<String> mDependencyCollection = new Vector<String>();
814 mhunt 63
 
64
  /**primary package version key pv_id in database
65
   * @attribute
66
   */
67
  int mId;
68
 
69
  /**indication of the nature of change
70
   * @attribute
71
   */
72
  Package.VersionNumberingStandard mChangeType = new VersionNumberingStandard();
73
 
74
  /**determines what field is rippled on a package version whose dependencies have changed
75
   * @attribute
76
   */
77
  Package.VersionNumberingStandard mRippleField = new VersionNumberingStandard();
78
 
79
  /**interested owners
80
   * @attribute
81
   */
864 mhunt 82
  private Vector<String> mBuildFailureEmailCollection = new Vector<String>();
814 mhunt 83
 
84
  /**when true will trigger unit tests as part of the package build phase in daemon mode
85
   * @attribute
86
   */
87
  boolean mHasAutomatedUnitTests = false;
88
 
89
  /**when true, do not ripple this package through packages which are dependent upon it in daemon mode
90
   * @attribute
91
   */
92
  boolean mAdvisoryRipple = false;
93
 
94
  /**determines the build file the package is built in, or not
95
   *  1 buildfile 1 etc
96
   *  0 not yet processed (initial value)
97
   * -1 not reproducible
98
   * -2 not reproducible on the build platforms configured for this release
99
   * -3 do not ripple
100
   * -4 directly dependent on package versions not in the baseline
101
   * -5 indirectly dependent on package versions which are not reproducible
102
   *    because of -1, -2 (escrow), -3 (daemon), -4
103
   * @attribute
104
   */
105
  int mBuildFile = 0;
106
 
107
  /**build dependencies by package
108
   * @attribute
109
   */
864 mhunt 110
  Vector<Package> mPackageDependencyCollection = new Vector<Package>();
814 mhunt 111
 
112
  /**used for escrow build purposes
113
   * set true when a package has been processed
114
   * @attribute
115
   */
116
  boolean mProcessed = false;
117
 
118
  /**set true for WIP package versions
119
   * only used in daemon mode
120
   * @attribute
121
   */
122
  boolean mDirectlyPlanned = false;
123
 
124
  /**set true when it is determined to be ripple built
125
   * @attribute
126
   */
127
  boolean mIndirectlyPlanned = false;
128
 
908 mhunt 129
  /**non zero instruction number when it is determined to be ripple built by force
130
   * @attribute
131
   */
132
  int mForcedRippleInstruction = 0;
133
 
134
  /**non zero instruction number when it is determined to be test built
135
   * @attribute
136
   */
137
  int mTestBuildInstruction = 0;
138
 
139
  /**test build email destination
140
   * @attribute
141
   */
142
  String mTestBuildEmail;
143
 
144
  /**clearcase vob location, must not contain spaces
145
   * @attribute
146
   */
147
  String mTestBuildLocation = new String();
148
 
149
  /**clearcase source file instance identifier
150
   * @attribute
151
   */
152
  String mTestBuildLabel = new String();
153
 
154
  /**build standards
155
   * @attribute
156
   */
157
  Vector<BuildStandard> mTestBuildStandardCollection = new Vector<BuildStandard>();
158
 
159
  /**build dependencies by package alias
160
   * @attribute
161
   */
162
  Vector<String> mTestBuildDependencyCollection = new Vector<String>();
163
 
814 mhunt 164
  /**build dependencies by pv_id (-1 or not used for planned dependencies)
165
   * @attribute
166
   */
864 mhunt 167
  Vector<Integer> mDependencyIDCollection = new Vector<Integer>();
814 mhunt 168
 
169
  /**unique pkg_id in the database
170
   * used for querying package version existence in the database in daemon mode
171
   * @attribute
172
   */
173
  int mPid;
174
 
874 mhunt 175
  /**maximum major number supported for determining ripple number
176
   * @attribute
177
   */
178
  int mMajorLimit;
179
 
180
  /**maximum minor number supported for determining ripple number
181
   * @attribute
182
   */
183
  int mMinorLimit;
184
 
185
  /**maximum patch number supported for determining ripple number
186
   * @attribute
187
   */
188
  int mPatchLimit;
189
 
190
  /**maximum build number number supported for determining ripple number
191
   * @attribute
192
   */
193
  int mBuildLimit;
194
 
814 mhunt 195
  /**Logger
196
   * @attribute
197
   */
198
  private static final Logger mLogger = Logger.getLogger(Package.class);
199
 
200
  /**dpkg archive location
201
   * @attribute
202
   */
203
  public static final String mGbeDpkg = System.getenv("GBE_DPKG");
204
 
205
  /**deploy archive location
206
   * @attribute
207
   */
208
  public static final String mGbeDply = System.getenv("GBE_DPLY");
209
 
896 mhunt 210
  /**Exception message used upon detection an archive does not exist
211
   * Seems this is a rare but transient and recoverable scenario
212
   * @attribute
213
   */
214
  public static final String mRecoverable = "dpkg or deploy_archive do not exist, recovery will be attempted";
215
 
814 mhunt 216
  /**true if the package exists in the dpkg or deploy archive
217
   * @attribute
218
   */
219
  private boolean mArchivalExistence = true;
220
 
852 mhunt 221
  /**when true will trigger source control interaction eg labelling
222
   * @attribute
223
   */
224
  public boolean mRequiresSourceControlInteraction = true;
225
 
814 mhunt 226
  /**constructor
227
   */
228
  Package(int pv_id, String pkg_name, String v_ext, String alias, 
902 mhunt 229
          String pkg_label, String src_path, char change_type, char ripple_field)
814 mhunt 230
  {
231
    mLogger.debug("Package 1: pv_id " + pv_id + " pkg_name " + pkg_name + " v_ext " + v_ext + " alias " + alias + " pkg_label " + pkg_label + " src_path " + src_path + " change_type " + change_type);
232
    mId = pv_id;
233
    mName = pkg_name;
234
    mVersion = "0.0.0000";
235
    mExtension = v_ext;
236
    mAlias = alias;
237
    mLabel = pkg_label;
238
    mLocation = src_path;
239
 
240
    if (change_type == 'M')
241
    {
902 mhunt 242
      // a ripple_field of 'L' indicates this package has limited version numbering
243
      mChangeType.setMajor(ripple_field == 'L' ? true : false);
814 mhunt 244
    }
245
    else if (change_type == 'N')
246
    {
902 mhunt 247
      mChangeType.setMinor(ripple_field == 'L' ? true : false);
814 mhunt 248
    }
249
    else
250
    {
902 mhunt 251
      mChangeType.setPatch(ripple_field == 'L' ? true : false);
814 mhunt 252
    }
253
  }
254
 
255
  /**constructor
256
   */
257
  Package(int pv_id, String pkg_name, String pkg_version, String v_ext, 
258
          String alias, String pkg_label, String src_path, 
259
          char ripple_field)
260
  {
261
    mLogger.debug("Package 2: pv_id " + pv_id + " pkg_name " + pkg_name + " pkg_version " + pkg_version + " v_ext " + v_ext + " alias " + alias + " pkg_label " + pkg_label + " src_path " + src_path + " ripple_field " + ripple_field);
262
    mId = pv_id;
263
    mName = pkg_name;
264
    mVersion = pkg_version;
265
    int endindex = mVersion.length() - v_ext.length();
266
 
267
    if ( endindex > 0 )
268
    {
269
      mVersion = mVersion.substring(0, endindex);
270
    }
271
 
272
    mExtension = v_ext;
273
    mAlias = alias;
274
    mLabel = pkg_label;
275
    mLocation = src_path;
276
 
874 mhunt 277
    // setBuild is the default
814 mhunt 278
    if (ripple_field == 'M')
279
    {
280
      mRippleField.setMajor();
281
    }
282
    else if (ripple_field == 'm')
283
    {
284
      mRippleField.setMinor();
285
    }
286
    else if (ripple_field == 'p')
287
    {
288
      mRippleField.setPatch();
289
    }
874 mhunt 290
    else if (ripple_field == 'L')
291
    {
292
      mRippleField.setLimit();
293
    }
814 mhunt 294
  }
295
 
296
  /**constructor
297
   */
298
  Package()
299
  {
300
    mLogger.debug("Package 3");
301
    mId = 0;
302
    mName = "null";
303
    mExtension = "null";
304
    mAlias = "null";
305
    mLabel = "null";
306
    mLocation = "null";
307
  }
308
 
908 mhunt 309
  /**constructor for test build purposes
310
   */
311
  Package(String pkg_name, String v_ext, String alias, 
312
          String pkg_label, String src_path, int testBuildInstruction, String email)
313
  {
314
    mLogger.debug("Package 4: pkg_name " + pkg_name + " v_ext " + v_ext + " alias " + alias + " pkg_label " + pkg_label + " src_path " + src_path);
315
    // don't need pv_id
316
    mId = -1;
317
    mName = pkg_name;
318
    // avoid interaction with real versions
319
    mVersion = "0.0.0000";
320
    mExtension = v_ext;
321
    mAlias = alias;
322
    mTestBuildInstruction = testBuildInstruction;
323
    mTestBuildEmail = email;
324
    mTestBuildLocation = src_path;
325
    mTestBuildLabel = pkg_label;
326
  }
327
 
328
/**constructor for unit test purposes
874 mhunt 329
  */
330
  public Package(ReleaseManager rm, String version, int majorLimit, int minorLimit, int patchLimit, int buildNumberLimit)
331
  {
332
    mId = -1;
333
    mRippleField.setLimit();
334
    mVersion = version;
335
    mMajorLimit = majorLimit;
336
    mMinorLimit = minorLimit;
337
    mPatchLimit = patchLimit;
338
    mBuildLimit = buildNumberLimit;
339
    try
340
    {
341
      mId = applyPV( rm, 0 );
342
    }
343
    catch(Exception e)
344
    {
345
    }
346
  }
347
 
348
  /**accessor for unit test purposes
349
   */
350
  public int getId()
351
  {
352
    return mId;
353
  }
354
 
355
  /**accessor for unit test purposes
356
   */
357
  public String getVersion()
358
  {
359
    return mVersion;
360
  }
361
 
814 mhunt 362
  /**returns true if mBuildStandardCollection is not empty
363
   */
364
  boolean isReproducible()
365
  {
366
    mLogger.debug("isReproducible on Package " + mName);
367
    boolean retVal = false;
368
 
369
    if ( mBuildStandardCollection.size() > 0 )
370
    {
371
      retVal = true;
372
    }
373
 
374
    mLogger.info("isReproducible returned " + retVal);
375
    return retVal;
376
  }
377
 
378
  /**returns true if at least one of its BuildStandards has mWin32 or mGeneric true
379
   */
380
  boolean isWin32Built()
381
  {
382
    mLogger.debug("isWin32Built on Package " + mName);
383
    boolean retVal = false;
864 mhunt 384
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 385
    {
864 mhunt 386
      BuildStandard buildStandard = it.next();
814 mhunt 387
 
388
      if (buildStandard.getWin32() || buildStandard.getGeneric())
389
      {
390
        retVal = true;
391
        break;
392
      }
393
    }
394
 
395
    mLogger.info("isWin32Built returned " + retVal);
396
    return retVal;
397
  }
398
 
399
  /**returns true if at least one of its BuildStandards has mSolaris or mGeneric true
400
   */
401
  boolean isSolarisBuilt()
402
  {
403
    mLogger.debug("isSolarisBuilt on Package " + mName);
404
    boolean retVal = false;
864 mhunt 405
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 406
    {
864 mhunt 407
      BuildStandard buildStandard = it.next();
814 mhunt 408
 
409
      if (buildStandard.getSolaris() || buildStandard.getGeneric())
410
      {
411
        retVal = true;
412
        break;
413
      }
414
    }
415
 
416
    mLogger.info("isSolarisBuilt returned " + retVal);
417
    return retVal;
418
  }
419
 
420
  /**returns true if at least one of its BuildStandards has mLinux or mGeneric true
421
   */
422
  boolean isLinuxBuilt()
423
  {
424
    mLogger.debug("isLinuxBuilt on Package " + mName);
425
    boolean retVal = false;
864 mhunt 426
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 427
    {
864 mhunt 428
      BuildStandard buildStandard = it.next();
814 mhunt 429
 
430
      if (buildStandard.getLinux() || buildStandard.getGeneric())
431
      {
432
        retVal = true;
433
        break;
434
      }
435
    }
436
 
437
    mLogger.info("isLinuxBuilt returned " + retVal);
438
    return retVal;
439
  }
440
 
441
  /**returns true if at least one of its BuildStandards has mGeneric true
442
   */
443
  boolean isGeneric()
444
  {
445
    mLogger.debug("isGeneric on Package " + mName);
446
    boolean retVal = false;
864 mhunt 447
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 448
    {
864 mhunt 449
      BuildStandard buildStandard = it.next();
814 mhunt 450
 
451
      if (buildStandard.getGeneric())
452
      {
453
        retVal = true;
454
        break;
455
      }
456
    }
457
 
458
    mLogger.info("isGeneric returned " + retVal);
459
    return retVal;
460
  }
461
 
462
  /**applies the required version number change
874 mhunt 463
   * returns 0 on success
464
   *         1 on cannot work with non standard versioning
465
   *         2 on ripple field limitations prevent a ripple build
814 mhunt 466
   */
874 mhunt 467
  int applyPV(ReleaseManager releaseManager, int rtag_id) throws Exception
814 mhunt 468
  {
469
    mLogger.debug("applyPV on Package " + mName);
908 mhunt 470
    // four scenarios, only applyPV for 3 of them
471
    // WIP/test build exists:           mDirectlyPlanned == true;   mIndirectlyPlanned == true; mArchivalExistence don't care; mForcedRipple don't care - applyPV
472
    // Package version is out of date:  mDirectlyPlanned == false;  mIndirectlyPlanned == true; mArchivalExistence == true;    mForcedRipple don't care - applyPV
473
    // Forced ripple:                   mDirectlyPlanned == false;  mIndirectlyPlanned == true; mArchivalExistence don't care; mForcedRipple > 0        - applyPV
474
    // Package version does not exist:  mDirectlyPlanned == false;  mIndirectlyPlanned == true; mArchivalExistence == false;   mForcedRipple = 0    - do not applyPV
475
    if ( !mDirectlyPlanned && mIndirectlyPlanned && !mArchivalExistence && mForcedRippleInstruction == 0 )
814 mhunt 476
    {
477
      // the package has an mIndirectlyPlanned flag set true in daemon mode because the package does not exist in an archive
478
      // do not apply a different package version
908 mhunt 479
      mLogger.info("applyPV !mDirectlyPlanned && mIndirectlyPlanned && !mArchivalExistence && zero mForcedRippleInstruction on Package " + mName);
836 mhunt 480
      releaseManager.claimVersion(mPid, mVersion + mExtension, rtag_id);
874 mhunt 481
      mLogger.info("applyPv returned 0");
482
      return 0;
814 mhunt 483
    }
908 mhunt 484
 
485
    // override - no longer doing a rebuild - version number change from this point on
486
    if ( mTestBuildInstruction == 0 )
487
    {
488
      mRequiresSourceControlInteraction = true;
489
    }
814 mhunt 490
 
892 mhunt 491
    MutableInt major = new MutableInt();
492
    major.value = 0;
493
    MutableInt minor = new MutableInt();
494
    minor.value = 0;
495
    MutableInt patch = new MutableInt();
496
    patch.value = 1000;
814 mhunt 497
 
498
    String field[] = mVersion.split("\\D");
888 mhunt 499
    String nonStandardCotsVersion = "";
500
 
814 mhunt 501
    if ( field.length == 3 )
502
    {
892 mhunt 503
      major.value = Integer.parseInt(field[0]);
504
      minor.value = Integer.parseInt(field[1]);
505
      patch.value = Integer.parseInt(field[2]);
814 mhunt 506
    }
507
    else
508
    {
888 mhunt 509
      if ( !mChangeType.mMajor &&
510
           !mChangeType.mMinor &&
511
           !mChangeType.mPatch &&
512
           mRippleField.mBuild &&
513
           mExtension.compareTo(".cots") == 0 &&
514
           field.length > 0 )
515
      {
516
        // DEVI 52782
517
        // allow and work with (ripple build) versions a.b.c.d....xxxx
518
        // where xxxx.length > 3
519
        String patchStr = field[field.length - 1];
520
        int patchLen = patchStr.length();
521
 
522
        // check patchStr is the last (at least 4) digits
523
        if ( patchLen > 3 && mVersion.substring( mVersion.length() - patchLen, mVersion.length() ).compareTo(patchStr) == 0 )
524
        {
892 mhunt 525
          patch.value = Integer.parseInt(patchStr);
888 mhunt 526
          nonStandardCotsVersion = mVersion.substring(0, mVersion.length() - patchLen );
527
        }
528
      }
529
 
530
      if ( nonStandardCotsVersion.length() == 0 )
531
      {
532
        // cannot work with non standard versioning
533
        mLogger.error("applyPV cannot work with non standard versioning");
534
        mLogger.info("applyPv returned 1");
535
        return 1;
536
      }
814 mhunt 537
    }
538
 
888 mhunt 539
    if ( nonStandardCotsVersion.length() == 0 &&
892 mhunt 540
         patch.value < 1000 && 
888 mhunt 541
         field[2].substring(0, 1).compareTo("0") != 0 )
814 mhunt 542
    {
543
      mLogger.info("applyPV accomodate old style mVersion of the form 1.0.1");
892 mhunt 544
      patch.value = patch.value * 1000;
814 mhunt 545
    }
546
 
547
    // mChangeType overrides mRippleField
548
    do
549
    {
550
      if ( mChangeType.mMajor )
551
      {
892 mhunt 552
        if ( !incrementFieldsAccordingToLimits(4, major, minor, patch) )
553
        {
554
          mLogger.info("applyPv returned 2");
555
          return 2;
556
        }
814 mhunt 557
      }
558
      else if ( mChangeType.mMinor )
559
      {
892 mhunt 560
        if ( !incrementFieldsAccordingToLimits(3, major, minor, patch) )
561
        {
562
          mLogger.info("applyPv returned 2");
563
          return 2;
564
        }
814 mhunt 565
      }
566
      else if ( mChangeType.mPatch )
567
      {
892 mhunt 568
        if ( !incrementFieldsAccordingToLimits(2, major, minor, patch) )
814 mhunt 569
        {
892 mhunt 570
          mLogger.info("applyPv returned 2");
571
          return 2;
572
        }
814 mhunt 573
      }
574
      else
575
      {
576
        if ( mRippleField.mMajor )
577
        {
892 mhunt 578
          major.value++;
579
          mLogger.info("applyPV mRippleField.mMajor " + major.value);
580
          minor.value = 0;
581
          patch.value = 0;
814 mhunt 582
        }
583
        else if ( mRippleField.mMinor )
584
        {
892 mhunt 585
          minor.value++;
586
          mLogger.info("applyPV mRippleField.mMinor " + minor.value);
587
          patch.value = 0;
814 mhunt 588
        }
589
        else if ( mRippleField.mPatch )
590
        {
591
          do
592
          {
892 mhunt 593
            patch.value++;
594
          } while ( ( patch.value / 1000 ) * 1000 != patch.value );
595
          mLogger.info("applyPV mRippleField.mPatch " + patch.value);
814 mhunt 596
        }
874 mhunt 597
        else if ( mRippleField.mBuild )
814 mhunt 598
        {
892 mhunt 599
          patch.value++;
600
          mLogger.info("applyPV mRippleField.mBuild " + patch.value);
814 mhunt 601
        }
874 mhunt 602
        else
603
        {
892 mhunt 604
          if ( !incrementFieldsAccordingToLimits(1, major, minor, patch) )
874 mhunt 605
          {
606
            mLogger.info("applyPv returned 2");
607
            return 2;
608
          }
609
        }
814 mhunt 610
      }
888 mhunt 611
 
612
      if ( nonStandardCotsVersion.length() == 0 )
613
      {
892 mhunt 614
        mVersion = String.valueOf(major.value) + "." + String.valueOf(minor.value) + ".";
888 mhunt 615
      }
616
      else
617
      {
618
        mVersion = nonStandardCotsVersion;
619
      }
814 mhunt 620
 
892 mhunt 621
      if ( patch.value < 10 )
814 mhunt 622
      {
623
        mVersion += "000";
624
      }
892 mhunt 625
      else if ( patch.value < 100 )
814 mhunt 626
      {
627
        mVersion += "00";
628
      }
892 mhunt 629
      else if ( patch.value < 1000 )
814 mhunt 630
      {
631
        mVersion += "0";
632
      }
633
 
892 mhunt 634
      mVersion += String.valueOf(patch.value);
814 mhunt 635
    } while ( exists(releaseManager, rtag_id) );
636
 
637
    releaseManager.claimVersion(mPid, mVersion + mExtension, rtag_id);
874 mhunt 638
    mLogger.info("applyPv returned 0");
639
    return 0;
814 mhunt 640
  }
641
 
892 mhunt 642
  /**increments fields according to mRippleField.mLimit if necessary
643
   * will apply it to the field passed as follows
644
   * 1 = build
645
   * 2 = patch
646
   * 3 = minor
647
   * other = major
648
   * returns true on success
649
   *         false on ripple field limitations prevent a ripple build
650
   */
651
  private boolean incrementFieldsAccordingToLimits(int field, MutableInt major, MutableInt minor, MutableInt patch)
652
  {
653
    boolean retVal = true;
654
 
902 mhunt 655
    if (!mChangeType.mLimit && !mRippleField.mLimit)
892 mhunt 656
    {
657
      // simple case
658
      // no need to take field limits into consideration
659
      switch (field)
660
      {
661
      case 1:
662
        // unreachable
663
        // the only scenario involving build number manipulation involves the mRippleField.mLimit being set
664
        retVal = false;
665
        break;
666
      case 2:
667
        do
668
        {
669
          patch.value++;
670
        } while ( ( patch.value / 1000 ) * 1000 != patch.value );
671
        mLogger.info("incrementFieldsAccordingToLimits patch " + patch.value);
672
        break;
673
      case 3:
674
        minor.value++;
675
        mLogger.info("incrementFieldsAccordingToLimits minor " + minor.value);
676
        patch.value = 0;
677
        break;
678
      default:
679
        major.value++;
680
        mLogger.info("incrementFieldsAccordingToLimits major " + major.value);
681
        minor.value = 0;
682
        patch.value = 0;
683
      }
684
    }
685
    else
686
    {
687
      // take field limits into consideration
688
      boolean changeOccurred = false;
689
      boolean incrementField = true;
690
 
691
      switch (field)
692
      {
693
      case 1:
694
        if ( mBuildLimit != 0 )
695
        {
696
          // increment or reset the patch build number
697
          int buildNumber = patch.value - (patch.value/1000) * 1000;
698
 
699
          if ( buildNumber < mBuildLimit )
700
          {
701
            // can increment the patch build number
702
            patch.value++;
703
            mLogger.info("incrementFieldsAccordingToLimits mRippleField.mLimit build number " + patch.value);
704
            changeOccurred = true;
705
            incrementField = false;
706
          }
707
          else
708
          {
709
            if ( mPatchLimit == 0 )
710
            {
711
              // reset the patch number and patch build number
712
              patch.value = 0;
713
            }
714
          }
715
        }
716
        // no break by design
717
      case 2:
718
        if ( mPatchLimit != 0 && incrementField )
719
        {
720
          // increment or reset the patch number
721
          if ( ( patch.value / 1000 ) < mPatchLimit )
722
          {
723
            do
724
            {
725
              patch.value++;
726
            } while ( ( patch.value / 1000 ) * 1000 != patch.value );
727
 
728
            mLogger.info("incrementFieldsAccordingToLimits mRippleField.mLimit patch " + patch.value);
729
            changeOccurred = true;
730
            incrementField = false;
731
          }
732
          else
733
          {
734
            // reset the patch number and patch build number
735
            patch.value = 0;
736
          }
737
        }
738
        // no break by design
739
      case 3:
740
        if ( mMinorLimit != 0 && incrementField )
741
        {
742
          // increment or reset the minor number
743
          if ( minor.value < mMinorLimit )
744
          {
745
            minor.value++;
746
            patch.value = 0;
747
            mLogger.info("incrementFieldsAccordingToLimits mRippleField.mLimit minor " + minor.value);
748
            changeOccurred = true;
749
            incrementField = false;
750
          }
751
          else
752
          {
753
            // reset the minor number
754
            minor.value = 0;
755
          }
756
        }
757
        // no break by design
758
      default:
759
        if ( mMajorLimit != 0 && incrementField )
760
        {
761
          // increment or reset the major number
762
          if ( major.value < mMajorLimit )
763
          {
764
            // increment the major number
765
            changeOccurred = true;
766
            major.value++;
767
            minor.value = 0;
768
            patch.value = 0;
769
            mLogger.info("incrementFieldsAccordingToLimits mRippleField.mLimit major " + major.value);
770
          }
771
        }
772
      }
773
 
774
      if ( !changeOccurred )
775
      {
776
        // unable to increment a field due to field limitations
777
        mLogger.error("incrementFieldsAccordingToLimits ripple field limitations prevent a ripple build");
778
        mLogger.info("incrementFieldsAccordingToLimits returned false");
779
        retVal = false;
780
      }
781
    }
782
 
783
    return retVal;
784
  }
785
 
814 mhunt 786
  /**returns true if the version exists in the dpkg_archive, deploy_archive or release manager database
787
   * claims the version in the release manager database
788
   */
789
  private boolean exists(ReleaseManager releaseManager, int rtag_id) throws Exception
790
  {
791
    mLogger.debug("exists 1 on Package " + mName + " version " + mVersion + " extension " + mExtension);
792
    boolean retVal = false;
793
 
864 mhunt 794
    if ( !ReleaseManager.mUseDatabase )
814 mhunt 795
    {
796
      mLogger.info("exists 1 !releaseManager.mUseDatabase");
797
    }
798
    else
799
    {
800
      retVal = exists();
801
 
802
      if ( !retVal )
803
      {
804
        String pkg_version = new String(mVersion);
805
 
806
        if ( mExtension.length() > 0 )
807
        {
808
          pkg_version += mExtension;
809
        }
810
 
811
        retVal = releaseManager.queryPackageVersions(mPid, pkg_version);
812
      }
813
    }
814
 
815
    mLogger.info("exists 1 returned " + retVal);
816
    return retVal;
817
  }
818
 
896 mhunt 819
  /**returns true if the dpkg_archive and deploy_archive exist
820
   * attempt to recover from their transient loss 
821
   */
822
  public static boolean recover()
823
  {
824
    mLogger.debug("recover");
825
    boolean retVal = false;
826
 
827
    String Release = mGbeDpkg;
828
    String Deploy = mGbeDply;
829
 
830
    if (Release != null && Deploy != null)
831
    {
832
      File dpkg = new File(mGbeDpkg);
833
      File dply = new File(mGbeDply);
834
 
835
      if ( dpkg.exists() && dply.exists() )
836
      {
837
        retVal = true;
838
      }
839
    }
840
 
841
    mLogger.info("recover returned " + retVal);
842
    return retVal;
843
  }
844
 
814 mhunt 845
  /**returns true if the version exists in the dpkg_archive or deploy_archive
846
   */
847
  boolean exists()
848
    throws Exception
849
  {
850
    mLogger.debug("exists 2 on Package " + mName);
851
    boolean retVal = false;
852
 
853
    String Release = mGbeDpkg;
854
    String Deploy = mGbeDply;
855
 
856
    if (Release == null || Deploy == null)
857
    {
868 mhunt 858
      mLogger.fatal("exists 2 Release == null || Deploy == null");
859
      throw new Exception("exists 2 Release == null || Deploy == null");
814 mhunt 860
    }
896 mhunt 861
 
862
    File dpkg = new File(mGbeDpkg);
863
    File dply = new File(mGbeDply);
864
 
865
    if ( !dpkg.exists() || !dply.exists() )
866
    {
867
      mLogger.fatal("exists 2 " + mRecoverable);
868
      throw new Exception(mRecoverable);
869
    }
814 mhunt 870
 
871
    String fs = System.getProperty( "file.separator" );
872
    String name = new String(Release);
873
    name += fs + mName + fs + mVersion + mExtension;
874
    File release = new File(name);
875
 
876
    if (release.exists())
877
    {
878
      mLogger.info("exists 2 release.exists()");
879
      retVal = true;
880
    }
881
 
882
    if (!retVal && (Release != Deploy))
883
    {
884
      name = Deploy + fs + mName + fs + mVersion + mExtension;
885
 
886
      File deploy = new File(name);
887
 
888
      if (deploy.exists())
889
      {
890
        mLogger.info("exists 2 deploy.exists()");
891
        retVal = true;
892
      }
893
    }
894
 
895
    mArchivalExistence = retVal;
896
    mLogger.info("exists 2 returned " + retVal);
897
    return retVal;
898
  }
854 mhunt 899
 
900
  /**returns email information
901
   */
902
  String emailInfo( String lf )
903
  {
904
    String retVal = new String();
905
 
864 mhunt 906
    for (Iterator<String> it = mBuildFailureEmailCollection.iterator(); it.hasNext(); )
854 mhunt 907
    {
864 mhunt 908
      String email = it.next();
854 mhunt 909
      retVal +=
910
      "  <owner email=\"" + email +"\"/>" + lf;
911
    }
912
 
913
    return retVal;
914
  }
814 mhunt 915
 
866 mhunt 916
  /**returns email information
917
   */
918
  String emailInfoNonAntTask()
919
  {
920
    String retVal = null;
921
 
922
    for (Iterator<String> it = mBuildFailureEmailCollection.iterator(); it.hasNext(); )
923
    {
924
      String email = it.next();
925
 
926
      if ( retVal == null )
927
      {
928
        retVal = new String();
929
      }
930
      else
931
      {
932
        retVal += ",";
933
      }
934
      retVal += email;
935
    }
936
 
937
    return retVal;
938
  }
939
 
864 mhunt 940
  /**adds email to mBuildFailureEmailCollection if unique
941
   */
942
  void addEmail( String email )
943
  {
944
    boolean alreadyExists = false;
945
 
946
    for (Iterator<String> it = mBuildFailureEmailCollection.iterator(); it.hasNext(); )
947
    {
948
      String existingEmail = it.next();
949
 
950
      if ( existingEmail.compareTo(email) == 0 )
951
      {
952
        alreadyExists = true;
953
        break;
954
      }
955
    }
956
 
957
    if ( !alreadyExists )
958
    {
959
      mBuildFailureEmailCollection.add(email);
960
    }
961
  }
962
 
908 mhunt 963
  /**accessor method
964
   */
965
  void setEmail()
966
  {
967
    mBuildFailureEmailCollection.clear();
968
    addEmail( mTestBuildEmail );
969
  }
970
 
971
  /**accessor method
972
   */
973
  void setDependencyCollection()
974
  {
975
    // does not worry about mPackageDendencyCollection by design
976
    mDependencyCollection.clear();
977
 
978
    for (Iterator<String> it = mTestBuildDependencyCollection.iterator(); it.hasNext(); )
979
    {
980
      String dependency = it.next();
981
      mDependencyCollection.add(dependency);
982
    }
983
  }
984
 
985
  /**accessor method
986
   */
987
  void setBuildStandardCollection()
988
  {
989
    mBuildStandardCollection.clear();
990
 
991
    for (Iterator<BuildStandard> it = mTestBuildStandardCollection.iterator(); it.hasNext(); )
992
    {
993
      BuildStandard buildStandard = it.next();
994
      mBuildStandardCollection.add(buildStandard);
995
    }
996
  }
997
 
998
  /**sends email notification and marks the instruction complete in the database
999
   */
1000
  public void completeTestBuild( String mailServer, String mailSender, ReleaseManager releaseManager, String release, boolean success ) throws SQLException, Exception
1001
  {
1002
    mLogger.debug("completeTestBuild");
1003
 
1004
    if ( mTestBuildInstruction == 0)
1005
    {
1006
      return;
1007
    }
1008
 
1009
    String mailBody="Test build issues are identified in preceding build failure email.<p>" +
1010
                    "Release: " + release + "<br>" +
1011
                    "Package: " + mAlias + "<br>" +
1012
                    "Label: " + mLabel + "<br>" +
1013
                    "Location: " + mLocation + "<p>" +
1014
                    "Build dependencies:<p>";
1015
 
1016
    for (Iterator<Package> it3 = mPackageDependencyCollection.iterator(); it3.hasNext(); )
1017
    {
1018
      Package depend = it3.next();
1019
 
1020
      String dependsExtension = depend.mExtension;
1021
      String dependsVersion = depend.mVersion;
1022
 
1023
      if ( dependsExtension.length() > 0 )
1024
      {
1025
        dependsVersion += dependsExtension;
1026
      }
1027
      mailBody += "\'" + depend.mName + "\',\'" + dependsVersion + "\' <br>";
1028
    }
1029
 
1030
    mailBody += "<br>Build standards:<p>";
1031
 
1032
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
1033
    {
1034
      BuildStandard bs = it.next();
1035
 
1036
      String platform = bs.getPlatform(!ReleaseManager.mUseDatabase, false);
1037
 
1038
      if ( platform.length() > 0 )
1039
      {
1040
        mailBody += platform + ", ";
1041
      }
1042
 
1043
      String standard = bs.getBuildStandard(!ReleaseManager.mUseDatabase, false);
1044
 
1045
      if ( standard.length() > 0 )
1046
      {
1047
        mailBody += standard + "<br>";
1048
      }
1049
    }
1050
 
1051
    try
1052
    {
1053
      Smtpsend.send(
1054
      mailServer, // mailServer
1055
      mailSender, // source
1056
      emailInfoNonAntTask(), // target
1057
      null, // cc
1058
      null, // bcc
1059
      success == true ? "TEST BUILD COMPLETED SUCCESSFULLY" : "TEST BUILD FAILED", // subject
1060
      mailBody, // body
1061
      null // attachment
1062
      );
1063
    }
1064
    catch( Exception e )
1065
    {
1066
    }
1067
 
1068
    releaseManager.markDaemonInstCompletedConnect(mTestBuildInstruction);
1069
  }
1070
 
814 mhunt 1071
  /**entity class supporting the ERG version numbering standard:
1072
   * <major>.<minor>.<patch/build>
1073
   * patch/build is at least a 4 digit number whose last 3 digits represent the build
1074
   */
1075
  public class VersionNumberingStandard
1076
  {
1077
    /**in terms of the mChangeType Package field,
1078
     * when true indicates the contract of the package has changed in a non backwardly compatible manner
1079
     * in terms of the mRippleField Package field,
1080
     * when true indicates the major version number will be incremented
1081
     * @attribute
1082
     */
1083
    private boolean mMajor = false;
1084
 
1085
    /**in terms of the mChangeType Package field,
1086
     * when true indicates the contract of the package has changed in a backwardly compatible manner
1087
     * in terms of the mRippleField Package field,
1088
     * when true indicates the minor version number will be incremented
1089
     * @attribute
1090
     */
1091
    private boolean mMinor = false;
1092
 
1093
    /**in terms of the mChangeType Package field,
1094
     * when true indicates the contract of the package has not changed, but the package has changed internally
1095
     * in terms of the mRippleField Package field,
1096
     * when true indicates the minor version number will be incremented
1097
     * @attribute
1098
     */
1099
    private boolean mPatch = false;
1100
 
1101
    /**in terms of the mChangeType Package field,
1102
     * when true indicates the package has not changed, its dependencies potentially have
1103
     * in terms of the mRippleField Package field,
1104
     * when true indicates the build number will be incremented
1105
     * @attribute
1106
     */
1107
    private boolean mBuild = true;
1108
 
874 mhunt 1109
    /**in terms of the mChangeType Package field,
902 mhunt 1110
     * when true indicates the major, minor, and patch number will be incremented according to field limits
874 mhunt 1111
     * in terms of the mRippleField Package field,
1112
     * when true indicates the major, minor, patch and build number will be incremented according to field limits
1113
     * @attribute
1114
     */
1115
    private boolean mLimit = false;
1116
 
814 mhunt 1117
    /**constructor
1118
     */
1119
    private VersionNumberingStandard()
1120
    {
1121
      mLogger.debug("VersionNumberingStandard");
1122
    }
1123
 
874 mhunt 1124
    /**sets mBuild true, mMajor false, mMinor false, mPatch false, mLimit false
814 mhunt 1125
     */
1126
    void setBuild()
1127
    {
1128
      mLogger.debug("setBuild");
1129
      mBuild = true;
1130
      mMajor = false;
1131
      mMinor = false;
1132
      mPatch = false;
874 mhunt 1133
      mLimit = false;
814 mhunt 1134
    }
1135
 
874 mhunt 1136
    /**sets mBuild false, mMajor true, mMinor false, mPatch false, mLimit false
814 mhunt 1137
     */
1138
    void setMajor()
1139
    {
1140
      mLogger.debug("setMajor");
1141
      mBuild = false;
1142
      mMajor = true;
1143
      mMinor = false;
1144
      mPatch = false;
874 mhunt 1145
      mLimit = false;
814 mhunt 1146
    }
1147
 
902 mhunt 1148
    /**sets mBuild false, mMajor true, mMinor false, mPatch false, mLimit limit
1149
     */
1150
    void setMajor( boolean limit )
1151
    {
1152
      mLogger.debug("setMajor " + limit);
1153
      mBuild = false;
1154
      mMajor = true;
1155
      mMinor = false;
1156
      mPatch = false;
1157
      mLimit = limit;
1158
    }
1159
 
874 mhunt 1160
    /**sets mBuild false, mMajor false, mMinor true, mPatch false, mLimit false
814 mhunt 1161
     */
1162
    void setMinor()
1163
    {
1164
      mLogger.debug("setMinor");
1165
      mBuild = false;
1166
      mMajor = false;
1167
      mMinor = true;
1168
      mPatch = false;
874 mhunt 1169
      mLimit = false;
814 mhunt 1170
    }
1171
 
902 mhunt 1172
    /**sets mBuild false, mMajor false, mMinor true, mPatch false, mLimit limit
1173
     */
1174
    void setMinor( boolean limit )
1175
    {
1176
      mLogger.debug("setMinor " + limit);
1177
      mBuild = false;
1178
      mMajor = false;
1179
      mMinor = true;
1180
      mPatch = false;
1181
      mLimit = limit;
1182
    }
1183
 
874 mhunt 1184
    /**sets mBuild false, mMajor false, mMinor false, mPatch true, mLimit false
814 mhunt 1185
     */
1186
    void setPatch()
1187
    {
1188
      mLogger.debug("setPatch");
1189
      mBuild = false;
1190
      mMajor = false;
1191
      mMinor = false;
1192
      mPatch = true;
874 mhunt 1193
      mLimit = false;
814 mhunt 1194
    }
1195
 
902 mhunt 1196
    /**sets mBuild false, mMajor false, mMinor false, mPatch true, mLimit limit
1197
     */
1198
    void setPatch( boolean limit )
1199
    {
1200
      mLogger.debug("setPatch");
1201
      mBuild = false;
1202
      mMajor = false;
1203
      mMinor = false;
1204
      mPatch = true;
1205
      mLimit = limit;
1206
    }
1207
 
874 mhunt 1208
    /**sets mBuild false, mMajor false, mMinor false, mPatch false, mLimit true
1209
     */
1210
    void setLimit()
1211
    {
1212
      mLogger.debug("setPatch");
1213
      mBuild = false;
1214
      mMajor = false;
1215
      mMinor = false;
1216
      mPatch = false;
1217
      mLimit = true;
1218
    }
1219
 
814 mhunt 1220
  }
1221
 
1222
}