Subversion Repositories DevTools

Rev

Rev 7078 | Rev 7080 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7078 Rev 7079
Line 117... Line 117...
117
 
117
 
118
    /** List of packages that we plan to build
118
    /** List of packages that we plan to build
119
     * Used to provide feedback into RM
119
     * Used to provide feedback into RM
120
     * Only the first entry is about to be built as we re-plan every cycle
120
     * Only the first entry is about to be built as we re-plan every cycle
121
     */
121
     */
122
    private ArrayList<Package> mBuildOrder = new ArrayList  <Package>();
122
    private ArrayList<PlannedPackage> mBuildOrder = new ArrayList  <PlannedPackage>();
123
    /**Warning message
123
    /**Warning message
124
     * @attribute
124
     * @attribute
125
     */
125
     */
126
    private static final String mAnyBuildPlatforms = "Warning. The following package versions are not reproducible on any build platform: ";
126
    private static final String mAnyBuildPlatforms = "Warning. The following package versions are not reproducible on any build platform: ";
127
 
127
 
Line 439... Line 439...
439
                mLogger.info("planRelease circular dependency detected {}", p.mAlias);
439
                mLogger.info("planRelease circular dependency detected {}", p.mAlias);
440
                
440
                
441
                //  Force this package to be marked as having a circular dependency - even if its been excluded
441
                //  Force this package to be marked as having a circular dependency - even if its been excluded
442
                p.mBuildFile = 0;
442
                p.mBuildFile = 0;
443
                
443
                
444
                // exclude all dependent packages
444
                // Exclude the package
445
                // max 50 chars
445
                // max 50 chars
446
                rippleBuildExclude(p, p.mId, "Package has circular dependency", null, null, true, false);
446
                rippleBuildExclude(p, p.mId, "Package has circular dependency", -6);
447
 
447
 
448
                // take the package out of the build
448
                // take the package out of the build
449
                p.mBuildFile = -6;
-
 
450
                mLogger.info("planRelease set mBuildFile to -6 for package {}", p.mAlias );
-
 
451
                standardOut(mCircularDependency, p.mAlias, mCircularDependencyFlag);
449
                standardOut(mCircularDependency, p.mAlias, mCircularDependencyFlag);
452
                mCircularDependencyFlag = false;
450
                mCircularDependencyFlag = false;
453
            }
451
            }
454
        }
452
        }
455
 
453
 
456
        // Scan for packages with missing dependencies
454
        // Scan for packages with missing dependencies
457
        //    ie: The dependent package is not in the package Collection
455
        //    ie: The dependent package is not in the package Collection
458
        //        DEVI 55483 now use the fully built mPackageDependencyCollection (in rippleBuildExclude)
-
 
459
        mLogger.debug("planRelease use the fully built mPackageDependencyCollection");
456
        mLogger.debug("planRelease use the fully built mPackageDependencyCollection");
460
        for (Iterator<Package> it = mPackageCollectionAll.iterator(); it.hasNext(); )
457
        for (Iterator<Package> it = mPackageCollectionAll.iterator(); it.hasNext(); )
461
        {
458
        {
462
            Package p = it.next();
459
            Package p = it.next();
463
 
460
 
Line 478... Line 475...
478
                Package dependency = findPackage(alias);
475
                Package dependency = findPackage(alias);
479
 
476
 
480
                if (dependency == ReleaseManager.NULL_PACKAGE)
477
                if (dependency == ReleaseManager.NULL_PACKAGE)
481
                {
478
                {
482
                    mLogger.info("planRelease dependency is not in the baseline {}", alias);
479
                    mLogger.info("planRelease dependency is not in the baseline {}", alias);
483
                    // exclude all dependent packages
480
                    // Exclude the package
484
                    // max 50 chars
481
                    // max 50 chars
485
                    rippleBuildExclude(p, p.mId, "Package build dependency not in the release", null, null, true, true);
482
                    rippleBuildExclude(p, p.mId, "Package build dependency not in the release", -4);
486
 
483
 
487
                    // take the package out of the build
484
                    // take the package out of the build
488
                    p.mBuildFile = -4;
-
 
489
                    mLogger.info("planRelease set mBuildFile to -4 for package {}", p.mAlias );
-
 
490
                    standardOut(mNotInBaseline, p.mAlias, mNotInBaselineFlag);
485
                    standardOut(mNotInBaseline, p.mAlias, mNotInBaselineFlag);
491
                    mNotInBaselineFlag = false;
486
                    mNotInBaselineFlag = false;
492
                    break;
487
                    break;
493
                }
488
                }
494
            }
489
            }
Line 517... Line 512...
517
                // Escrow - Assume the package is provided
512
                // Escrow - Assume the package is provided
518
                // Daemon - Exclude this package, but not its consumers. If the package is available then we can use it.
513
                // Daemon - Exclude this package, but not its consumers. If the package is available then we can use it.
519
                if (!p.isReproducible())
514
                if (!p.isReproducible())
520
                {
515
                {
521
                    mLogger.info("planRelease package not reproducible {}" ,p.mName);
516
                    mLogger.info("planRelease package not reproducible {}" ,p.mName);
-
 
517
                    
-
 
518
                    // Exclude the package
522
                    // max 50 chars
519
                    // max 50 chars
523
                    rippleBuildExclude(p, p.mId, "Package has no build environment", null, null, false, true);
520
                    rippleBuildExclude(p, p.mId, "Package has no build environment", -1);
524
 
521
 
525
                    // package is not reproducible, discard
522
                    // package is not reproducible, discard
526
                    p.mBuildFile = -1;
-
 
527
                    mLogger.info("planRelease set mBuildFile to -1 for package {}", p.mAlias );
-
 
528
                    standardOut(mAnyBuildPlatforms, p.mAlias, mAnyBuildPlatformsFlag);
523
                    standardOut(mAnyBuildPlatforms, p.mAlias, mAnyBuildPlatformsFlag);
529
                    mAnyBuildPlatformsFlag = false;
524
                    mAnyBuildPlatformsFlag = false;
530
                }
525
                }
531
            }
526
            }
532
        }
527
        }
Line 579... Line 574...
579
 
574
 
580
                if ( !reproduce )
575
                if ( !reproduce )
581
                {
576
                {
582
                    mLogger.info("planRelease package not reproducible on the build platforms configured for this baseline {}", p.mName);
577
                    mLogger.info("planRelease package not reproducible on the build platforms configured for this baseline {}", p.mName);
583
 
578
 
-
 
579
                    // Exclude the package
584
                    // max 50 chars
580
                    // max 50 chars
585
                    rippleBuildExclude(p, p.mId, "Package not built for configured platforms", null, null, false, true);
581
                    rippleBuildExclude(p, p.mId, "Package not built for configured platforms", -2);
586
 
582
 
587
                    // package is not reproducible on the build platforms configured for this baseline, discard
583
                    // package is not reproducible on the build platforms configured for this baseline, discard
588
                    p.mBuildFile = -2;
-
 
589
                    mLogger.info("planRelease set mBuildFile to -2 for package {}", p.mAlias );
-
 
590
                    standardOut(mAssocBuildPlatforms, p.mAlias, mAssocBuildPlatformsFlag);
584
                    standardOut(mAssocBuildPlatforms, p.mAlias, mAssocBuildPlatformsFlag);
591
                    mAssocBuildPlatformsFlag = false;
585
                    mAssocBuildPlatformsFlag = false;
592
                }
586
                }
593
            }
587
            }
594
        }      
588
        }      
595
 
589
 
596
        if (mDaemon)
590
        if (mDaemon )
