BuildUserVars and BuildNameDescriptionSetter plug-ins for jenkins plug-in learning

The execution order of BuildUserVars and BuildNameDescriptionSetter plug-ins in jenkins plug-in learning

The two plug-ins BuildUserVars and BuildNameDescriptionSetter have been used before, 
Through BuildUserVars, you can get who triggered the build. This plug-in will set a similar environment variable BUILD_USER 
Then set the environment variable BUILD_USER to the build name through the BuildNameDescriptionSetter plug-in
 It is convenient to see which build is triggered by which person / timer in the construction history

The BuildNameDescriptionSetter plug-in has options "Set build name before build starts" and "Set build name after build ends"
It is found that only when "Set build name after build ends" can the variable "BUILD_USER" be obtained. Why???

It is found that BuildUserVars is executed after BuildNameDescriptionSetter
 The execution order is similar to the following
 ① "Set build name before build starts" of BuildNameDescriptionSetter
 ② Then the BuildUserVars plug-in sets user related environment variables
 ③ Finally, "Set build name after build ends" of BuildNameDescriptionSetter

You can also see the BuildNameDescriptionSetter plug-in on the BuildUserVars plug-in in the "Build Environment" section of the job configuration interface
 Why is this sort?

Through search, it is found that the order of plug-in Extension is provided by an ordinal value. The larger the value, the higher the priority. By default, this value of the two plug-ins is 0
 If they are all 0, they will be sorted according to the displayName of the plug-in

If modified, the ordinal value of BuildUserVars plug-in can be set to be greater than 0  
The second method is to change the display name to change the sorting position
    @Extension(ordinal = 1) //  The ordinal value is set to greater than 0
    public static class DescriptorImpl extends BuildWrapperDescriptor {


        @Override
        public boolean isApplicable(AbstractProject<?, ?> item) {
            return true;
        }

        @Override
        public String getDisplayName() {
            return EXTENSION_DISPLAY_NAME;
        }
    }
	
    private static final String EXTENSION_DISPLAY_NAME = "Set jenkins user build variables";

	/**
     * Returns all the registered {@link BuildWrapper} descriptors.
     */
    // for compatibility we can't use BuildWrapperDescriptor
    public static DescriptorExtensionList<BuildWrapper,Descriptor<BuildWrapper>> all() {
        // use getDescriptorList and not getExtensionList to pick up legacy instances
        return Jenkins.getInstance().<BuildWrapper,Descriptor<BuildWrapper>>getDescriptorList(BuildWrapper.class);
    }

    public  DescriptorExtensionList<T,D> getDescriptorList(Class<T> type) { //type = BuildWrapper.class hudson.tasks.BuildWrapper
        return descriptorLists.computeIfAbsent(type, key -> DescriptorExtensionList.createDescriptorList(this, key));
        //If there is a value corresponding to key in descriptorLists, it can be obtained directly. If it is not used, create a new one through DescriptorExtensionList.createDescriptorList(this, key)

    }

descriptorLists There are a lot of initial ones in this DescriptorExtensionList, And what we're looking for is {Class@10416} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@13112}  size = 2 This corresponds to.
descriptorLists = {ConcurrentHashMap@13015}  size = 14
 {Class@10349} "class hudson.views.ListViewColumn" -> {DescriptorExtensionList@13102}  size = 8
 {Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@13103}  size = 22
 {Class@10272} "class hudson.model.JobProperty" -> {DescriptorExtensionList@13104}  size = 3
 {Class@10289} "class hudson.scm.SCM" -> {DescriptorExtensionList@13105}  size = 1
 {Class@8453} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@13106}  size = 8
 {Class@10312} "class hudson.tasks.Publisher" -> {Publisher$DescriptorExtensionListImpl@13107}  size = 6
 {Class@10253} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@13108}  size = 7
 {Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@13109}  size = 6
 {Class@10370} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@13110}  size = 1
 {Class@7731} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@13111}  size = 4
 {Class@10416} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@13112}  size = 2
 {Class@8443} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@13113}  size = 3
 {Class@10323} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@13114}  size = 1
 {Class@10317} "class hudson.tasks.Builder" -> {DescriptorExtensionList@13115}  size = 6

public static DescriptorExtensionList<T,D> createDescriptorList(Jenkins jenkins, Class<T> describableType) {
    if (describableType == (Class) Publisher.class) {
        return (DescriptorExtensionList) new Publisher.DescriptorExtensionListImpl(jenkins);
    }
    return new DescriptorExtensionList<>(jenkins, describableType);
}


@Deprecated  This method is no longer used. The parameter passed in is hudson It's just an example. We see that it's also mandatory hudson Convert to jenkins Example.public class Hudson extends Jenkins
public static DescriptorExtensionList<T,D> createDescriptorList(Hudson hudson, Class<T> describableType) {
    return (DescriptorExtensionList)createDescriptorList((Jenkins)hudson,describableType);
}

