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
 
5
import java.util.Iterator;
6
import java.util.Vector;
7
 
8
import org.apache.log4j.Logger;
9
 
10
public class Package
11
{
12
  /**name of package, must not contain spaces
13
   * @attribute
14
   */
15
  String mName = new String();
16
 
17
  /**package scope
18
   * @attribute
19
   */
20
  String mExtension = new String();
21
 
22
  /**instance identifier
23
   * @attribute
24
   */
25
  String mVersion = new String();
26
 
27
  /**unique identifier
28
   * for daemon builds = mName + mExtension
29
   * for escrow builds = mName + mVersion + mExtension
30
   * @attribute
31
   */
32
  String mAlias = new String();
33
 
34
  /**clearcase vob location, must not contain spaces
35
   * @attribute
36
   */
37
  String mLocation = new String();
38
 
39
  /**clearcase source file instance identifier
40
   * @attribute
41
   */
42
  String mLabel = new String();
43
 
44
  /**build standards
45
   * @attribute
46
   */
864 mhunt 47
  Vector<BuildStandard> mBuildStandardCollection = new Vector<BuildStandard>();
814 mhunt 48
 
49
  /**GBE_MACHTYPE used to build generic packages for this baseline
50
   * only has meaning in the daemon build, not the escrow build
51
   * accessed by BuildStandard::getPlatform, getBuildStandard
52
   * @attribute
53
   */
54
  public static final String mGenericMachtype = System.getenv("GBE_MACHTYPE");
55
 
56
  /**build dependencies by package alias
57
   * @attribute
58
   */
864 mhunt 59
  Vector<String> mDependencyCollection = new Vector<String>();
814 mhunt 60
 
61
  /**primary package version key pv_id in database
62
   * @attribute
63
   */
64
  int mId;
65
 
66
  /**indication of the nature of change
67
   * @attribute
68
   */
69
  Package.VersionNumberingStandard mChangeType = new VersionNumberingStandard();
70
 
71
  /**determines what field is rippled on a package version whose dependencies have changed
72
   * @attribute
73
   */
74
  Package.VersionNumberingStandard mRippleField = new VersionNumberingStandard();
75
 
76
  /**interested owners
77
   * @attribute
78
   */
864 mhunt 79
  private Vector<String> mBuildFailureEmailCollection = new Vector<String>();
814 mhunt 80
 
81
  /**when true will trigger unit tests as part of the package build phase in daemon mode
82
   * @attribute
83
   */
84
  boolean mHasAutomatedUnitTests = false;
85
 
86
  /**when true, do not ripple this package through packages which are dependent upon it in daemon mode
87
   * @attribute
88
   */
89
  boolean mAdvisoryRipple = false;
90
 
91
  /**determines the build file the package is built in, or not
92
   *  1 buildfile 1 etc
93
   *  0 not yet processed (initial value)
94
   * -1 not reproducible
95
   * -2 not reproducible on the build platforms configured for this release
96
   * -3 do not ripple
97
   * -4 directly dependent on package versions not in the baseline
98
   * -5 indirectly dependent on package versions which are not reproducible
99
   *    because of -1, -2 (escrow), -3 (daemon), -4
100
   * @attribute
101
   */
102
  int mBuildFile = 0;
103
 
104
  /**build dependencies by package
105
   * @attribute
106
   */
864 mhunt 107
  Vector<Package> mPackageDependencyCollection = new Vector<Package>();
814 mhunt 108
 
109
  /**used for escrow build purposes
110
   * set true when a package has been processed
111
   * @attribute
112
   */
113
  boolean mProcessed = false;
114
 
115
  /**set true for WIP package versions
116
   * only used in daemon mode
117
   * @attribute
118
   */
119
  boolean mDirectlyPlanned = false;
120
 
121
  /**set true when it is determined to be ripple built
122
   * @attribute
123
   */
124
  boolean mIndirectlyPlanned = false;
125
 
126
  /**build dependencies by pv_id (-1 or not used for planned dependencies)
127
   * @attribute
128
   */
864 mhunt 129
  Vector<Integer> mDependencyIDCollection = new Vector<Integer>();
814 mhunt 130
 
131
  /**unique pkg_id in the database
132
   * used for querying package version existence in the database in daemon mode
133
   * @attribute
134
   */
135
  int mPid;
136
 
137
  /**Logger
138
   * @attribute
139
   */
140
  private static final Logger mLogger = Logger.getLogger(Package.class);
141
 
142
  /**dpkg archive location
143
   * @attribute
144
   */
145
  public static final String mGbeDpkg = System.getenv("GBE_DPKG");
146
 
147
  /**deploy archive location
148
   * @attribute
149
   */
150
  public static final String mGbeDply = System.getenv("GBE_DPLY");
151
 
152
  /**true if the package exists in the dpkg or deploy archive
153
   * @attribute
154
   */
155
  private boolean mArchivalExistence = true;
156
 
852 mhunt 157
  /**when true will trigger source control interaction eg labelling
158
   * @attribute
159
   */
160
  public boolean mRequiresSourceControlInteraction = true;
161
 
814 mhunt 162
  /**constructor
163
   */
164
  Package(int pv_id, String pkg_name, String v_ext, String alias, 
165
          String pkg_label, String src_path, char change_type)
166
  {
167
    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);
168
    mId = pv_id;
169
    mName = pkg_name;
170
    mVersion = "0.0.0000";
171
    mExtension = v_ext;
172
    mAlias = alias;
173
    mLabel = pkg_label;
174
    mLocation = src_path;
175
 
176
    if (change_type == 'M')
177
    {
178
      mChangeType.setMajor();
179
    }
180
    else if (change_type == 'N')
181
    {
182
      mChangeType.setMinor();
183
    }
184
    else
185
    {
186
      mChangeType.setPatch();
187
    }
188
  }