597
        {
591
        {
598
            // Daemon Mode Only
-
 
599
            // Process packages which are not ripple buildable, and all packages dependent upon them
-
 
600
            //      I would have thought that all consumer packages had already been excluded ??
-
 
601
            mLogger.debug("planRelease process packages which are not ripple buildable");
-
 
602
            for (ListIterator<BuildExclusion> it = mBuildExclusionCollection.listIterator(); it.hasNext(); )
-
 
603
            {
-
 
604
                BuildExclusion be = it.next();
-
 
605
 
-
 
606
                for (Iterator<Package> it1 = mPackageCollectionAll.iterator(); it1.hasNext(); )
-
 
607
                {
-
 
608
                    Package p = it1.next();
-
 
609
 
-
 
610
                    // ensure only root cause, non test build, build exclusions are excluded
-
 
611
                    // mBuildExclusionCollection is at this point based on
-
 
612
                    // relevant (direct and indirect) excluded pv's in the database
-
 
613
                    if ( be.compare(p.mId) && be.isARootCause() && p.mTestBuildInstruction == 0 && p.mForcedRippleInstruction == 0 )
-
 
614
                    {
-
 
615
                        // package is not reproducible, discard
-
 
616
 
-
 
617
                        rippleBuildExclude( p, p.mId, null, it, be, true, true );
-
 
618
                        p.mBuildFile = -3;
-
 
619
                        mLogger.info("planRelease set mBuildFile to -3 for package {}", p.mAlias );
-
 
620
                        break;
-
 
621
                    }
-
 
622
                }
-
 
623
            }
-
 
624
 
592
 
625
            //  Daemon Mode Only
593
            //  Daemon Mode Only
626
            //  Process packages which need to be ripple built
594
            //  Process packages which need to be ripple built
627
            mLogger.debug("planRelease process packages which need to be ripple built");
595
            mLogger.debug("planRelease process packages which need to be ripple built");
628
            for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
596
            for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
Line 668... Line 636...
668
                                //
636
                                //
669
                                if (p.mRippleStop == 's' || p.mRippleStop == 'w') 
637
                                if (p.mRippleStop == 's' || p.mRippleStop == 'w') 
670
                                {
638
                                {
671
                                    // Package marked as a rippleStop
639
                                    // Package marked as a rippleStop
672
                                    // max 50 chars
640
                                    // max 50 chars
673
                                    rippleBuildExclude(p, -2, "Ripple Required." + " Waiting for user", null, null, false, true);
641
                                    rippleBuildExclude(p, -2, "Ripple Required." + " Waiting for user", -11);
674
 
642
 
675
                                    // package is unBuildable, mark reason and discard
-
 
676
                                    p.mBuildFile = -11;
-
 
677
                                    
-
 
678
                                    if (p.mRippleStop == 's' ) {
643
                                    if (p.mRippleStop == 's' ) {
679
                                        // Need to flag to users that the package build is waiting user action
644
                                        // Need to flag to users that the package build is waiting user action
680
                                        mLogger.info("planRelease Ripple Required. Stopped by flag {}", p.mName);
645
                                        mLogger.info("planRelease Ripple Required. Stopped by flag {}", p.mName);
681
                                        mReleaseManager.setRippleStopWait(mRtagId,p);
646
                                        mReleaseManager.setRippleStopWait(mRtagId,p);
682
                                    }
647
                                    }
Line 710... Line 675...
710
                                if (! p.mIsBuildable)
675
                                if (! p.mIsBuildable)
711
                                {
676
                                {
712
                                    //  Package does not exist in dpkg_archive and it has been flagged as unbuildable
677
                                    //  Package does not exist in dpkg_archive and it has been flagged as unbuildable
713
                                    //  This may be because is Unbuildable or Manually built
678
                                    //  This may be because is Unbuildable or Manually built
714
                                    mLogger.info("planRelease Unbuildable package not found in archive {}", p.mName);
679
                                    mLogger.info("planRelease Unbuildable package not found in archive {}", p.mName);
-
 
680
                                    // Exclude the package
715
                                    // max 50 chars
681
                                    // max 50 chars
716
                                    rippleBuildExclude(p, p.mId, "Unbuildable" + " package not found in archive", null, null, true, true);
682
                                    rippleBuildExclude(p, p.mId, "Unbuildable" + " package not found in archive", -10);
717
 
-
 
718
                                    // package is unBuildable, mark reason and discard
-
 
719
                                    p.mBuildFile = -10;
-
 
720
                                    
683
                                    
721
                                }
684
                                }
722
                                //  Not interested in a pegged package or a package provided from an SDK.
685
                                //  Not interested in a pegged package or a package provided from an SDK.
723
                                //  Such packages are not rippled
686
                                //  Such packages are not rippled
724
                                else if (p.mIsPegged || p.mIsSdk)
687
                                else if (p.mIsPegged || p.mIsSdk)
Line 728... Line 691...
728
 
691
 
729
                                    //  Pegged packages or packages provided from an SDK MUST exist in dpkg_archive
692
                                    //  Pegged packages or packages provided from an SDK MUST exist in dpkg_archive
730
                                    //  They will not be built within the context of this release. It is the responsibility
693
                                    //  They will not be built within the context of this release. It is the responsibility
731
                                    //  of another release to build them.
694
                                    //  of another release to build them.
732
                                    mLogger.info("planRelease {} package not found in archive {}", reason, p.mName);
695
                                    mLogger.info("planRelease {} package not found in archive {}", reason, p.mName);
-
 
696
                                    // Exclude the package
733
                                    // max 50 chars
697
                                    // max 50 chars
734
                                    rippleBuildExclude(p, p.mId, reason + " package not found in archive", null, null, true, true);
698
                                    rippleBuildExclude(p, p.mId, reason + " package not found in archive", -7);
735
 
-
 
736
                                    // package is not reproducible, mark reason and discard
-
 
737
                                    p.mBuildFile = -7;
-
 
738
 
-
 
739
                                }
699
                                }
740
                                else if (p.mForcedRippleInstruction == 0)
700
                                else if (p.mForcedRippleInstruction == 0)
741
                                {
701
                                {
742
                                    //  [JATS-331] Unable to rebuild package with Advisory Ripple dependencies
702
                                    //  [JATS-331] Unable to rebuild package with Advisory Ripple dependencies
743
                                    //    Examine this packages dependencies
703
                                    //    Examine this packages dependencies
Line 750... Line 710...
750
                                        {
710
                                        {
751
                                            // This package cannot be rebuilt as one of its dependents is NOT in this release
711
                                            // This package cannot be rebuilt as one of its dependents is NOT in this release
752
                                            // exclude all dependent package versions
712
                                            // exclude all dependent package versions
753
                                            
713
                                            
754
                                            mLogger.info("planRelease package not found in archive. Cannot be rebuilt due to {}", p.mName);
714
                                            mLogger.info("planRelease package not found in archive. Cannot be rebuilt due to {}", p.mName);
-
 
715
                                            // Exclude the package
755
                                            // max 50 chars
716
                                            // max 50 chars
756
                                            rippleBuildExclude(p, p.mId, "Package cannot be rebuilt in this release", null, null, true, true);
717
                                            rippleBuildExclude(p, p.mId, "Package cannot be rebuilt in this release", -4);
757
 
-
 
758
                                            // package is not reproducible, mark reason and discard
-
 
759
                                            p.mBuildFile = -4;
-
 
760
                                            break;
718
                                            break;
761
                                        }
719
                                        }
762
                                    }
720
                                    }
763
                                    
721
                                    
764
                                    //  The package has not been excluded from the build
722
                                    //  The package has not been excluded from the build
Line 881... Line 839...
881
            //  The package will be excluded and the user will be emailed
839
            //  The package will be excluded and the user will be emailed
882
            //
840
            //
883
            ArrayList<Package> testVersions = new ArrayList<Package>();
841
            ArrayList<Package> testVersions = new ArrayList<Package>();
884
            testVersions.addAll(mPackageCollectionWip);
842
            testVersions.addAll(mPackageCollectionWip);
885
            testVersions.addAll(mPackageCollectionRipple);
843
            testVersions.addAll(mPackageCollectionRipple);
-
 
844
            testVersions.addAll(mPackageCollectionTest);
886
            
845
            
887
            for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
846
            for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
888
            {
847
            {
889
                Package p = it.next();
848
                Package p = it.next();
890
                if (p.mBuildFile >= 0 &&  p.mBuildReason != null) {
849
                if (p.mBuildFile >= 0 &&  p.mBuildReason != null) {
Line 901... Line 860...
901
                    int pvApplied = p.applyPV(mReleaseManager);
860
                    int pvApplied = p.applyPV(mReleaseManager);
902
 
861
 
903
                    if ( pvApplied == 1 )
862
                    if ( pvApplied == 1 )
904
                    {
863
                    {
905
                        // max 50 chars
864
                        // max 50 chars
906
                        rippleBuildExclude(p, p.mId, "Package has non standard versioning", null, null, true, true);
865
                        rippleBuildExclude(p, p.mId, "Package has non standard versioning", -5);
907
                    }
866
                    }
908
                    else if ( pvApplied == 2 )
867
                    else if ( pvApplied == 2 )
909
                    {
868
                    {
910
                        // max 50 chars
869
                        // max 50 chars
911
                        rippleBuildExclude(p, p.mId, "Package has reached ripple field limitations", null, null, true, true);
870
                        rippleBuildExclude(p, p.mId, "Package has reached ripple field limitations", -5);
912
                    }
871
                    }
913
                    else if ( pvApplied == 3 )
872
                    else if ( pvApplied == 3 )
914
                    {
873
                    {
915
                        // max 50 chars
874
                        // max 50 chars
916
                        rippleBuildExclude(p, p.mId, "Package has invalid change type", null, null, true, true);
875
                        rippleBuildExclude(p, p.mId, "Package has invalid change type", -5);
917
                    }
876
                    }
918
                }
877
                }
919
            }
878
            }
920
            
879
            
921
        }
880
        }
Line 936... Line 895...
936
                    mDependentFlag = false;
895
                    mDependentFlag = false;
937
                }
896
                }
938
            }
897
            }
939
        }
898
        }
940
    }
899
    }
-
 
900
    
-
 
901
    /** Plan the build order.
-
 
902
         *  Assumes that a great deal of work has been done.
-
 
903
         *  This is a stand alone method to contain the work
-
 
904
         *  
-
 
905
         * @throws Exception
-
 
906
         * @throws SQLException
-
 
907
         */
-
 
908
        private void planBuildOrder() throws Exception, SQLException 