Through return descriptorlists.computeifabsent (type, key - > descriptorextensionlist. Createdescriptorlist (this, key)); and breakpoint debugging, it is found that

Lazy load!

//First, restart debug. That is, restart jenkins
descriptorLists = {ConcurrentHashMap@10542}  size = 0  Instantiate this for the first time class hudson.node_monitors.NodeMonitor

descriptorLists = {ConcurrentHashMap@10541}  size = 1 2nd time. Ready to instantiate this class jenkins.model.GlobalConfiguration
 {Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741}  size = 6
//By this time, jenkins has been started. If you click job later, you will continue to instantiate the following

descriptorLists = {ConcurrentHashMap@10541}  size = 2   The third time class hudson.model.PageDecorator
 {Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557}  size = 22
 {Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741}  size = 6

descriptorLists = {ConcurrentHashMap@10541}  size = 3
 {Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557}  size = 22
 {Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741}  size = 6
 {Class@8454} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11911}  size = 8

descriptorLists = {ConcurrentHashMap@10541}  size = 3  4th time class jenkins.model.GlobalConfiguration
 {Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557}  size = 22
 {Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741}  size = 6
 {Class@8454} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11911}  size = 8
//At this time, it is a few instances that are loaded after clicking the job

descriptorLists = {ConcurrentHashMap@10541}  size = 4    5th time interface hudson.model.TopLevelItem
 {Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557}  size = 22
 {Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741}  size = 6
 {Class@8440} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12854}  size = 3
 {Class@8454} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11911}  size = 8

//Lazy load!
descriptorLists = {ConcurrentHashMap@10542}  size = 5   6th time     class jenkins.model.BuildDiscarder
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22

//Add another. class jenkins.model.BuildDiscarder!!!
descriptorLists = {ConcurrentHashMap@10542}  size = 6
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22

//Add another. class hudson.model.ParameterDefinition!!! Parameter stage
descriptorLists = {ConcurrentHashMap@10542}  size = 7
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22

//Another. class hudson.scm.SCM!!
descriptorLists = {ConcurrentHashMap@10542}  size = 8
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22

//Another. class jenkins.scm.SCMCheckoutStrategy!!! This is basically the configuration of the job configuration page from top to bottom. Code check-out stage
descriptorLists = {ConcurrentHashMap@10542}  size = 9
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22

//Add another class hudson.triggers.Trigger!!! This is basically the configuration of job configuration page from top to bottom. Trigger stage
descriptorLists = {ConcurrentHashMap@10542}  size = 10
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770}  size = 4
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22



//Another class hudson.tasks.buildwrapper has been added,!! buildwrapper stage. Build environment settings. That one
descriptorLists = {ConcurrentHashMap@10542}  size = 11
 {Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804}  size = 2
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770}  size = 4
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22

//Add another class hudson.tasks.Builder!!! Construction phase
descriptorLists = {ConcurrentHashMap@10542}  size = 12
 {Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804}  size = 2
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@10318} "class hudson.tasks.Builder" -> {DescriptorExtensionList@12845}  size = 6
 {Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770}  size = 4
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1

//Added another class hudson.tasks.Publisher
descriptorLists = {ConcurrentHashMap@10542}  size = 13
 {Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804}  size = 2
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@10318} "class hudson.tasks.Builder" -> {DescriptorExtensionList@12845}  size = 6
 {Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770}  size = 4
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22
 {Class@10313} "class hudson.tasks.Publisher" -> {Publisher$DescriptorExtensionListImpl@13032}  size = 6
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1



descriptorLists = {ConcurrentHashMap@10542}  size = 14
 {Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804}  size = 2
 {Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637}  size = 1
 {Class@10318} "class hudson.tasks.Builder" -> {DescriptorExtensionList@12845}  size = 6
 {Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770}  size = 4
 {Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528}  size = 22
 {Class@10313} "class hudson.tasks.Publisher" -> {Publisher$DescriptorExtensionListImpl@13032}  size = 6
 {Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571}  size = 3
 {Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527}  size = 6
 {Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722}  size = 1
 {Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546}  size = 8
 {Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672}  size = 7
 {Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401}  size = 3
 {Class@10350} "class hudson.views.ListViewColumn" -> {DescriptorExtensionList@13278}  size = 8
 {Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696}  size = 1

