From 0ffa03278e597edcde5576971a7e51b8938d6edd Mon Sep 17 00:00:00 2001 From: Stefan Wolf Date: Sun, 30 Jan 2011 23:19:11 +0100 Subject: [PATCH] Added autocomplete feature to BuildTrigger --- .../main/java/hudson/tasks/BuildTrigger.java | 62 +++++++++++++------ .../hudson/tasks/BuildTrigger/config.jelly | 4 +- .../hudson/tasks/Messages.properties | 1 + .../hudson/tasks/Messages_de.properties | 1 + 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/hudson/tasks/BuildTrigger.java b/core/src/main/java/hudson/tasks/BuildTrigger.java index 48e32adee9..4d28f4dcea 100644 --- a/core/src/main/java/hudson/tasks/BuildTrigger.java +++ b/core/src/main/java/hudson/tasks/BuildTrigger.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,14 +23,15 @@ */ package hudson.tasks; -import hudson.Launcher; import hudson.Extension; +import hudson.Launcher; import hudson.Util; -import hudson.security.AccessControlled; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Action; +import hudson.model.AutoCompletionCandidates; import hudson.model.BuildListener; +import hudson.model.Cause.UpstreamCause; import hudson.model.DependecyDeclarer; import hudson.model.DependencyGraph; import hudson.model.DependencyGraph.Dependency; @@ -41,15 +42,16 @@ import hudson.model.Job; import hudson.model.Project; import hudson.model.Result; import hudson.model.Run; -import hudson.model.Cause.UpstreamCause; import hudson.model.TaskListener; import hudson.model.listeners.ItemListener; +import hudson.security.AccessControlled; import hudson.util.FormValidation; import net.sf.json.JSONObject; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; import java.io.PrintStream; @@ -67,7 +69,7 @@ import java.util.logging.Logger; * *

* Despite what the name suggests, this class doesn't actually trigger other jobs - * as a part of {@link #perform} method. Its main job is to simply augument + * as a part of {@link #perform} method. Its main job is to simply augment * {@link DependencyGraph}. Jobs are responsible for triggering downstream jobs * on its own, because dependencies may come from other sources. * @@ -130,7 +132,7 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } - + /** * Checks if this trigger has the exact same set of children as the given list. */ @@ -268,8 +270,12 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { @Override public Publisher newInstance(StaplerRequest req, JSONObject formData) throws FormException { + String childProjectsString = formData.getString("childProjects").trim(); + if (childProjectsString.endsWith(",")) { + childProjectsString = childProjectsString.substring(0, childProjectsString.length() - 1).trim(); + } return new BuildTrigger( - formData.getString("childProjects"), + childProjectsString, formData.has("evenIfUnstable") && formData.getBoolean("evenIfUnstable")); } @@ -279,7 +285,7 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { } public boolean showEvenIfUnstableOption(Class jobType) { - // UGLY: for promotion process, this option doesn't make sense. + // UGLY: for promotion process, this option doesn't make sense. return !jobType.getName().contains("PromotionProcess"); } @@ -291,18 +297,38 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { if(!subject.hasPermission(Item.CONFIGURE)) return FormValidation.ok(); StringTokenizer tokens = new StringTokenizer(Util.fixNull(value),","); + boolean hasProjects = false; while(tokens.hasMoreTokens()) { String projectName = tokens.nextToken().trim(); - Item item = Hudson.getInstance().getItemByFullName(projectName,Item.class); - if(item==null) - return FormValidation.error(Messages.BuildTrigger_NoSuchProject(projectName,AbstractProject.findNearest(projectName).getName())); - if(!(item instanceof AbstractProject)) - return FormValidation.error(Messages.BuildTrigger_NotBuildable(projectName)); + if (StringUtils.isNotBlank(projectName)) { + Item item = Hudson.getInstance().getItemByFullName(projectName,Item.class); + if(item==null) + return FormValidation.error(Messages.BuildTrigger_NoSuchProject(projectName,AbstractProject.findNearest(projectName).getName())); + if(!(item instanceof AbstractProject)) + return FormValidation.error(Messages.BuildTrigger_NotBuildable(projectName)); + hasProjects = true; + } + } + if (!hasProjects) { + return FormValidation.error(Messages.BuildTrigger_NoProjectSpecified()); } return FormValidation.ok(); } + public AutoCompletionCandidates doAutoCompleteChildProjects(@QueryParameter String value) { + AutoCompletionCandidates candidates = new AutoCompletionCandidates(); + List jobs = Hudson.getInstance().getItems(Job.class); + for (Job job: jobs) { + if (job.getFullName().startsWith(value)) { + if (job.hasPermission(Item.READ)) { + candidates.add(job.getFullName()); + } + } + } + return candidates; + } + @Extension public static class ItemListenerImpl extends ItemListener { @Override diff --git a/core/src/main/resources/hudson/tasks/BuildTrigger/config.jelly b/core/src/main/resources/hudson/tasks/BuildTrigger/config.jelly index 20404ab407..d1a50afe4d 100644 --- a/core/src/main/resources/hudson/tasks/BuildTrigger/config.jelly +++ b/core/src/main/resources/hudson/tasks/BuildTrigger/config.jelly @@ -25,7 +25,9 @@ THE SOFTWARE. + checkUrl="'descriptorByName/BuildTrigger/check?value='+encodeURIComponent(this.value)" + autoCompleteDelimChar="," + field="childProjects"/> diff --git a/core/src/main/resources/hudson/tasks/Messages.properties b/core/src/main/resources/hudson/tasks/Messages.properties index b828a7b85f..236134a342 100644 --- a/core/src/main/resources/hudson/tasks/Messages.properties +++ b/core/src/main/resources/hudson/tasks/Messages.properties @@ -44,6 +44,7 @@ BuildTrigger.Disabled={0} is disabled. Triggering skipped BuildTrigger.DisplayName=Build other projects BuildTrigger.InQueue={0} is already in the queue BuildTrigger.NoSuchProject=No such project ''{0}''. Did you mean ''{1}''? +BuildTrigger.NoProjectSpecified=No project specified BuildTrigger.NotBuildable={0} is not buildable BuildTrigger.Triggering=Triggering a new build of {0} diff --git a/core/src/main/resources/hudson/tasks/Messages_de.properties b/core/src/main/resources/hudson/tasks/Messages_de.properties index 7841e02e8b..866b169511 100644 --- a/core/src/main/resources/hudson/tasks/Messages_de.properties +++ b/core/src/main/resources/hudson/tasks/Messages_de.properties @@ -44,6 +44,7 @@ BuildTrigger.Disabled={0} ist deaktiviert. Keine Ausl BuildTrigger.DisplayName=Weitere Projekte bauen BuildTrigger.InQueue={0} ist bereits geplant. BuildTrigger.NoSuchProject=Kein Projekt ''{0}'' gefunden. Meinten Sie ''{1}''? +BuildTrigger.NoProjectSpecified=Kein Projekt angegeben BuildTrigger.NotBuildable={0} kann nicht gebaut werden. BuildTrigger.Triggering=L\u00F6se einen neuen Build von {0} aus -- GitLab