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