-
 
909
        {
-
 
910
            
-
 
911
    //TODO - Planning is not working well
-
 
912
    /**
-
 
913
     * Current status
-
 
914
     * The selection of the package to build next is deeply flawed
-
 
915
     * Currently it will select a directly planned package over a ripple - (perhaps that is good)
-
 
916
     * 
-
 
917
     * Currently on the buildPlan of the 'selected' package is included in the BuildOrder
-
 
918
     * 
-
 
919
     * The current algorithm is based on time - but all packages have zero build time ( in UTF )
-
 
920
     * Even if this is fixed the algorithm is broken as we will select the complete build with the shortest time
-
 
921
     * which will be the ripple of a leaf package ( perhaps that is good )
-
 
922
     * 
-
 
923
     * Also:
-
 
924
     *      [Done] Need to include all packages that we can now build into the final build plan, not just the first one and its build tree
-
 
925
     * 
-
 
926
     *      [Done-ish]Need to generate a single package set - so that WIPS and others replace those in the final build set
-
 
927
     *      [Done]Remove duplicates from the complete package set
-
 
928
     *      
-
 
929
     *      [Being Done] Need more test cases
-
 
930
     *      
-
 
931
     *      [Done, in the UTF] Need to report all build options, not just the selected one
-
 
932
     *                         Data to RM may need some more info
-
 
933
     *      
-
 
934
     *      Cleanup the ANT build file - don't list all the release dependencies, just those needed to build the current package
-
 
935
     *      Chances are - all we need is the new package version number
-
 
936
     *      
-
 
937
     *      [Fixed] If a WIP on a package that has circular dependencies is added, then the WIP will be excluded. This prevents the problem being fixed.
-
 
938
     *              Should not exclude a WIP of a package with a circular dependency
-
 
939
     */
-
 
940
    
-
 
941
            // Process remaining packages which are need to be reproduced for this baseline.
-
 
942
            //    Determine the build file for each package
-
 
943
            //    For daemon builds:
-
 
944
            //      Determine the next package that can be built now
-
 
945
            //          Sounds simple - doesn't it
-
 
946
            //      Set its mBuildNumber to 1, all remaining reproducible packages to 2
-
 
947
            //    For escrow builds:
-
 
948
            //      Determine the package versions that can be built in the build iteration
-
 
949
            //      Set their mBuildNumber to the build iteration
-
 
950
            //      Increment the build iteration and repeat until all package versions 
-
 
951
            //      that need to be reproduced have been assigned a build iteration        
-
 
952
            
-
 
953
            //
-
 
954
            //  Generate a plan for the packages that are in the current release
-
 
955
            //  These may be the result of a ripple going through the system 
-
 
956
            //  or a rebuild of a missing package or the result of a merge.
-
 
957
            //
-
 
958
            //  This will provide our basic plan, before we consider adding new packages to the
-
 
959
            //  mix, such as those from user WIPS and RIPPLE requests.
-
 
960
            //  
-
 
961
            PlanResults basicPlan = planCollection("Basic", mPackageCollection, true);
-
 
962
            
-
 
963
            //  Have not considered any of the WIP or RIPPLE packages
-
 
964
            //  If any of them are in the basic plan, then we can ignore them as we will build them
-
 
965
            //  when we build the basic plan
-
 
966
            //
-
 
967
            //  Determine a set of packages that will not be included if we build the basic plan
-
 
968
            //
-
 
969
            //  At the moment - lets assume there are none
-
 
970
            //  What do we do ?
-
 
971
            //      Select the first request
-
 
972
            //      Replace the package in the released collection
-
 
973
            //      Run the plan algorithm
-
 
974
            //      Restore the release collection
-
 
975
            //
-
 
976
            if ( mDaemon )
-
 
977
            {
-
 
978
                //
-
 
979
                //  Need to consider the TEST requests
-
 
980
                //      - Valid requests will be placed first on the build order
-
 
981
                //
-
 
982
                mBuildOrder.clear();
-
 
983
                for (Iterator<Package> it = mPackageCollectionTest.iterator(); it.hasNext(); )
-
 
984
                {
-
 
985
                    Package p = it.next();
-
 
986
                    if (p.mBuildFile >= 0)
-
 
987
                    {
-
 
988
                        mBuildOrder.add( new PlannedPackage(p,0 ) );
-
 
989
                    }
-
 
990
                }
-
 
991
                
-
 
992
                //  First attempt
-
 
993
                //  Insert all the WIPs and RIPPLES into the buildset. 
-
 
994
                //  Generate a plan and see how much the time is extended.
-
 
995
                //
-
 
996
                //  Don't modify mPackageCollection, although data in the 'Package' in the underlying packages may change
-
 
997
                
-
 
998
                PlanResults fullPlan = null;           
-
 
999
                fullPlan = postRipplePlan("Full", basicPlan, true);
-
 
1000
                
-
 
1001
                //  Decide with plan to use
-
 
1002
                //  At the moment we have, at most two.
-
 
1003
                //      - (basic) Current Release ripples
-
 
1004
                //      - (full) Current Release + All WIPS and RIPPLES
-
 
1005
                //
-
 
1006
                //  If we have both then if the full plan is < 20% longer than the basic plan, use the full plan
-
 
1007
                //  Otherwise we use basic plan FOLLOWED by the a MODIFIED full plan (one without the natural ripples)
-
 
1008
                //  Add the planned packages into the buildOrder
-
 
1009
    
-
 
1010
                if( !basicPlan.planCollection.isEmpty() && fullPlan != null )
-
 
1011
                {
-
 
1012
                    mLogger.error("Two plan selection: {} {}, {} <= {}", basicPlan.planTime,fullPlan.planTime, basicPlan.planTime * 12, fullPlan.planTime * 10);
-
 
1013
                    if ( (basicPlan.planTime * 12) <= (fullPlan.planTime * 10) )
-
 
1014
                    {
-
 
1015
                        //  Use the basic plan FOLLOWED by a plan that does not include
-
 
1016
                        //      Ripples done by the basic plan
-
 
1017
                        //      WIPs/RIPPLES done in the course of doing the basic plan
-
 
1018
    
-
 
1019
                        mBuildOrder.addAll(basicPlan.planCollection);
-
 
1020
                        fullPlan = postRipplePlan("Full-Ripples", basicPlan, false);
-
 
1021
                        mBuildOrder.addAll(fullPlan.planCollection);
-
 
1022
                        
-
 
1023
                    } else {
-
 
1024
                        //  Use the full plan
-
 
1025
                        mBuildOrder.addAll(fullPlan.planCollection);
-
 
1026
                    }
-
 
1027
                } else if (!basicPlan.planCollection.isEmpty() ) {
-
 
1028
                    // Use the basic plan
-
 
1029
                    mBuildOrder.addAll(basicPlan.planCollection);
-
 
1030
                    
-
 
1031
                } else if ( fullPlan != null ) {
-
 
1032
                    // Use the full plan, but treat it as the basic plan so that we will mark level-0 builds
-
 
1033
                    basicPlan = fullPlan;
-
 
1034
                    fullPlan = null;
-
 
1035
                    mBuildOrder.addAll(basicPlan.planCollection);
-
 
1036
                    
-
 
1037
                } else {
-
 
1038
                    // Do not have a plan
-
 
1039
                    // May have tests requests
-
 
1040
                }
-
 
1041
                
-
 
1042
                //  Now have an mBuildOrder
-
 
1043
                //  Mark the first package in the build order as the one to be built
-
 
1044
                //
-
 
1045
                Package build = ReleaseManager.NULL_PACKAGE;
-
 
1046
                if (!mBuildOrder.isEmpty()) {
-
 
1047
                    build = mBuildOrder.get(0).mPkg;
-
 
1048
                    build.mBuildFile = 1;
-
 
1049
                    
-
 
1050
                    if ( build.mForcedRippleInstruction > 0 )
-
 
1051
                    {
-
 
1052
                        mReleaseManager.markDaemonInstCompleted( build.mForcedRippleInstruction );
-
 
1053
                    }
-
 
1054
    
-
 
1055
                    if ( build.mTestBuildInstruction > 0 )
-
 
1056
                    {
-
 
1057
                        mReleaseManager.markDaemonInstInProgress( build.mTestBuildInstruction );
-
 
1058
                    }
-
 
1059
                    
-
 
1060
                    //  Now that we know which package we are building
-
 
1061
                    //      Set the previously calculated nextVersion as the packages version number
-
 
1062
                    //      Claim the version number to prevent other builds from using it. Even if doing a test build
-
 
1063
                    //
-
 
1064
                    if (build.mNextVersion != null)
-
 
1065
                    {
-
 
1066
                        mReleaseManager.claimVersion(build.mPid, build.mNextVersion + build.mExtension, mBaseline);
-
 
1067
                        build.mVersion = build.mNextVersion;
-
 
1068
                    }
-
 
1069
                }
-
 
1070
                
-
 
1071
                //
-
 
1072
                //  Massage the package collection
-
 
1073
                //      Replace WIP/TEST/RIPPLE so that the mPackageCollection is a collection of packages we would like in the release
-
 
1074
                //      Don't replace those that we can't build due to errors
-
 
1075
                //  
-
 
1076
 
-
 
1077
                //         Update packages in the basicPlan
-
 
1078
                //         Update / Add packages to the fullPlan
-
 
1079
                //
-
 
1080
                ArrayList<Package> buildCandidates = new ArrayList<Package>();
-
 
1081
                buildCandidates.addAll(mPackageCollectionTest);
-
 
1082
                buildCandidates.addAll(mPackageCollectionWip);
-
 
1083
                buildCandidates.addAll(mPackageCollectionRipple);
-
 
1084
    
-
 
1085
                for (Iterator<Package> it = buildCandidates.iterator(); it.hasNext(); )
-
 
1086
                {
-
 
1087
                    Package p = it.next();
-
 
1088
                    if ( p.mBuildFile >= 0 )
-
 
1089
                    {
-
 
1090
                        Package pReleased = findPackage(p.mAlias);
-
 
1091
                        if ( pReleased != ReleaseManager.NULL_PACKAGE)
-
 
1092
                        {
-
 
1093
                            int index = mReleaseManager.findPackageLastIndex;
-
 
1094
                            mPackageCollection.set(index, p);
-
 
1095
                            p.mIsNotReleased = false;
-
 
1096
                        }
-
 
1097
                        else
-
 
1098
                        {
-
 
1099
                            mPackageCollection.add(p);
-
 
1100
                            p.mIsNotReleased = false;
-
 
1101
                        }
-
 
1102
                    }
-
 
1103
                }
-
 
1104
                
-
 
1105
                //
-
 
1106
                //  Report packages that are indirectly excluded
-
 
1107
                //  ie: They will be built because one, or more, of there dependents is not buildable
-
 
1108
                //
-
 
1109
                mLogger.debug("planBuildOrder process packages which are not ripple buildable");
-
 
1110
 
-
 
1111
                 for (ListIterator<BuildExclusion> it = mBuildExclusionCollection.listIterator(); it.hasNext(); )
-
 
1112
                 {
-
 
1113
                     BuildExclusion be = it.next();
-
 
1114
 
-
 
1115
                     for (Iterator<Package> it1 = mPackageCollection.iterator(); it1.hasNext(); )
-
 
1116
                     {
-
 
1117
                         Package p = it1.next();
-
 
1118
 
-
 
1119
                         // ensure only root cause, non test build, build exclusions are excluded
-
 
1120
                         // mBuildExclusionCollection is at this point based on
-
 
1121
                         // relevant (direct and indirect) excluded pv's in the database
-
 
1122
                         if ( be.compare(p.mId) && be.isARootCause() && p.mTestBuildInstruction == 0 && p.mForcedRippleInstruction == 0 )
-
 
1123
                         {
-
 
1124
                             // package is not reproducible, discard it and its consumers
-
 
1125
                             //
-
 
1126
                             mLogger.error("Excluded Package {}, {}", p.mAlias, be.mRootCause);                                     
-
 
1127
                             
-
 
1128
                             ArrayList<Package> toExclude = new ArrayList<Package>();
-
 
1129
                             toExclude.addAll(usedByAnyPackages(p, mPackageCollection ));
-
 
1130
                             
-
 
1131
                             //  Process packages that we need to exclude indirectly
-
 
1132
                             //
-
 
1133
                             while ( ! toExclude.isEmpty())
-
 
1134
                             {
-
 
1135
                                 Package pkg = toExclude.remove(0);
-
 
1136
                                 
-
 
1137
                                 // If this package has not been excluded ( for whatever reason), than add it
-
 
1138
                                 boolean found = false;
-
 
1139
                                 for (Iterator<BuildExclusion> it2 = mBuildExclusionCollection.iterator(); it2.hasNext(); )
-
 
1140
                                 {
-
 
1141
                                     BuildExclusion buildExclusion = it2.next();
-
 
1142
                                     if (buildExclusion.compare(pkg.mId) )
-
 
1143
                                     {
-
 
1144
                                         found = true;
-
 
1145
                                         break;
-
 
1146
                                     }
-
 
1147
                                 }
-
 
1148
                                 
-
 
1149
                                 if (!found)
-
 
1150
                                 {
-
 
1151
                                     BuildExclusion buildExclusion = new BuildExclusion(pkg.mId, p.mId, null, p.mTestBuildInstruction);
-
 
1152
                                     it.add(buildExclusion);
-
 
1153
                                     mLogger.error("Indirectly Excluded Package {}", pkg.mAlias);  
-
 
1154
 
-
 
1155
                                     ArrayList<Package> usedBy = usedByAnyPackages(p, mPackageCollectionAll );
-
 
1156
                                     toExclude.addAll(usedBy);
-
 
1157
                                 }
-
 
1158
                             }
-
 
1159
                         }
-
 
1160
                     }
-
 
1161
                 }
-
 
1162
                
-
 
1163
                //
-
 
1164
                //  To fit in with the old algorithm ( ie: could be improved )
-
 
1165
                //  Insert marks into all packages
-
 
1166
                //  Not sure exactly why - Its used in the generation of the ant build file
-
 
1167
                //                     Want to set mNoBuildReason, mBuildFile
-
 
1168
                //
-
 
1169
                //      Package we have selected to build: 0     , 1
-
 
1170
                //      Package we could have built      : 0     , 2
-
 
1171
                //      Packages we can't build          : reason, 3
-
 
1172
                //      Packages that are OK             : 3     , 3
-
 
1173
                //      ????                             : 0     , 3
-
 
1174
                
-
 
1175
                for (Iterator<Package> it = mPackageCollectionAll.iterator(); it.hasNext(); )
-
 
1176
                {
-
 
1177
                    Package p = it.next();
-
 
1178
                    if (p == build ) {
-
 
1179
                        p.mNoBuildReason = 0;
-
 
1180
                        p.mBuildFile = 1;
-
 
1181
                    } 
-
 
1182
                    else if ( p.mBuildFile < 0 )
-
 
1183
                    {
-
 
1184
                        p.mNoBuildReason = p.mBuildFile;
-
 
1185
                        p.mBuildFile = 3;
-
 
1186
                    }
-
 
1187
                    else if (p.mBuildReason != null)
-
 
1188
                    {
-
 
1189
                        p.mNoBuildReason = 0;
-
 
1190
                        p.mBuildFile = 2;
-
 
1191
                    }
-
 
1192
                    else
-
 
1193
                    {
-
 
1194
                        p.mNoBuildReason = 0;
-
 
1195
                        p.mBuildFile = 3;
-
 
1196
                    }
-
 
1197
                }
-
 
1198
    
-
 
1199
            }
-
 
1200
            else
-
 
1201
            {
-
 
1202
                //  Escrow
-
 
1203
                //  The basic plan is the escrow build order
-
 
1204
                mBuildOrder = basicPlan.planCollection;
-
 
1205
            }
-
 
1206
    
-
 
1207
            mLogger.error("Final Plan");
-
 
1208
            for (Iterator<PlannedPackage> it = mBuildOrder.iterator(); it.hasNext(); )
-
 
1209
            {
-
 
1210
                PlannedPackage p = it.next();
-
 
1211
                mLogger.error("Plan: {} {}", p.mBuildLevel, p.mPkg.mAlias);
-
 
1212
            }
-
 
1213
               
-
 
1214
    
-
 
1215
        }
