diff --git a/changelog.html b/changelog.html index db0ddfc1bdc6feb2540c353505f05f74f9d4518b..9620b517a525333affc129e4dcb6c345aa225e0c 100644 --- a/changelog.html +++ b/changelog.html @@ -84,6 +84,10 @@ Upcoming changes
  • Global search box now remembers entered text (issue 18192) +
  • + Add extension point to allow plugins to contribute to the checking of + assigned labels. + (issue 20514) diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 32584041b4420ccac9f6285f0edf0231d68b4df7..7321e88096d058e05deb9b083640ba0ea6a3db84 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -29,6 +29,7 @@ package hudson.model; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import hudson.EnvVars; +import hudson.ExtensionPoint; import hudson.Functions; import antlr.ANTLRException; import hudson.AbortException; @@ -103,6 +104,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.stapler.Ancestor; +import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.ForwardToView; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; @@ -2209,7 +2211,8 @@ public abstract class AbstractProject

    ,R extends A return true; } - public FormValidation doCheckAssignedLabelString(@QueryParameter String value) { + public FormValidation doCheckAssignedLabelString(@AncestorInPath AbstractProject project, + @QueryParameter String value) { if (Util.fixEmpty(value)==null) return FormValidation.ok(); // nothing typed yet try { @@ -2228,6 +2231,15 @@ public abstract class AbstractProject

    ,R extends A } return FormValidation.warning(Messages.AbstractProject_AssignedLabelString_NoMatch()); } + if (project != null) { + for (AbstractProject.LabelValidator v : Jenkins.getInstance() + .getExtensionList(AbstractProject.LabelValidator.class)) { + FormValidation result = v.check(project, l); + if (!FormValidation.Kind.OK.equals(result.kind)) { + return result; + } + } + } return FormValidation.ok(); } @@ -2384,5 +2396,23 @@ public abstract class AbstractProject

    ,R extends A this.customWorkspace= Util.fixEmptyAndTrim(customWorkspace); save(); } - + + /** + * Plugins may want to contribute additional restrictions on the use of specific labels for specific projects. + * This extension point allows such restrictions. + * + * @since 1.540 + */ + public static abstract class LabelValidator implements ExtensionPoint { + /** + * Check the use of the label within the specified context. + * + * @param project the project that wants to restrict itself to the specified label. + * @param label the label that the project wants to restrict itself to. + * @return the {@link FormValidation} result. + */ + @Nonnull + public abstract FormValidation check(@Nonnull AbstractProject project, @Nonnull Label label); + } + } diff --git a/test/src/test/java/hudson/model/labels/LabelExpressionTest.java b/test/src/test/java/hudson/model/labels/LabelExpressionTest.java index f2df9b967314f59716c2156800480a20c54a18b3..d75e892567ff9c3166ce6e63e66a687354cae155 100644 --- a/test/src/test/java/hudson/model/labels/LabelExpressionTest.java +++ b/test/src/test/java/hudson/model/labels/LabelExpressionTest.java @@ -233,11 +233,11 @@ public class LabelExpressionTest extends HudsonTestCase { Label l = jenkins.getLabel("foo"); DumbSlave s = createSlave(l); - String msg = d.doCheckAssignedLabelString("goo").renderHtml(); + String msg = d.doCheckAssignedLabelString(null, "goo").renderHtml(); assertTrue(msg.contains("foo")); assertTrue(msg.contains("goo")); - msg = d.doCheckAssignedLabelString("master && goo").renderHtml(); + msg = d.doCheckAssignedLabelString(null, "master && goo").renderHtml(); assertTrue(msg.contains("foo")); assertTrue(msg.contains("goo")); return null;