Skip to content
Permalink
Browse files

Merge pull request #30 from jglick/dynamic-load-JENKINS-33106

[JENKINS-33106] Dynamic CustomOrganizationFolderDescriptor registration
  • Loading branch information...
jglick committed Mar 11, 2016
2 parents 2c30f50 + be0c950 commit 61ec9d9144df9b4bd99641bc0cb0c5e9319324f3
@@ -64,8 +64,7 @@
</scm>

<properties>
<jenkins.version>1.609.1</jenkins.version>
<java.level>6</java.level>
<jenkins.version>1.625.1</jenkins.version>
</properties>

<repositories>
@@ -26,6 +26,7 @@

import hudson.Extension;
import hudson.ExtensionList;
import hudson.ExtensionListListener;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
import hudson.model.Descriptor;
@@ -35,6 +36,10 @@
import hudson.model.TopLevelItemDescriptor;
import hudson.model.View;
import hudson.model.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.scm.api.SCMNavigatorDescriptor;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
@@ -46,6 +51,8 @@
@Restricted(NoExternalUse.class)
public class CustomOrganizationFolderDescriptor extends TopLevelItemDescriptor {

private static final Logger LOGGER = Logger.getLogger(CustomOrganizationFolderDescriptor.class.getName());

public final SCMNavigatorDescriptor delegate;

CustomOrganizationFolderDescriptor(SCMNavigatorDescriptor delegate) {
@@ -70,19 +77,52 @@ public TopLevelItem newInstance(ItemGroup parent, String name) {
return p;
}

// TODO better for DescriptorVisibilityFilter to allow items to be added as well as removed
@SuppressWarnings("deprecation") // dynamic registration intentional here
@Override
public String toString() {
return "CustomOrganizationFolderDescriptor[" + delegate.getId() + "]";
}

// TODO HACK ALERT! better for DescriptorVisibilityFilter to allow items to be added as well as removed

@Initializer(after=InitMilestone.PLUGINS_STARTED, before=InitMilestone.EXTENSIONS_AUGMENTED)
public static void addSpecificDescriptors() {
LOGGER.fine("ran addSpecificDescriptors");
doAddSpecificDescriptors();
ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class).addListener(new ListenerImpl());
}

private static class ListenerImpl extends ExtensionListListener {

@Override
public void onChange() {
doAddSpecificDescriptors();
}

}

@SuppressWarnings("deprecation") // dynamic registration intentional here
private static void doAddSpecificDescriptors() {
LOGGER.fine("ran doAddSpecificDescriptors");
List<CustomOrganizationFolderDescriptor> old = new ArrayList<>();
for (TopLevelItemDescriptor d : all()) {
if (d instanceof CustomOrganizationFolderDescriptor) {
old.add((CustomOrganizationFolderDescriptor) d);
}
}
LOGGER.log(Level.FINE, "clearing {0}", old);
all().removeAll(old);
if (ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class).isEmpty()) {
LOGGER.fine("no MultiBranchProjectFactoryDescriptor");
return; // nothing like workflow-multibranch installed, so do not even offer this option
}
TopLevelItemDescriptor.all().size(); // TODO must force ExtensionList.ensureLoaded to be called, else .add adds to both .legacyInstances and .extensions, then later .ensureLoaded adds two copies!
for (SCMNavigatorDescriptor d : ExtensionList.lookup(SCMNavigatorDescriptor.class)) {
if (d.newInstance((String) null) != null) {
LOGGER.log(Level.FINE, "adding {0}", d.getId());
TopLevelItemDescriptor.all().add(new CustomOrganizationFolderDescriptor(d));
}
}
LOGGER.fine("done");
}

/**
@@ -93,6 +133,7 @@ public static void addSpecificDescriptors() {

@Override
public boolean filter(Object context, Descriptor descriptor) {
LOGGER.log(Level.FINER, "filtering {0}", descriptor.getId());
if (descriptor instanceof OrganizationFolder.DescriptorImpl && (context instanceof View || context instanceof ViewGroup)) {
return false;
}
@@ -31,6 +31,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Util;
import hudson.XmlFile;
import hudson.model.CauseAction;
import hudson.model.Descriptor;
import hudson.model.Item;
import hudson.model.ItemGroup;
@@ -357,20 +358,11 @@ public void observe(@NonNull SCMHead head, @NonNull SCMRevision revision) {

private void scheduleBuild(BranchProjectFactory<P,R> factory, final P item, SCMRevision revision, TaskListener listener) {
listener.getLogger().println("Scheduling build for branch: " + factory.getBranch(item).getName());
if (item instanceof ParameterizedJobMixIn.ParameterizedJob) {
// TODO 1.621+ use standard method
ParameterizedJobMixIn scheduler = new ParameterizedJobMixIn() {
@Override
protected Job asJob() {
return item;
}
};
if (scheduler.scheduleBuild(0, new SCMTrigger.SCMTriggerCause("Branch indexing"))) {
try {
factory.setRevisionHash(item, revision);
} catch (IOException e) {
e.printStackTrace(listener.error("Could not update last revision hash"));
}
if (ParameterizedJobMixIn.scheduleBuild2(item, 0, new CauseAction(new SCMTrigger.SCMTriggerCause("Branch indexing"))) != null) {
try {
factory.setRevisionHash(item, revision);
} catch (IOException e) {
e.printStackTrace(listener.error("Could not update last revision hash"));
}
}
}
@@ -88,6 +88,16 @@ public void someNavigatorSomeFactoryInstalled() throws Exception {
@TestExtension("someNavigatorSomeFactoryInstalled")
public static class SomeNavigatorSomeFactoryInstalledDescriptor2 extends OrganizationFolderTest.MockFactoryDescriptor {}

@Issue("JENKINS-33106")
@SuppressWarnings("deprecation") // ExtensionList.add simulating dynamic installation
@Test
public void dynamicLoad() throws Exception {
assertEquals(Collections.emptyList(), newItemTypes());
ExtensionList.lookup(SCMNavigatorDescriptor.class).add(new SomeNavigatorSomeFactoryInstalledDescriptor1());
ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class).add(new SomeNavigatorSomeFactoryInstalledDescriptor2());
assertEquals(Collections.singletonList("MockNavigator"), newItemTypes());
}

@Issue("JENKINS-31949")
@Test
public void insideFolder() throws Exception {

0 comments on commit 61ec9d9

Please sign in to comment.
You can’t perform that action at this time.