941
 
1216
 
942
    /** Internal class to contain intermediate results
1217
    /** Internal class to contain intermediate results
943
     */
1218
     */
944
    class PlanResults {
1219
    class PlanResults {
945
        int planTime = 0;
1220
        int planTime = 0;
946
        ArrayList<Package> planCollection = new ArrayList<Package>(); 
1221
        ArrayList<PlannedPackage> planCollection = new ArrayList<PlannedPackage>(); 
947
    }
1222
    }
948
 
1223
 
949
    /**
1224
    /**
950
     * Process a collection of packages and generate a collection of package plans
1225
     * Process a collection of packages and generate a collection of package plans
951
     * A package plan is a collection of packages that can be built
1226
     * A package plan is a collection of packages that can be built
Line 962... Line 1237...
962
     * 
1237
     * 
963
     * @return
1238
     * @return
964
     */
1239
     */
965
    private PlanResults planCollection(String name, ArrayList<Package> packageCollection, boolean mode)
1240
    private PlanResults planCollection(String name, ArrayList<Package> packageCollection, boolean mode)
966
    {
1241
    {
967
        ArrayList<Package> ripplePlan = new ArrayList<Package>();
1242
        ArrayList<PlannedPackage> ripplePlan = new ArrayList<PlannedPackage>();
968
        PlanResults results = new PlanResults();
1243
        PlanResults results = new PlanResults();
969
 
1244
 
970
        //  Reset flags used in the calculations
1245
        //  Reset flags used in the calculations
971
        Package.resetProcessed(packageCollection);
1246
        Package.resetProcessed(packageCollection);
972
        
1247
        
Line 1080... Line 1355...
1080
                    if (allDependenciesForThisPackageProcessed)
1355
                    if (allDependenciesForThisPackageProcessed)
1081
                    {
1356
                    {
1082
                        p.mProcessed = true;
1357
                        p.mProcessed = true;
1083
                        if ( canBeBuiltNow )
1358
                        if ( canBeBuiltNow )
1084
                        {
1359
                        {
1085
                            results.planCollection.add(p);
1360
                            results.planCollection.add( new PlannedPackage(p, buildLevel));
1086
                            p.mBuildFile = buildLevel;
1361
                            p.mBuildFile = buildLevel;
1087
                            p.mIsProcessed = true;
1362
                            p.mIsProcessed = true;
1088
                            mLogger.info("planRelease set mBuildFile to {} for package {}",buildLevel, p.mAlias );
1363
                            mLogger.info("planRelease set mBuildFile to {} for package {}",buildLevel, p.mAlias );
1089
                        }
1364
                        }
1090
                    }
1365
                    }
Line 1118... Line 1393...
1118
        //      The packages currently have a build level set into mBuildFile
1393
        //      The packages currently have a build level set into mBuildFile
1119
        //
1394
        //
1120
        if (mDaemon)
1395
        if (mDaemon)
1121
        {
1396
        {
1122
            //  Determine if we have a reason to build anything in this collection of buildable packages
1397
            //  Determine if we have a reason to build anything in this collection of buildable packages
-
 
1398
            //  Reset the calculated buildLevel - It will be calculated again
-
 
1399
            //
1123
            ArrayList<Package> toBuild = new ArrayList<Package>();
1400
            ArrayList<PlannedPackage> toBuild = new ArrayList<PlannedPackage>();
1124
            for (Iterator<Package> it = results.planCollection.iterator(); it.hasNext(); )
1401
            for (Iterator<PlannedPackage> it = results.planCollection.iterator(); it.hasNext(); )
1125
            {
1402
            {
1126
                Package p = it.next();
1403
                PlannedPackage p = it.next();
-
 
1404
                p.mBuildLevel = 0;
-
 
1405
                
1127
                if (p.mBuildReason != null) {
1406
                if (p.mPkg.mBuildReason != null) {
1128
                    if (mode || ( !mode && p.mBuildReason != BuildReason.Ripple ))
1407
                    if (mode || ( !mode && p.mPkg.mBuildReason != BuildReason.Ripple ))
1129
                    {
1408
                    {
1130
                        toBuild.add(p);
1409
                        toBuild.add(p);
1131
                    }
1410
                    }
1132
                }
1411
                }
1133
            }
1412
            }
Line 1142... Line 1421...
1142
                
1421
                
1143
                //  Need to add elements to the end of the list while processing
1422
                //  Need to add elements to the end of the list while processing
1144
                //  Sum the buildTimes of the packages that we add to the list
1423
                //  Sum the buildTimes of the packages that we add to the list
1145
                while ( ! toBuild.isEmpty())
1424
                while ( ! toBuild.isEmpty())
1146
                {
1425
                {
1147
                    Package pkg = toBuild.remove(0);
1426
                    PlannedPackage pkg = toBuild.remove(0);
1148
                    
1427
                    
1149
                    if (pkg.mRippleOrder > 100 ) {
1428
                    if (pkg.mBuildLevel > 100 ) {
1150
                        mLogger.error("Circular dependency detected - not handled well");
1429
                        mLogger.error("Circular dependency detected - not handled well");
1151
                        break;
1430
                        break;
1152
                    }
1431
                    }
1153
                    
1432
                    
1154
                    if ( ! ripplePlan.contains( pkg ))
1433
                    if ( ! ripplePlan.contains( pkg ))
1155
                    {
1434
                    {
1156
                        ripplePlan.add(pkg);
1435
                        ripplePlan.add(pkg);
1157
                        results.planTime += pkg.mBuildTime;
1436
                        results.planTime += pkg.mPkg.mBuildTime;
1158
                    }
1437
                    }
1159
                    
1438
                    
1160
                    ArrayList<Package> usedBy = usedByPackages(pkg, results.planCollection, pkg.mRippleOrder + 1);
1439
                    ArrayList<PlannedPackage> usedBy = usedByPackages(pkg, results.planCollection, pkg.mBuildLevel + 1);
1161
                    toBuild.addAll(usedBy);
1440
                    toBuild.addAll(usedBy);
1162
                }
1441
                }
-
 
1442
                
1163
                //  Sort the packages by buildOrder and buildTime
1443
                //  Sort the packages by buildOrder and buildTime
1164
                Collections.sort(ripplePlan, Package.BuildOrderComparitor);
1444
                Collections.sort(ripplePlan, PlannedPackage.BuildOrderComparitor);
1165
                
1445
                
1166
                mLogger.error("Plan Build {} Time: {}", name, results.planTime);
1446
                mLogger.error("Plan Build {} Time: {}", name, results.planTime);
1167
                for (Iterator<Package> it = ripplePlan.iterator(); it.hasNext(); )
1447
                for (Iterator<PlannedPackage> it = ripplePlan.iterator(); it.hasNext(); )
1168
                {
1448
                {
1169
                    Package p = it.next();
1449
                    PlannedPackage p = it.next();
1170
                    mLogger.error("Plan: {} {}", p.mRippleOrder, p.mAlias);
1450
                    mLogger.error("Plan: {} {}", p.mBuildLevel, p.mPkg.mAlias);
1171
                }
1451
                }
1172
            }
1452
            }
1173
            
1453
            
1174
            //  Daemon mode: Returning calculated plan
1454
            //  Daemon mode: Returning calculated plan
1175
            results.planCollection = ripplePlan;
1455
            results.planCollection = ripplePlan;
Line 1201... Line 1481...
1201
                if (p.mBuildFile >= 0)
1481
                if (p.mBuildFile >= 0)
1202
                {
1482
                {
1203
                    if (!mode)
1483
                    if (!mode)
1204
                    {
1484
                    {
1205
                        //  Exclude packages that would have been processed in the basicPlan
1485
                        //  Exclude packages that would have been processed in the basicPlan
1206
                        for (Iterator<Package> it1 = basicPlan.planCollection.iterator(); it1.hasNext(); )
1486
                        for (Iterator<PlannedPackage> it1 = basicPlan.planCollection.iterator(); it1.hasNext(); )
1207
                        {
1487
                        {
1208
                            Package pkg = it1.next();
1488
                            PlannedPackage pkg = it1.next();
1209
                            if (pkg == p)
1489
                            if (pkg.mPkg == p)
1210
                            {
1490
                            {
1211
                                mLogger.error("Test Plan without {}", p.mAlias);
1491
                                mLogger.error("Test Plan without {}", p.mAlias);
1212
                                continue;
1492
                                continue;
1213
                            }
1493
                            }
1214
                        }
1494
                        }
Line 1232... Line 1512...
1232
                        mLogger.info("planRelease circular dependency detected {}", p.mAlias);
1512
                        mLogger.info("planRelease circular dependency detected {}", p.mAlias);
1233
                        
1513
                        
1234
                        //  Force this package to be marked as having a circular dependency - even if its been excluded
1514
                        //  Force this package to be marked as having a circular dependency - even if its been excluded
1235
                        p.mBuildFile = 0;
1515
                        p.mBuildFile = 0;
1236
                        
1516
                        
1237
                        // exclude all dependent packages
1517
                        // Exclude the package
1238
                        // max 50 chars
1518
                        // max 50 chars
1239
                        rippleBuildExclude(p, p.mId, "Package has circular dependency", null, null, true, false);
1519
                        rippleBuildExclude(p, p.mId, "Package has circular dependency", -6);
1240
 
-
 
1241
                        // take the package out of the build
-
 
1242
                        p.mBuildFile = -6;
-
 
1243
                        mLogger.info("planRelease set mBuildFile to -6 for package {}", p.mAlias );
-
 
1244
                    }
1520
                    }
1245
                }
1521
                }
1246
            }
1522
            }