189
 
190
  /**constructor
191
   */
192
  Package(int pv_id, String pkg_name, String pkg_version, String v_ext, 
193
          String alias, String pkg_label, String src_path, 
194
          char ripple_field)
195
  {
196
    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);
197
    mId = pv_id;
198
    mName = pkg_name;
199
    mVersion = pkg_version;
200
    int endindex = mVersion.length() - v_ext.length();
201
 
202
    if ( endindex > 0 )
203
    {
204
      mVersion = mVersion.substring(0, endindex);
205
    }
206
 
207
    mExtension = v_ext;
208
    mAlias = alias;
209
    mLabel = pkg_label;
210
    mLocation = src_path;
211
 
212
    if (ripple_field == 'M')
213
    {
214
      mRippleField.setMajor();
215
    }
216
    else if (ripple_field == 'm')
217
    {
218
      mRippleField.setMinor();
219
    }
220
    else if (ripple_field == 'p')
221
    {
222
      mRippleField.setPatch();
223
    }
224
  }
225
 
226
  /**constructor
227
   */
228
  Package()
229
  {
230
    mLogger.debug("Package 3");
231
    mId = 0;
232
    mName = "null";
233
    mExtension = "null";
234
    mAlias = "null";
235
    mLabel = "null";
236
    mLocation = "null";
237
  }
238
 
239
  /**returns true if mBuildStandardCollection is not empty
240
   */
241
  boolean isReproducible()
242
  {
243
    mLogger.debug("isReproducible on Package " + mName);
244
    boolean retVal = false;
245
 
246
    if ( mBuildStandardCollection.size() > 0 )
247
    {
248
      retVal = true;
249
    }
250
 
251
    mLogger.info("isReproducible returned " + retVal);
252
    return retVal;
253
  }
254
 
255
  /**returns true if at least one of its BuildStandards has mWin32 or mGeneric true
256
   */
257
  boolean isWin32Built()
258
  {
259
    mLogger.debug("isWin32Built on Package " + mName);
260
    boolean retVal = false;
864 mhunt 261
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 262
    {
864 mhunt 263
      BuildStandard buildStandard = it.next();
814 mhunt 264
 
265
      if (buildStandard.getWin32() || buildStandard.getGeneric())
266
      {
267
        retVal = true;
268
        break;
269
      }
270
    }
271
 
272
    mLogger.info("isWin32Built returned " + retVal);
273
    return retVal;
274
  }
275
 
276
  /**returns true if at least one of its BuildStandards has mSolaris or mGeneric true
277
   */
278
  boolean isSolarisBuilt()
279
  {
280
    mLogger.debug("isSolarisBuilt on Package " + mName);
281
    boolean retVal = false;
864 mhunt 282
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 283
    {
864 mhunt 284
      BuildStandard buildStandard = it.next();
814 mhunt 285
 
286
      if (buildStandard.getSolaris() || buildStandard.getGeneric())
287
      {
288
        retVal = true;
289
        break;
290
      }
291
    }
292
 
293
    mLogger.info("isSolarisBuilt returned " + retVal);
294
    return retVal;
295
  }