public abstract class Project<P extends Project<P,B>,B extends Build<P,B>>
    extends AbstractProject<P,B> implements SCMTriggerItem, Saveable, ProjectWithMaven, BuildableItemWithBuildWrappers {
    @Override
    protected void submit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException {
        super.submit(req,rsp);

        JSONObject json = req.getSubmittedForm();

        getBuildWrappersList().rebuild(req,json, BuildWrappers.getFor(this));
        getBuildersList().rebuildHetero(req,json, Builder.all(), "builder");
        getPublishersList().rebuildHetero(req, json, Publisher.all(), "publisher");
    }
//In the Project class submit()Method will be called to BuildWrappers.getFor(this) Method. submit()The way is to click job In the configuration save Button triggered.


public class BuildWrappers {
    /**
     * List up all {@link BuildWrapperDescriptor}s that are applicable for the given project.
     *
     * @return
     *      The signature doesn't use {@link BuildWrapperDescriptor} to maintain compatibility
     *      with {@link BuildWrapper} implementations before 1.150.
     */
    public static List<Descriptor<BuildWrapper>> getFor(AbstractProject<?, ?> project) {
        List<Descriptor<BuildWrapper>> result = new ArrayList<>();
        Descriptor pd = Jenkins.getInstance().getDescriptor((Class)project.getClass());

        for (Descriptor<BuildWrapper> w : BuildWrapper.all()) {
            if (pd instanceof AbstractProjectDescriptor && !((AbstractProjectDescriptor)pd).isApplicable(w))
                continue;
            if (w instanceof BuildWrapperDescriptor) {
                BuildWrapperDescriptor bwd = (BuildWrapperDescriptor) w;
                if(bwd.isApplicable(project))
                    result.add(bwd);
            } else {
                // old BuildWrapper that doesn't implement BuildWrapperDescriptor
                result.add(w);
            }
        }
        return result;
    }
}

//By calling the getFor()Method.
//Call to for (Descriptor<BuildWrapper> w : BuildWrapper.all()) { It will be implemented to  public @Nonnull Iterator<T> iterator() { inside

    @Override
    public @Nonnull Iterator<T> iterator() {
        // we need to intercept mutation, so for now don't allow Iterator.remove
        return new AdaptedIterator<ExtensionComponent<T>,T>(Iterators.readOnly(ensureLoaded().iterator())) {
            protected T adapt(ExtensionComponent<T> item) {
                return item.getInstance();
            }
        };
    }
//Then?iterator() Method will callensureLoaded() Method

    private List<ExtensionComponent<T>> ensureLoaded() {
        if(extensions!=null)
            return extensions; // already loaded
        if (jenkins.getInitLevel().compareTo(InitMilestone.PLUGINS_PREPARED)<0)
            return legacyInstances; // can't perform the auto discovery until all plugins are loaded, so just make the legacy instances visible

        synchronized (getLoadLock()) {
            if(extensions==null) {
                List<ExtensionComponent<T>> r = load();
                r.addAll(legacyInstances);
                extensions = sort(r);
            }
            return extensions;
        }
    }
//Last ensureLoaded() It's going to be right List Sort. 
    /**
     * If the {@link ExtensionList} implementation requires sorting extensions,
     * override this method to do so.
     *
     * <p>
     * The implementation should copy a list, do a sort, and return the new instance.
     */
    protected List<ExtensionComponent<T>> sort(List<ExtensionComponent<T>> r) {
        r = new ArrayList<>(r);
        Collections.sort(r);
        return r;
    }

//When sorting, it will call the extension component compareTo(ExtensionComponent<T> that) Method.


DescriptorExtensionList Stored in ExtensionComponent A collection of. Then? ExtensionComponent There will be one compareTo Method of comparing order.
//The order of comparison is the execution order of the BuildWrapper type plug-ins.
//If the coordinate value is set. The higher the value, the earlier the execution (that is job No settings ordinal Just compare displayname. Compared by string.
//If you fail to compare displayname, you will comparegetClass().getName(),Also compare by string.

this = {DescriptorExtensionList@12209}  size = 2
 0 = {BuildNameSetter$DescriptorImpl@12212}
 1 = {BuildUser$DescriptorImpl@12213}
    /**
     * Sort {@link ExtensionComponent}s in the descending order of {@link #ordinal()}.
     */
    public int compareTo(ExtensionComponent<T> that) {
        double a = this.ordinal();
        double b = that.ordinal();
        if (a>b)    return -1;
        if (a<b)    return 1;

        // make the order bit more deterministic among extensions of the same ordinal
        if (this.instance instanceof Descriptor && that.instance instanceof Descriptor) {
            try {
                return Util.fixNull(((Descriptor)this.instance).getDisplayName()).compareTo(Util.fixNull(((Descriptor)that.instance).getDisplayName()));
            } catch (RuntimeException | LinkageError x) {
                LOG.log(Level.WARNING, null, x);
            }
        }
        return this.instance.getClass().getName().compareTo(that.instance.getClass().getName());
    }


Here I used the method of modifying the display of the build user vars plugin plug-in. I thought the display name he set was not good.

    private static final String EXTENSION_DISPLAY_NAME = "Set jenkins user build variables";
    private static final String EXTENSION_DISPLAY_NAME = "Set Build  User Variables";

Please refer to https://github.com/mamh-java/build-user-vars-plugin

Tags: jenkins JSON github Java

Posted on Sun, 26 Apr 2020 03:00:02 -0700 by kellz