1247
            
1523
            
1248
        }
1524
        }
1249
        return planCollection(name, fullPlanCollection, mode);
1525
        return planCollection(name, fullPlanCollection, mode);
1250
    }
1526
    }
1251
 
1527
 
-
 
1528
    /** 
-
 
1529
     *  Calculate a collection of packages that actively use the named package
-
 
1530
     *  A consumer package does NOT use the named package,
1252
    /** Plan the build order.
1531
     *      If the consumer is an SDK or is Pegged
1253
     *  Assumes that a great deal of work has been done.
1532
     *      If the consumer is marked as advisoryRipple
1254
     *  This is a stand alone method to contain the work
1533
     *      If the consumer cannot be built
1255
     *  
1534
     *   
1256
     * @throws Exception
1535
     * @param pkg - Package to process
-
 
1536
     * @param planCollection - collection of packages to scan
1257
     * @throws SQLException
1537
     * @param rippleOrder - Set the ripple oder, if >= 0
-
 
1538
     *
-
 
1539
     * @return A collection of packages that actively 'use' the specified package
-
 
1540
 
1258
     */
1541
     */
1259
    private void planBuildOrder() throws Exception, SQLException 
1542
    private ArrayList<PlannedPackage> usedByPackages(PlannedPackage pkg, ArrayList<PlannedPackage> planCollection, int rippleOrder) {
1260
    {
-
 
1261
        
1543
        
1262
//TODO - Planning is not working well
-
 
1263
/**
-
 
1264
 * Current status
-
 
1265
 * The selection of the package to build next is deeply flawed
-
 
1266
 * Currently it will select a directly planned package over a ripple - (perhaps that is good)
-
 
1267
 * 
-
 
1268
 * Currently on the buildPlan of the 'selected' package is included in the BuildOrder
-
 
1269
 * 
-
 
1270
 * The current algorithm is based on time - but all packages have zero build time ( in UTF )
-
 
1271
 * Even if this is fixed the algorithm is broken as we will select the complete build with the shortest time
-
 
1272
 * which will be the ripple of a leaf package ( perhaps that is good )
-
 
1273
 * 
-
 
1274
 * Also:
-
 
1275
 *      [Done] Need to include all packages that we can now build into the final build plan, not just the first one and its build tree
-
 
1276
 * 
-
 
1277
 *      [Done-ish]Need to generate a single package set - so that WIPS and others replace those in the final build set
-
 
1278
 *      [Done]Remove duplicates from the complete package set
-
 
1279
 *      
-
 
1280
 *      [Being Done] Need more test cases
-
 
1281
 *      
-
 
1282
 *      [Done, in the UTF] Need to report all build options, not just the selected one
-
 
1283
 *                         Data to RM may need some more info
-
 
1284
 *      
-
 
1285
 *      Cleanup the ANT build file - don't list all the release dependencies, just those needed to build the current package
-
 
1286
 *      Chances are - all we need is the new package version number
-
 
1287
 *      
-
 
1288
 *      [Fixed] If a WIP on a package that has circular dependencies is added, then the WIP will be excluded. This prevents the problem being fixed.
-
 
1289
 *              Should not exclude a WIP of a package with a circular dependency
-
 
1290
 */
-
 
1291
 
-
 
1292
        // Process remaining packages which are need to be reproduced for this baseline.
1544
        ArrayList<PlannedPackage> usedBy = new ArrayList<PlannedPackage>();
1293
        //    Determine the build file for each package
-
 
1294
        //    For daemon builds:
-
 
1295
        //      Determine the next package that can be built now
-
 
1296
        //          Sounds simple - doesn't it
-
 
1297
        //      Set its mBuildNumber to 1, all remaining reproducible packages to 2
-
 
1298
        //    For escrow builds:
-
 
1299
        //      Determine the package versions that can be built in the build iteration
-
 
1300
        //      Set their mBuildNumber to the build iteration
-
 
1301
        //      Increment the build iteration and repeat until all package versions 
-
 
1302
        //      that need to be reproduced have been assigned a build iteration        
-
 
1303
        
1545
        
1304
        //
-
 
1305
        //  Generate a plan for the packages that are in the current release
1546
        for (Iterator<PlannedPackage> it = planCollection.iterator(); it.hasNext(); )
1306
        //  These may be the result of a ripple going through the system 
-
 
1307
        //  or a rebuild of a missing package or the result of a merge.
-
 
1308
        //
-
 
1309
        //  This will provide our basic plan, before we consider adding new packages to the
-
 
1310
        //  mix, such as those from user WIPS and RIPPLE requests.
-
 
1311
        //  
-
 
1312
        PlanResults basicPlan = planCollection("Basic", mPackageCollection, true);
-
 
1313
        
-
 
1314
        //  Have not considered any of the WIP or RIPPLE packages
-
 
1315
        //  If any of them are in the basic plan, then we can ignore them as we will build them
-
 
1316
        //  when we build the basic plan
-
 
1317
        //
-
 
1318
        //  Determine a set of packages that will not be included if we build the basic plan
-
 
1319
        //
-
 
1320
        //  At the moment - lets assume there are none
-
 
1321
        //  What do we do ?
-
 
1322
        //      Select the first request
-
 
1323
        //      Replace the package in the released collection
-
 
1324
        //      Run the plan algorithm
-
 
1325
        //      Restore the release collection
-
 
1326
        //
-
 
1327
        if ( mDaemon )
-
 
1328
        {
1547
        {
1329
            //
-
 
1330
            //  Need to consider the TEST requests
-
 
1331
            //      - Valid requests will be placed first on the build order
-
 
1332
            //
-
 
1333
            mBuildOrder.clear();
-
 
1334
            for (Iterator<Package> it = mPackageCollectionTest.iterator(); it.hasNext(); )
-
 
1335
            {
-
 
1336
                Package p = it.next();
1548
            PlannedPackage p = it.next();
1337
                if (p.mBuildFile >= 0)
-
 
1338
                {
-
 
1339
                    mBuildOrder.add(p);
-
 
1340
                    p.mRippleOrder = 0;
-
 
1341
                }
-
 
1342
            }
-
 
1343
            
-
 
1344
            //  First attempt
-
 
1345
            //  Insert all the WIPs and RIPPLES into the buildset. 
-
 
1346
            //  Generate a plan and see how much the time is extended.
-
 
1347
            //
-
 
1348
            //  Don't modify mPackageCollection, although data in the 'Package' in the underlying packages may change
-
 
1349
            
1549
            
1350
            PlanResults fullPlan = null;           
-
 
1351
            fullPlan = postRipplePlan("Full", basicPlan, true);
-
 
1352
            
-
 
1353
            //  Decide with plan to use
-
 
1354
            //  At the moment we have, at most two.
-
 
1355
            //      - (basic) Current Release ripples
-
 
1356
            //      - (full) Current Release + All WIPS and RIPPLES
-
 
1357
            //
-
 
1358
            //  If we have both then if the full plan is < 20% longer than the basic plan, use the full plan
-
 
1359
            //  Otherwise we use basic plan FOLLOWED by the a MODIFIED full plan (one without the natural ripples)
-
 
1360
            //  Add the planned packages into the buildOrder
-
 
1361
 
-
 
1362
            if( !basicPlan.planCollection.isEmpty() && fullPlan != null )
-
 
1363
            {
-
 
1364
                mLogger.error("Two plan selection: {} {}, {} <= {}", basicPlan.planTime,fullPlan.planTime, basicPlan.planTime * 12, fullPlan.planTime * 10);
-
 
1365
                if ( (basicPlan.planTime * 12) <= (fullPlan.planTime * 10) )
-
 
1366
                {
-
 
1367
                    //  Use the basic plan FOLLOWED by a plan that does not include
-
 
1368
                    //      Ripples done by the basic plan
-
 
1369
                    //      WIPs/RIPPLES done in the course of doing the basic plan
-
 
1370
 
-
 
1371
                    mBuildOrder.addAll(basicPlan.planCollection);
-
 
1372
                    fullPlan = postRipplePlan("Full-Ripples", basicPlan, false);
-
 
1373
                    mBuildOrder.addAll(fullPlan.planCollection);
-
 
1374
                    
-
 
1375
                } else {
-
 
1376
                    //  Use the full plan
-
 
1377
                    mBuildOrder.addAll(fullPlan.planCollection);
-
 
1378
                }
-
 
1379
            } else if (!basicPlan.planCollection.isEmpty() ) {
-
 
1380
                // Use the basic plan
-
 
1381
                mBuildOrder.addAll(basicPlan.planCollection);
-
 
1382
            } else if ( fullPlan != null ) {
-
 
1383
                // Use the full plan
-
 
1384
                mBuildOrder.addAll(fullPlan.planCollection);
-
 
1385
            } else {
-
 
1386
                // Do not have a plan
-
 
1387
                // May have tests requests
-
 
1388
            }
-
 
1389
            
-
 
1390
            //  Now have an mBuildOrder
-
 
1391
            //  Mark the first package in the build order as the one to be built
1550
            //  Is this package 'actively used' in the current build
1392
            //
-
 
1393
            Package build = ReleaseManager.NULL_PACKAGE;
-
 
1394
            if (!mBuildOrder.isEmpty()) {
-
 
1395
                build = mBuildOrder.get(0);
-
 
1396
                build.mBuildFile = 1;
1551
            if (p.mPkg.mBuildFile >= 0)
1397
                
-
 
1398
                if ( build.mForcedRippleInstruction > 0 )
-
 
1399
                {
-
 
1400
                    mReleaseManager.markDaemonInstCompleted( build.mForcedRippleInstruction );
-
 
1401
                }
-
 
1402
 
-
 
1403
                if ( build.mTestBuildInstruction > 0 )
-
 
1404
                {
-
 
1405
                    mReleaseManager.markDaemonInstInProgress( build.mTestBuildInstruction );
-
 
1406
                }
-
 
1407
                
-
 
1408
                //  Now that we know which package we are building
-
 
1409
                //      Set the previously calculated nextVersion as the packages version number
-
 
1410
                //      Claim the version number to prevent other builds from using it. Even if doing a test build
-
 
1411
                //
-
 
1412
                if (build.mNextVersion != null)
-
 
1413
                {
-
 
1414
                    mReleaseManager.claimVersion(build.mPid, build.mNextVersion + build.mExtension, mBaseline);
-
 
1415
                    build.mVersion = build.mNextVersion;
-
 
1416
                }
-
 
1417
            }
-
 
1418
            
-
 
1419
            //
-
 
1420
            //  Massage the package collection
-
 
1421
            //      Replace WIP/TEST/RIPPLE so that the mPackageCollection is a collection of packages we would like in the release
-
 
1422
            //      Don't replace those that we can't build due to errors
-
 
1423
            //  
-
 
1424
            //  TODO - Not sure this does anything for us. Once upon a time it might have been nice, but now it may be confusing
-
 
1425
            //
-
 
1426
            ArrayList<Package> buildCandidates = new ArrayList<Package>();
-
 
1427
            buildCandidates.addAll(mPackageCollectionTest);
-
 
1428
            buildCandidates.addAll(mPackageCollectionWip);
-
 
1429
            buildCandidates.addAll(mPackageCollectionRipple);
-
 
1430
 
-
 
1431
            for (Iterator<Package> it = buildCandidates.iterator(); it.hasNext(); )
-
 
1432
            {
1552
            {
1433
                Package p = it.next();
1553
                for (Iterator<String> it2 = p.mPkg.mDependencyCollection.iterator(); it2.hasNext(); )
1434
                if ( p.mBuildFile >= 0 )
-
 
1435
                {
1554
                {
1436
                    Package pReleased = findPackage(p.mAlias);
1555
                    String alias = it2.next();
-
 
1556
                    if (  pkg.mPkg.mAlias.compareTo( alias ) == 0  ) {
1437
                    if ( pReleased != ReleaseManager.NULL_PACKAGE)
1557
                        //  Have found a consumer of 'pkg'
1438
                    {
1558
                        usedBy.add(p);
1439
                        int index = mReleaseManager.findPackageLastIndex;
1559
                        if (rippleOrder >= 0)
1440
                        mPackageCollection.set(index, p);
1560
                            p.mBuildLevel = rippleOrder;
1441
                        p.mIsNotReleased = false;
1561
                        break;
1442
                    }
1562
                    }
1443
                }
1563
                }
1444
            }
1564
            }
1445
                        
-
 
1446
            
-
 
1447
            //
-
 
1448
            //  To fit in with the old algorithm ( ie: could be improved )
-
 
1449
            //  Insert marks into all packages
-
 
1450
            //  Not sure exactly why - Its used in the generation of the ant build file
-
 
1451
            //                     Want to set mNoBuildReason, mBuildFile
-
 
1452
            //
-
 
1453
            //      Package we have selected to build: 0     , 1
-
 
1454
            //      Package we could have built      : 0     , 2
-
 
1455
            //      Packages we can't build          : reason, 3
-
 
1456
            //      Packages that are OK             : 3     , 3
-
 
1457
            //      ????                             : 0     , 3
-
 
1458
            
-
 
1459
            for (Iterator<Package> it = mPackageCollectionAll.iterator(); it.hasNext(); )
-
 
1460
            {
-
 
1461
                Package p = it.next();
-
 
1462
                if (p == build ) {
-
 
1463
                    p.mNoBuildReason = 0;
-
 
1464
                    p.mBuildFile = 1;
-
 
1465
                } 
-
 
1466
                else if ( p.mBuildFile < 0 )
-
 
1467
                {
-
 
1468
                    p.mNoBuildReason = p.mBuildFile;
-
 
1469
                    p.mBuildFile = 3;
-
 
1470
                }
-
 
1471
                else if (p.mBuildReason != null)
-
 
1472
                {
-
 
1473
                    p.mNoBuildReason = 0;
-
 
1474
                    p.mBuildFile = 2;
-
 
1475
                }
-
 
1476
                else
-
 
1477
                {
-
 
1478
                    p.mNoBuildReason = 0;
-
 
1479
                    p.mBuildFile = 3;
-
 
1480
                }
-
 
1481
            }
-
 
1482
 
-
 
1483
        }
-
 
1484
        else
-
 
1485
        {
-
 
1486
            //  Escrow
-
 
1487
            //  The basic plan is the escrow build order
-
 
1488
            mBuildOrder = basicPlan.planCollection;
-
 
1489
        }
1565
        }
1490
 
-
 
1491
        mLogger.error("Final Plan");
-
 
1492
        for (Iterator<Package> it = mBuildOrder.iterator(); it.hasNext(); )
-
 
1493
        {
1566
        
1494
            Package p = it.next();
-
 
1495
            mLogger.error("Plan: {} {}", p.mRippleOrder, p.mAlias);
-
 
1496
        }
-
 
1497
           
1567
        return usedBy;
1498
 
-
 
1499
    }
1568
    }