296
 
297
  /**returns true if at least one of its BuildStandards has mLinux or mGeneric true
298
   */
299
  boolean isLinuxBuilt()
300
  {
301
    mLogger.debug("isLinuxBuilt on Package " + mName);
302
    boolean retVal = false;
864 mhunt 303
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 304
    {
864 mhunt 305
      BuildStandard buildStandard = it.next();
814 mhunt 306
 
307
      if (buildStandard.getLinux() || buildStandard.getGeneric())
308
      {
309
        retVal = true;
310
        break;
311
      }
312
    }
313
 
314
    mLogger.info("isLinuxBuilt returned " + retVal);
315
    return retVal;
316
  }
317
 
318
  /**returns true if at least one of its BuildStandards has mGeneric true
319
   */
320
  boolean isGeneric()
321
  {
322
    mLogger.debug("isGeneric on Package " + mName);
323
    boolean retVal = false;
864 mhunt 324
    for (Iterator<BuildStandard> it = mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 325
    {
864 mhunt 326
      BuildStandard buildStandard = it.next();
814 mhunt 327
 
328
      if (buildStandard.getGeneric())
329
      {
330
        retVal = true;
331
        break;
332
      }
333
    }
334
 
335
    mLogger.info("isGeneric returned " + retVal);
336
    return retVal;
337
  }
338
 
339
  /**applies the required version number change
340
   */
341
  void applyPV(ReleaseManager releaseManager, int rtag_id) throws Exception
342
  {
343
    mLogger.debug("applyPV on Package " + mName);
344
    // three scenarios, only applyPV for 2 of them
345
    // WIP exists:                      mDirectlyPlanned == true;   mIndirectlyPlanned == true; mArchivalExistence don't care - applyPV
346
    // Package version is out of date:  mDirectlyPlanned == false;  mIndirectlyPlanned == true; mArchivalExistence == true    - applyPV
347
    // Package version does not exist:  mDirectlyPlanned == false;  mIndirectlyPlanned == true; mArchivalExistence == false   - do not applyPV
348
    if ( !mDirectlyPlanned && mIndirectlyPlanned && !mArchivalExistence )
349
    {
350
      // the package has an mIndirectlyPlanned flag set true in daemon mode because the package does not exist in an archive
351
      // do not apply a different package version
352
      mLogger.info("applyPV !mDirectlyPlanned && mIndirectlyPlanned && !mArchivalExistence on Package " + mName);
836 mhunt 353
      releaseManager.claimVersion(mPid, mVersion + mExtension, rtag_id);
814 mhunt 354
      return;
355
    }
356
 
357
    int major = 0;
358
    int minor = 0;
359
    int patch = 1000;
360
 
361
    String field[] = mVersion.split("\\D");
362
 
363
    if ( field.length == 3 )
364
    {
365
      major = Integer.parseInt(field[0]);
366
      minor = Integer.parseInt(field[1]);
367
      patch = Integer.parseInt(field[2]);
368
    }
369
    else
370
    {
371
      // cannot work with non standard versioning
372
      mLogger.error("applyPV cannot work with non standard versioning");
373
      return;
374
    }
375
 
376
    if ( patch < 1000 && field[2].substring(0, 1).compareTo("0") != 0 )
377
    {
378
      mLogger.info("applyPV accomodate old style mVersion of the form 1.0.1");
379
      patch = patch * 1000;
380
    }
381
 
382
    // mChangeType overrides mRippleField
383
    do
384
    {
385
      if ( mChangeType.mMajor )
386
      {
387
        major++;
388
        mLogger.info("applyPV mChangeType.mMajor " + major);
389
        minor = 0;
390
        patch = 0;
391
      }
392
      else if ( mChangeType.mMinor )
393
      {
394
        minor++;
395
        mLogger.info("applyPV mChangeType.mMinor " + minor);
396
        patch = 0;
397
      }
398
      else if ( mChangeType.mPatch )
399
      {
400
        do
401
        {
402
          patch++;
403
        } while ( ( patch / 1000 ) * 1000 != patch );
404
        mLogger.info("applyPV mChangeType.mPatch " + patch);
405
      }
406
      else
407
      {
408
        if ( mRippleField.mMajor )
409
        {
410
          major++;
411
          mLogger.info("applyPV mRippleField.mMajor " + major);
412
          minor = 0;
413
          patch = 0;
414
        }
415
        else if ( mRippleField.mMinor )
416
        {
417
          minor++;
418
          mLogger.info("applyPV mRippleField.mMinor " + minor);
419
          patch = 0;
420
        }
421
        else if ( mRippleField.mPatch )
422
        {
423
          do
424
          {
425
            patch++;
426
          } while ( ( patch / 1000 ) * 1000 != patch );
427
          mLogger.info("applyPV mRippleField.mPatch " + patch);
428
        }
429
        else
430
        {
431
          patch++;
432
          mLogger.info("applyPV ripple field default " + patch);
433
        }
434
      }
435
 
436
      mVersion = String.valueOf(major) + "." + String.valueOf(minor) + ".";
437
 
438
      if ( patch < 10 )
439
      {
440
        mVersion += "000";
441
      }
442
      else if ( patch < 100 )
443
      {
444
        mVersion += "00";
445
      }
446
      else if ( patch < 1000 )
447
      {
448
        mVersion += "0";
449
      }
450
 
451
      mVersion += String.valueOf(patch);
452
    } while ( exists(releaseManager, rtag_id) );
453
 
454
    releaseManager.claimVersion(mPid, mVersion + mExtension, rtag_id);
455
  }
456
 
457
  /**returns true if the version exists in the dpkg_archive, deploy_archive or release manager database
458
   * claims the version in the release manager database
459
   */
460
  private boolean exists(ReleaseManager releaseManager, int rtag_id) throws Exception
461
  {
462
    mLogger.debug("exists 1 on Package " + mName + " version " + mVersion + " extension " + mExtension);
463
    boolean retVal = false;
464
 
864 mhunt 465
    if ( !ReleaseManager.mUseDatabase )
814 mhunt 466
    {
467
      mLogger.info("exists 1 !releaseManager.mUseDatabase");
468
    }
469
    else
470
    {
471
      retVal = exists();
472
 
473
      if ( !retVal )
474
      {
475
        String pkg_version = new String(mVersion);
476
 
477
        if ( mExtension.length() > 0 )
478
        {
479
          pkg_version += mExtension;
480
        }
481
 
482
        retVal = releaseManager.queryPackageVersions(mPid, pkg_version);
483
      }
484
    }
485
 
486
    mLogger.info("exists 1 returned " + retVal);
487
    return retVal;
488
  }
489
 
490
  /**returns true if the version exists in the dpkg_archive or deploy_archive
491
   */
492
  boolean exists()
493
    throws Exception
494
  {
495
    mLogger.debug("exists 2 on Package " + mName);
496
    boolean retVal = false;
497
 
498
    String Release = mGbeDpkg;
499
    String Deploy = mGbeDply;
500
 
501
    if (Release == null || Deploy == null)
502
    {
868 mhunt 503
      mLogger.fatal("exists 2 Release == null || Deploy == null");
504
      throw new Exception("exists 2 Release == null || Deploy == null");
814 mhunt 505
    }
506
 
507
    String fs = System.getProperty( "file.separator" );
508
    String name = new String(Release);
509
    name += fs + mName + fs + mVersion + mExtension;
510
    File release = new File(name);
511
 
512
    if (release.exists())
513
    {
514
      mLogger.info("exists 2 release.exists()");
515
      retVal = true;
516
    }
517
 
518
    if (!retVal && (Release != Deploy))
519
    {
520
      name = Deploy + fs + mName + fs + mVersion + mExtension;
521
 
522
      File deploy = new File(name);
523
 
524
      if (deploy.exists())
525
      {
526
        mLogger.info("exists 2 deploy.exists()");
527
        retVal = true;
528
      }
529
    }
530
 
531
    mArchivalExistence = retVal;
532
    mLogger.info("exists 2 returned " + retVal);
533
    return retVal;
534
  }
854 mhunt 535
 
536
  /**returns email information
537
   */
538
  String emailInfo( String lf )
539
  {
540
    String retVal = new String();
541
 
864 mhunt 542
    for (Iterator<String> it = mBuildFailureEmailCollection.iterator(); it.hasNext(); )
854 mhunt 543
    {
864 mhunt 544
      String email = it.next();
854 mhunt 545
      retVal +=
546
      "  <owner email=\"" + email +"\"/>" + lf;
547
    }
548
 
549
    return retVal;
550
  }
814 mhunt 551
 
866 mhunt 552
  /**returns email information
553
   */
554
  String emailInfoNonAntTask()
555
  {
556
    String retVal = null;
557
 
558
    for (Iterator<String> it = mBuildFailureEmailCollection.iterator(); it.hasNext(); )
559
    {
560
      String email = it.next();
561
 
562
      if ( retVal == null )
563
      {
564
        retVal = new String();
565
      }
566
      else
567
      {
568
        retVal += ",";
569
      }
570
      retVal += email;
571
    }
572
 
573
    return retVal;
574
  }
575
 
864 mhunt 576
  /**adds email to mBuildFailureEmailCollection if unique
577
   */
578
  void addEmail( String email )
579
  {
580
    boolean alreadyExists = false;
581
 
582
    for (Iterator<String> it = mBuildFailureEmailCollection.iterator(); it.hasNext(); )
583
    {
584
      String existingEmail = it.next();
585
 
586
      if ( existingEmail.compareTo(email) == 0 )
587
      {
588
        alreadyExists = true;
589
        break;
590
      }
591
    }
592
 
593
    if ( !alreadyExists )
594
    {
595
      mBuildFailureEmailCollection.add(email);
596
    }
597
  }
598
 
814 mhunt 599
  /**entity class supporting the ERG version numbering standard:
600
   * <major>.<minor>.<patch/build>
601
   * patch/build is at least a 4 digit number whose last 3 digits represent the build
602
   */
603
  public class VersionNumberingStandard
604
  {
605
    /**in terms of the mChangeType Package field,
606
     * when true indicates the contract of the package has changed in a non backwardly compatible manner
607
     * in terms of the mRippleField Package field,
608
     * when true indicates the major version number will be incremented
609
     * @attribute
610
     */
611
    private boolean mMajor = false;
612
 
613
    /**in terms of the mChangeType Package field,
614
     * when true indicates the contract of the package has changed in a backwardly compatible manner
615
     * in terms of the mRippleField Package field,
616
     * when true indicates the minor version number will be incremented
617
     * @attribute
618
     */
619
    private boolean mMinor = false;
620
 
621
    /**in terms of the mChangeType Package field,
622
     * when true indicates the contract of the package has not changed, but the package has changed internally
623
     * in terms of the mRippleField Package field,
624
     * when true indicates the minor version number will be incremented
625
     * @attribute
626
     */
627
    private boolean mPatch = false;
628
 
629
    /**in terms of the mChangeType Package field,
630
     * when true indicates the package has not changed, its dependencies potentially have
631
     * in terms of the mRippleField Package field,
632
     * when true indicates the build number will be incremented
633
     * @attribute
634
     */
635
    private boolean mBuild = true;
636
 
637
    /**constructor
638
     */
639
    private VersionNumberingStandard()
640
    {
641
      mLogger.debug("VersionNumberingStandard");
642
    }
643
 
644
    /**sets mBuild true, mMajor false, mMinor false, mPatch false
645
     */
646
    void setBuild()
647
    {
648
      mLogger.debug("setBuild");
649
      mBuild = true;
650
      mMajor = false;
651
      mMinor = false;
652
      mPatch = false;
653
    }
654
 
655
    /**sets mBuild false, mMajor true, mMinor false, mPatch false
656
     */
657
    void setMajor()
658
    {
659
      mLogger.debug("setMajor");
660
      mBuild = false;
661
      mMajor = true;
662
      mMinor = false;
663
      mPatch = false;
664
    }
665
 
666
    /**sets mBuild false, mMajor false, mMinor true, mPatch false
667
     */
668
    void setMinor()
669
    {
670
      mLogger.debug("setMinor");
671
      mBuild = false;
672
      mMajor = false;
673
      mMinor = true;
674
      mPatch = false;
675
    }
676
 
677
    /**sets mBuild false, mMajor false, mMinor false, mPatch true
678
     */
679
    void setPatch()
680
    {
681
      mLogger.debug("setPatch");
682
      mBuild = false;
683
      mMajor = false;
684
      mMinor = false;
685
      mPatch = true;
686
    }
687
 
688
  }
689
 
690
}