1500
 
1569
    
1501
    /** 
1570
    /** 
1502
     *  Calculate a collection of packages that actively use the named package
1571
     *  Calculate a collection of packages that use the named package
1503
     *  A consumer package does NOT use the named package,
-
 
1504
     *      If the consumer is an SDK or is Pegged
-
 
1505
     *      If the consumer is marked as advisoryRipple
-
 
1506
     *      If the consumer cannot be built
-
 
1507
     *   
1572
     *   
1508
     * @param pkg - Package to process
1573
     * @param pkg - Package to process
1509
     * @param pkgCollection - collection of packages to scan
1574
     * @param pkgCollection - collection of packages to scan
1510
     * @param rippleOrder - Set the ripple oder, if >= 0
-
 
1511
     *
1575
     *
1512
     * @return A collection of packages that actively 'use' the specified package
1576
     * @return A collection of packages that actively 'use' the specified package
1513
 
1577
 
1514
     */
1578
     */
1515
    private ArrayList<Package> usedByPackages(Package pkg, ArrayList<Package> pkgCollection, int rippleOrder) {
1579
    private ArrayList<Package> usedByAnyPackages(Package pkg, ArrayList<Package> pkgCollection) {
1516
        
1580
        
1517
        ArrayList<Package> usedBy = new ArrayList<Package>();
1581
        ArrayList<Package> usedBy = new ArrayList<Package>();
1518
        
1582
        
1519
        for (Iterator<Package> it = pkgCollection.iterator(); it.hasNext(); )
1583
        for (Iterator<Package> it = pkgCollection.iterator(); it.hasNext(); )
1520
        {
1584
        {
1521
            Package p = it.next();
1585
            Package p = it.next();
1522
            
1586
            
1523
            //  Is this package 'actively used' in the current build
1587
            for (Iterator<String> it2 = p.mDependencyCollection.iterator(); it2.hasNext(); )
1524
            if (p.mBuildFile >= 0)
-
 
1525
            {
1588
            {
1526
                for (Iterator<String> it2 = p.mDependencyCollection.iterator(); it2.hasNext(); )
-
 
1527
                {
-
 
1528
                    String alias = it2.next();
1589
                String alias = it2.next();
1529
                    if (  pkg.mAlias.compareTo( alias ) == 0  ) {
1590
                if (  pkg.mAlias.compareTo( alias ) == 0  ) {
1530
                        //  Have found a consumer of 'pkg'
-
 
1531
                        usedBy.add(p);
1591
                    usedBy.add(p);
1532
                        if (rippleOrder >= 0)
-
 
1533
                            p.mRippleOrder = rippleOrder;
-
 
1534
                        break;
1592
                    break;
1535
                    }
-
 
1536
                }
1593
                }
1537
            }
1594
            }
1538
        }
1595
        }
1539
        
1596
        
1540
        return usedBy;
1597
        return usedBy;
Line 1710... Line 1767...
1710
        mLogger.info("findPackage returned {}", retVal.mName);
1767
        mLogger.info("findPackage returned {}", retVal.mName);
1711
        return retVal;
1768
        return retVal;
1712
    }
1769
    }
1713
    
1770
    
1714
    /**
1771
    /**
1715
     * Sets the mBuildFile to -5 (indirectly dependent on package versions which are not reproducible) 
1772
     * Sets the mBuildFile to the specified value for the package
1716
     * for the package and all dependent packages that are a part of the release set.
1773
     * Does not handle dependent packages - this will be done later  
1717
     *  
1774
     *  
1718
     * @param p             The package being excluded 
1775
     * @param p             The package being excluded 
1719
     * @param rootPvId      The PVID of the package that is causing the exclusion. Null or -ve values are special
1776
     * @param rootPvId      The PVID of the package that is causing the exclusion. Null or -ve values are special
1720
     *                      This package is the root cause, -2: Excluded by Ripple Stop 
1777
     *                      This package is the root cause, -2: Excluded by Ripple Stop 
1721
     * @param rootCause     Text message. Max 50 characters imposed by RM database 
1778
     * @param rootCause     Text message. Max 50 characters imposed by RM database 
1722
     * @param list          If not null, add build exclusion to specified list, else use default(mBuildExclusionCollection) list. Allows insertions while iterating the list.
-
 
1723
     * @param be            If not null, process provided BuildExclusion element, otherwise find-existing/create a BuildExclusion element
-
 
1724
     * @param dependentToo  True: Exclude all packages that depend on the excluded package 
-
 
1725
     * @param depWipsToo    False: Don't exclude WIP packages that depend on the excluded package
1779
     * @param reason        New value for mBuildFile
1726
     */
1780
     */
1727
    private void rippleBuildExclude(Package p, int rootPvId, String rootCause, ListIterator<BuildExclusion> list, BuildExclusion be, boolean dependentToo, boolean depWipsToo )
1781
    private void rippleBuildExclude(Package p, int rootPvId, String rootCause, int reason )
1728
    {
1782
    {
1729
        mLogger.debug("rippleBuildExclude");
1783
        mLogger.debug("rippleBuildExclude");
1730
     
1784
     
1731
        if ( p.mBuildFile == 0 || p.mBuildFile == 1 )
1785
        if ( p.mBuildFile == 0 || p.mBuildFile == 1 )
1732
        {
1786
        {
1733
            p.mBuildFile = -5;
1787
            p.mBuildFile = reason;
1734
            mLogger.info("rippleBuildExclude set mBuildFile to -5 for package {}", p.mAlias );
1788
            mLogger.info("rippleBuildExclude set mBuildFile to -5 for package {}", p.mAlias );
1735
 
1789
            
-
 
1790
            //  Scan the complete collection looking for a matching item
-
 
1791
            //  If found, process it, else add it (unprocessed)
1736
            if ( be != null )
1792
            boolean found = false;
-
 
1793
            for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
1737
            {
1794
            {
-
 
1795
                BuildExclusion buildExclusion = it.next();
-
 
1796
 
-
 
1797
                if ( buildExclusion.compare(p.mId, rootPvId, rootCause))
-
 
1798
                {
1738
                be.setProcessed();
1799
                    buildExclusion.setProcessed();
-
 
1800
                    found = true;
-
 
1801
                    break;
-
 
1802
                }
1739
            }
1803
            }
-
 
1804
 
1740
            else
1805
            if (!found)
1741
            {
1806
            {
1742
                //  If no be item has been provided, then scan the complete collection looking for a matching item
1807
                // Entry not found in the mBuildExclusionCollection
1743
                //  If found, process it, else add it (unprocessed)
1808
                // Mark all occurrences for this package as processed
1744
                boolean found = false;
1809
                // These will be superseded by a new build exclusion entry
1745
                for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
1810
                for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
1746
                {
1811
                {
1747
                    BuildExclusion buildExclusion = it.next();
1812
                    BuildExclusion buildExclusion = it.next();
1748
 
1813
 
1749
                    if ( buildExclusion.compare(p.mId, rootPvId, rootCause))
1814
                    if ( buildExclusion.compare(p.mId))
1750
                    {
1815
                    {
1751
                        buildExclusion.setProcessed();
1816
                        buildExclusion.setProcessed();
1752
                        found = true;
-
 
1753
                        break;
-
 
1754
                    }
-
 
1755
                }
-
 
1756
 
-
 
1757
                if (!found)
-
 
1758
                {
-
 
1759
                    // Entry not found in the mBuildExclusionCollection
-
 
1760
                    // Mark all occurrences for this package as processed
-
 
1761
                    // These will be superseded by a new build exclusion entry
-
 
1762
                    for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
-
 
1763
                    {
-
 
1764
                        BuildExclusion buildExclusion = it.next();
-
 
1765
 
-
 
1766
                        if ( buildExclusion.compare(p.mId))
-
 
1767
                        {
-
 
1768
                            buildExclusion.setProcessed();
-
 
1769
                        }
-
 
1770
                    }
-
 
1771
 
-
 
1772
                    BuildExclusion buildExclusion = new BuildExclusion(p.mId, rootPvId, rootCause, p.mTestBuildInstruction);
-
 
1773
 
-
 
1774
                    //
-
 
1775
                    //  Add the new build exclusion to a list
-
 
1776
                    //    Either the default list or a user-specified list
-
 
1777
                    if ( list == null )
-
 
1778
                    {
-
 
1779
                        mBuildExclusionCollection.add(buildExclusion);
-
 
1780
                    }
-
 
1781
                    else
-
 
1782
                    {
-
 
1783
                        // must use the ListIterator interface to add to the collection whilst iterating through it
-
 
1784
                        list.add(buildExclusion);
-
 
1785
                    }
1817
                    }
1786
                }
1818
                }
1787
            }
-
 
1788
 
-
 
1789
            //  Locate ALL packages that depend on this package and exclude them too
-
 
1790
            //  This process will be recursive
-
 
1791
            //    Not sure that this it is efficient 
-
 
1792
            //  Only ripple a build exclusion through for packages that are a part of the full release set
-
 
1793
            //  NewWIPs, ForcedRipples and TestBuilds will not force consumer packages to be excluded
-
 
1794
            //
-
 
1795
            if ( ! p.mIsNotReleased && dependentToo)
-
 
1796
            {
-
 
1797
                for (Iterator<Package> it = mPackageCollectionAll.iterator(); it.hasNext(); )
-
 
1798
                {
-
 
1799
                    Package pkg = it.next();
-
 
1800
                    
-
 
1801
                    //  Skip myself
-
 
1802
                    if (pkg == p)
-
 
1803
                        continue;
-
 
1804
 
-
 
1805
                    //  Ignore dependent WIPS if required
-
 
1806
                    if (!depWipsToo && pkg.mDirectlyPlanned)
-
 
1807
                        continue;
-
 
1808
                    
-
 
1809
                    for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
-
 
1810
                    {
-
 
1811
                        Package dependency = it2.next();
-
 
1812
 
1819
 
1813
                        if ( dependency == p )
-
 
1814
                        {
-
 
1815
                            rippleBuildExclude( pkg, rootPvId, null, list, null, dependentToo, depWipsToo );
1820
                BuildExclusion buildExclusion = new BuildExclusion(p.mId, rootPvId, rootCause, p.mTestBuildInstruction);
1816
                            break;
-
 
1817
                        }
-
 
1818
                    }
-
 
1819
 
1821
 
1820
                }
1822
                //
-
 
1823
                //  Add the new build exclusion to a list
-
 
1824
                //    Either the default list or a user-specified list
-
 
1825
                mBuildExclusionCollection.add(buildExclusion);
1821
            }
1826
            }
1822
        }
1827
        }
-
 
1828
 
1823
        mLogger.info("rippleBuildExclude set {} {}", p.mName, p.mBuildFile);
1829
        mLogger.info("rippleBuildExclude set {} {}", p.mAlias, p.mBuildFile);
1824
    }
1830
    }
1825
 
1831
 
1826
    /**Simple XML string escaping
1832
    /**Simple XML string escaping
1827
     * 
1833
     * 
1828
     * @param xml		- String to escape
1834
     * @param xml		- String to escape
Line 1944... Line 1950...
1944
                // Insert build exclusion information
1950
                // Insert build exclusion information
1945
                xml.addComment("mBuildExclusionCollection");
1951
                xml.addComment("mBuildExclusionCollection");
1946
                for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
1952
                for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
1947
                {
1953
                {
1948
                    BuildExclusion buildExclusion = it.next();
1954
                    BuildExclusion buildExclusion = it.next();
1949
                    if (!buildExclusion.isProcessed())
1955
                    //if (!buildExclusion.isProcessed())
1950
                    {
1956
                    {
1951
                        xml.addComment(buildExclusion.info());
1957
                        xml.addComment(buildExclusion.info());
1952
                    }
1958
                    }
1953
                }
1959
                }
1954
                
1960
                
1955
                // UTF Support
1961
                // UTF Support
1956
                // Insert build Plan
1962
                // Insert build Plan
1957
                if (mDaemon)
1963
                if (mDaemon)
1958
                {
1964
                {
1959
                    xml.addComment("mBuildOrder");
1965
                    xml.addComment("mBuildOrder");
1960
                    int order = 0;
-
 
1961
                    for (Iterator<Package> it = mBuildOrder.iterator(); it.hasNext(); )
1966
                    for (Iterator<PlannedPackage> it = mBuildOrder.iterator(); it.hasNext(); )
1962
                    {
1967
                    {
1963
                        Package p = it.next();
1968
                        PlannedPackage p = it.next();
1964
                        String comment =
1969
                        String comment =
1965
                                "pvid="+ p.mId +
1970
                                "pvid="+ p.mPkg.mId +
1966
                                " order=" + (++order) +
1971
                                " order=" + p.mBuildLevel +
1967
                                " Rorder=" + (p.mRippleOrder) +
-
 
1968
                                " time=" + p.mBuildTime +
1972
                                " time=" + p.mPkg.mBuildTime +
1969
                                " name=\"" + p.mAlias + "\"";
1973
                                " name=\"" + p.mPkg.mAlias + "\"";
1970
                        xml.addComment(comment);
1974
                        xml.addComment(comment);
1971
                    }
1975
                    }
1972
                }
1976
                }
1973
            }
1977
            }
1974
 
1978