From 78200ca9545cd28789d3afd0cf8070fc4c38ee89 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 3 May 2011 16:39:56 +0200 Subject: [PATCH 01/28] Prototype Groovy view support. --- core/src/main/java/hudson/taglibs/LayoutTagLib.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 core/src/main/java/hudson/taglibs/LayoutTagLib.java diff --git a/core/src/main/java/hudson/taglibs/LayoutTagLib.java b/core/src/main/java/hudson/taglibs/LayoutTagLib.java new file mode 100644 index 0000000000..c1abf47e8a --- /dev/null +++ b/core/src/main/java/hudson/taglibs/LayoutTagLib.java @@ -0,0 +1,10 @@ +package hudson.taglibs; + +/** + * Experimenting. This is to be auto-generated. + * + * @author Kohsuke Kawaguchi + */ +public interface LayoutTagLib extends TypedTagLibrary { + +} From 78e8be60df1dac63f86d984c0160b715018fb652 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 3 May 2011 16:40:32 +0200 Subject: [PATCH 02/28] Add groovy view support as a depdendency. --- core/pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index e8e5642821..7471475688 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -381,8 +381,8 @@ THE SOFTWARE. org.kohsuke.stapler - stapler-jelly - 1.164 + stapler-groovy + 1.166-SNAPSHOT commons-jelly @@ -392,6 +392,11 @@ THE SOFTWARE. commons-jexl commons-jexl + + + org.codehaus.groovy + groovy + From 4ed12d4faaf5c1fd8fda9eda296c3716fae767d9 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 3 May 2011 17:57:53 +0200 Subject: [PATCH 03/28] this is how you delegate to a class --- core/src/main/java/hudson/taglibs/test.gdsl | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 core/src/main/java/hudson/taglibs/test.gdsl diff --git a/core/src/main/java/hudson/taglibs/test.gdsl b/core/src/main/java/hudson/taglibs/test.gdsl new file mode 100644 index 0000000000..ed05d0590e --- /dev/null +++ b/core/src/main/java/hudson/taglibs/test.gdsl @@ -0,0 +1,12 @@ +def ctx = context(scope:scriptScope()) // TODO: make this more restrictive + +// TODO: GDSL with generics in methods? +// TODO: how to complete "it", "descriptor", "instance", and other interesting variables? +contributor(ctx) { + method name:"i18n", type:"java.lang.String", params: [msg:"java.lang.String"] +// method name:"namespace", type:"T", params: [type:"java.lang.Class"] + + property name:"app", type:"hudson.model.Hudson" + + delegatesTo(findClass("org.kohsuke.stapler.jelly.groovy.JellyBuilder")) +} \ No newline at end of file From 3754cac82aa487aa201ea3901c5689e732c8c205 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 3 May 2011 18:27:31 +0200 Subject: [PATCH 04/28] delegatesTo can be called multiple times --- core/src/main/java/hudson/taglibs/test.gdsl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/hudson/taglibs/test.gdsl b/core/src/main/java/hudson/taglibs/test.gdsl index ed05d0590e..341f385297 100644 --- a/core/src/main/java/hudson/taglibs/test.gdsl +++ b/core/src/main/java/hudson/taglibs/test.gdsl @@ -1,12 +1,11 @@ def ctx = context(scope:scriptScope()) // TODO: make this more restrictive -// TODO: GDSL with generics in methods? // TODO: how to complete "it", "descriptor", "instance", and other interesting variables? contributor(ctx) { - method name:"i18n", type:"java.lang.String", params: [msg:"java.lang.String"] -// method name:"namespace", type:"T", params: [type:"java.lang.Class"] +// method name:"i18n", type:"java.lang.String", params: [msg:"java.lang.String"] property name:"app", type:"hudson.model.Hudson" delegatesTo(findClass("org.kohsuke.stapler.jelly.groovy.JellyBuilder")) + delegatesTo(findClass("org.kohsuke.stapler.jelly.groovy.StaplerClosureScript")) } \ No newline at end of file From e31d2e3f2786bfe56630bb382859c73d2661cbcd Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 4 May 2011 11:32:56 +0200 Subject: [PATCH 05/28] experimenting with IntelliJ's auto-completion support. --- core/src/main/java/hudson/taglibs/test.gdsl | 64 +++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/hudson/taglibs/test.gdsl b/core/src/main/java/hudson/taglibs/test.gdsl index 341f385297..0e5367ea7f 100644 --- a/core/src/main/java/hudson/taglibs/test.gdsl +++ b/core/src/main/java/hudson/taglibs/test.gdsl @@ -1,11 +1,67 @@ +import com.intellij.openapi.module.*; +import com.intellij.openapi.roots.*; + def ctx = context(scope:scriptScope()) // TODO: make this more restrictive // TODO: how to complete "it", "descriptor", "instance", and other interesting variables? +// TODO: do view pages need packages? contributor(ctx) { -// method name:"i18n", type:"java.lang.String", params: [msg:"java.lang.String"] property name:"app", type:"hudson.model.Hudson" - delegatesTo(findClass("org.kohsuke.stapler.jelly.groovy.JellyBuilder")) - delegatesTo(findClass("org.kohsuke.stapler.jelly.groovy.StaplerClosureScript")) -} \ No newline at end of file + def ct = classType + if (ct.getClass().name.endsWith(".GroovyScriptClass")) { + // if we are completing Groovy script + + def roots = new HashSet/**/() + ModuleManager.getInstance(ct.project).modules.each { m -> + roots.addAll(ModuleRootManager.getInstance(m).sourceRoots) + } + + // figure out the path that this file is in + def contentPaths = [] + for (def f=ct.containingFile.virtualFile; f!=null && !roots.contains(f); f=f.parent) { + contentPaths << f.name + } + def fqcn = contentPaths.reverse()[0..-2].join('.') + + property name:"my", type:fqcn // but this is still shadowed by JellyBuilder.getMy + } + + // normally, built-in delegateTo function would do, except in this case + // we'd like to avoid binding getMy. + for ( String t : ["org.kohsuke.stapler.jelly.groovy.JellyBuilder","org.kohsuke.stapler.jelly.groovy.StaplerClosureScript"]) { + def c = findClass(t); + c.allMethods.findAll { !it.isConstructor() && it.name!="getMy" }.each { add it; } + c.allFields.each { add it; } + } +} + +// Record of past experiments +/* +try to infer "it" from the class name of Groovy page + +PsiElement.getProject() +ModuleManager.getInstance(project).getModules() +Module -> ModuleRootModel -> .getSourceRoots() + +classType=Script Class:manag_ : class org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass +place=Reference expression : class org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl +psiType=PsiType:manag_ : class com.intellij.psi.impl.source.PsiImmediateClassType + +System.out.println("classType=${classType} : ${classType.getClass()}") +System.out.println("qualifiedName="+ct.qualifiedName) +System.out.println("containingFile="+ct.containingFile) +System.out.println("containingFile.name="+ct.containingFile.name) +System.out.println("scope=${ct.scope}:${ct.scope.getClass()}") +System.out.println("scope.package=${ct.scope.getPackageName()}") + +if (0) { + // file system reference goes all the way to '/' in the POSIX file system + def f = ct.containingFile + while (f!=null) { + System.out.println(" name="+f.name) + f=f.parent + } +} +*/ From 8841d10fbb86a40f76ce6ae45c7ffa639c07f3ac Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 4 May 2011 11:34:02 +0200 Subject: [PATCH 06/28] hand-writing the interface, to be auto-generated, to test the feel of it --- core/src/main/java/hudson/taglibs/LayoutTagLib.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/src/main/java/hudson/taglibs/LayoutTagLib.java b/core/src/main/java/hudson/taglibs/LayoutTagLib.java index c1abf47e8a..4056b9f57d 100644 --- a/core/src/main/java/hudson/taglibs/LayoutTagLib.java +++ b/core/src/main/java/hudson/taglibs/LayoutTagLib.java @@ -1,10 +1,22 @@ package hudson.taglibs; +import groovy.lang.Closure; +import org.kohsuke.stapler.jelly.groovy.TagLibraryUri; +import org.kohsuke.stapler.jelly.groovy.TypedTagLibrary; + +import java.util.Map; + /** * Experimenting. This is to be auto-generated. * * @author Kohsuke Kawaguchi */ +@TagLibraryUri("/lib/layout") public interface LayoutTagLib extends TypedTagLibrary { + void layout(Map args, Closure body); + void layout(Map args); + void layout(Closure body); + void layout(); + void main_panel(Closure c); } From 00bc32985f0315b324f4e66d00a6a1b29feaf54e Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 4 May 2011 11:37:48 +0200 Subject: [PATCH 07/28] experimental re-write of the "manage Jenkins" view by Groovy --- .../hudson/model/Hudson/manag_.groovy | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 core/src/main/resources/hudson/model/Hudson/manag_.groovy diff --git a/core/src/main/resources/hudson/model/Hudson/manag_.groovy b/core/src/main/resources/hudson/model/Hudson/manag_.groovy new file mode 100644 index 0000000000..f3fa87d1ca --- /dev/null +++ b/core/src/main/resources/hudson/model/Hudson/manag_.groovy @@ -0,0 +1,65 @@ +import hudson.taglibs.LayoutTagLib + +l=namespace(LayoutTagLib) +t=namespace("/lib/hudson") +st=namespace("jelly:stapler") + +def feature(String icon, String href, String title, Closure body=null) { + t.summary(icon:icon, href:href, iconOnly:true) { + div(class:"link") { + a(href:href, title) + } + div(style:"color:gray; text-decoration:none;",body) + } +} + +l.layout(title:i18n("Manage Jenkins"),permission:app.ADMINISTER) { + + st.include(page:"sidepanel.jelly") + l.main_panel { + h1(i18n("Manage Jenkins")) + + if (my.isCheckURIEncodingEnabled()) { + script """ + var url='checkURIEncoding'; + var params='value=\u57f7\u4e8b'; + var checkAjax=new Ajax.Updater( + 'message', url, + { + method: 'get', parameters: params + } + ); + """ + span(id:"message") + } + + app.administrativeMonitors.each { am -> + if (am.isActivated() && am.isEnabled()) + st.include(it:am, page:"message.jelly") + } + + st.include(page:"downgrade.jelly") + + table(style:"padding-left: 2em;",id:"management-links") { + feature("setting.gif", "configure", i18n("Configure System")) { + raw(i18n("Configure global settings and paths.")) + } + // TODO: more features + + app.managementLinks.each { m -> + if (m.iconFileName==null) return; + feature(m.iconFileName, m.urlName, m.displayName) { + raw(m.description) + } + } + + if (app.quietingDown) { + feature("system-log-out.gif","cancelQuietDown",i18n("Cancel Shutdown")) + } else { + feature("system-log-out.gif","quietDown",i18n("Prepare for Shutdown")) { + raw(i18n("Stops executing new builds, so that the system can be eventually shut down safely.")) + } + } + } + } +} \ No newline at end of file From 2c6bb3584104433d20f703d3bc1efd1ca134c98f Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 4 May 2011 11:39:03 +0200 Subject: [PATCH 08/28] renamed sincce this isn't just a test mockup any longer. --- core/src/main/java/hudson/taglibs/{test.gdsl => IntelliJ.gdsl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/src/main/java/hudson/taglibs/{test.gdsl => IntelliJ.gdsl} (100%) diff --git a/core/src/main/java/hudson/taglibs/test.gdsl b/core/src/main/java/hudson/taglibs/IntelliJ.gdsl similarity index 100% rename from core/src/main/java/hudson/taglibs/test.gdsl rename to core/src/main/java/hudson/taglibs/IntelliJ.gdsl From 12ad3b0272967814176a25d6c5188216de4322d9 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 4 May 2011 12:05:50 +0200 Subject: [PATCH 09/28] replaced i18n by '_' since it shows up a lot. --- .../resources/hudson/model/Hudson/manag_.groovy | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/resources/hudson/model/Hudson/manag_.groovy b/core/src/main/resources/hudson/model/Hudson/manag_.groovy index f3fa87d1ca..07a3c35cb9 100644 --- a/core/src/main/resources/hudson/model/Hudson/manag_.groovy +++ b/core/src/main/resources/hudson/model/Hudson/manag_.groovy @@ -13,11 +13,11 @@ def feature(String icon, String href, String title, Closure body=null) { } } -l.layout(title:i18n("Manage Jenkins"),permission:app.ADMINISTER) { +l.layout(title:_("Manage Jenkins"),permission:app.ADMINISTER) { st.include(page:"sidepanel.jelly") l.main_panel { - h1(i18n("Manage Jenkins")) + h1(_("Manage Jenkins")) if (my.isCheckURIEncodingEnabled()) { script """ @@ -41,8 +41,8 @@ l.layout(title:i18n("Manage Jenkins"),permission:app.ADMINISTER) { st.include(page:"downgrade.jelly") table(style:"padding-left: 2em;",id:"management-links") { - feature("setting.gif", "configure", i18n("Configure System")) { - raw(i18n("Configure global settings and paths.")) + feature("setting.gif", "configure", _("Configure System")) { + raw(_("Configure global settings and paths.")) } // TODO: more features @@ -54,10 +54,10 @@ l.layout(title:i18n("Manage Jenkins"),permission:app.ADMINISTER) { } if (app.quietingDown) { - feature("system-log-out.gif","cancelQuietDown",i18n("Cancel Shutdown")) + feature("system-log-out.gif","cancelQuietDown",_("Cancel Shutdown")) } else { - feature("system-log-out.gif","quietDown",i18n("Prepare for Shutdown")) { - raw(i18n("Stops executing new builds, so that the system can be eventually shut down safely.")) + feature("system-log-out.gif","quietDown",_("Prepare for Shutdown")) { + raw(_("Stops executing new builds, so that the system can be eventually shut down safely.")) } } } From 61768cc0f89d6535b9a58db07c21be1b0301c043 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 6 May 2011 10:33:02 -0700 Subject: [PATCH 10/28] not specifying the file extension so that different pieces can be implemented by different view technologies --- core/src/main/resources/hudson/model/Hudson/manag_.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/resources/hudson/model/Hudson/manag_.groovy b/core/src/main/resources/hudson/model/Hudson/manag_.groovy index 07a3c35cb9..77ed9fd48f 100644 --- a/core/src/main/resources/hudson/model/Hudson/manag_.groovy +++ b/core/src/main/resources/hudson/model/Hudson/manag_.groovy @@ -15,7 +15,7 @@ def feature(String icon, String href, String title, Closure body=null) { l.layout(title:_("Manage Jenkins"),permission:app.ADMINISTER) { - st.include(page:"sidepanel.jelly") + st.include(page:"sidepanel") l.main_panel { h1(_("Manage Jenkins")) @@ -35,10 +35,10 @@ l.layout(title:_("Manage Jenkins"),permission:app.ADMINISTER) { app.administrativeMonitors.each { am -> if (am.isActivated() && am.isEnabled()) - st.include(it:am, page:"message.jelly") + st.include(it:am, page:"message") } - st.include(page:"downgrade.jelly") + st.include(page:"downgrade") table(style:"padding-left: 2em;",id:"management-links") { feature("setting.gif", "configure", _("Configure System")) { From 9e1fc0929e527d9ba92dcdf7da4dd43b34bd1189 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 15 May 2011 19:07:06 -0700 Subject: [PATCH 11/28] 1.166 shipped --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 7471475688..968db674ee 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -382,7 +382,7 @@ THE SOFTWARE. org.kohsuke.stapler stapler-groovy - 1.166-SNAPSHOT + 1.166 commons-jelly From e122be017cc4c45f11b81bbcf30c8a9ceec960fe Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 17 May 2011 11:29:41 -0700 Subject: [PATCH 12/28] added DSLD for Eclipse --- core/src/main/java/hudson/taglibs/eclipse.dsld | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 core/src/main/java/hudson/taglibs/eclipse.dsld diff --git a/core/src/main/java/hudson/taglibs/eclipse.dsld b/core/src/main/java/hudson/taglibs/eclipse.dsld new file mode 100644 index 0000000000..63dfb2b6e8 --- /dev/null +++ b/core/src/main/java/hudson/taglibs/eclipse.dsld @@ -0,0 +1,10 @@ +// fileExtension(...) and fileName(...) +(isScript() /*& sourceFolderOfCurrentFile("src/main/resources")*/).accept { + provider "Jenkins Groovy View"; + + property name:"app", type:"hudson.model.Hudson"; + + for ( String t : ["org.kohsuke.stapler.jelly.groovy.JellyBuilder","org.kohsuke.stapler.jelly.groovy.StaplerClosureScript"]) { + delegatesTo t; + } +} \ No newline at end of file From 5c53144d8d44c69586da33431d94b115e5b75c59 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 28 May 2011 15:35:35 +0200 Subject: [PATCH 13/28] Looks like a dead code. --- .../java/hudson/maven/MavenRedeployer.java | 85 ------------------- 1 file changed, 85 deletions(-) delete mode 100644 maven-plugin/src/main/java/hudson/maven/MavenRedeployer.java diff --git a/maven-plugin/src/main/java/hudson/maven/MavenRedeployer.java b/maven-plugin/src/main/java/hudson/maven/MavenRedeployer.java deleted file mode 100644 index f1206cff48..0000000000 --- a/maven-plugin/src/main/java/hudson/maven/MavenRedeployer.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * - * 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 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson.maven; - -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.model.Result; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Notifier; -import hudson.tasks.BuildStepMonitor; -import hudson.Launcher; -import hudson.maven.reporters.MavenArtifactRecord; -import hudson.tasks.Publisher; - -import java.io.IOException; - -/** - * {@link Publisher} for Maven projects to deploy artifacts to a Maven repository - * after the fact. - * - *

- * When a build breaks in the middle, this is a convenient way to prevent - * modules from being deployed partially. This can be combined with promoted builds - * plugin to deploy artifacts after testing, for example. - * - * @author Kohsuke Kawaguchi - */ -public class MavenRedeployer extends Notifier { - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - MavenArtifactRecord mar = build.getAction(MavenArtifactRecord.class); - if(mar==null) { - if(build.getResult().isBetterThan(Result.FAILURE)) { - listener.getLogger().println("There's no record of artifact information. Is this really a Maven build?"); - build.setResult(Result.FAILURE); - } - // failed - return true; - } - - listener.getLogger().println("TODO"); - - return true; - } - - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; - } - - public BuildStepDescriptor getDescriptor() { - return DESCRIPTOR; - } - - public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); - - public static final class DescriptorImpl extends BuildStepDescriptor { - public boolean isApplicable(Class jobType) { - return AbstractMavenProject.class.isAssignableFrom(jobType); - } - - public String getDisplayName() { - return Messages.MavenRedeployer_DisplayName(); - } - } -} \ No newline at end of file From 4434ed77063bcb1b939072011b2c7ec9401ce771 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 28 May 2011 18:26:04 +0200 Subject: [PATCH 14/28] A few more Jelly files switched to Groovy as a test Now config.jelly can be converted into groovy. Verified that the auto-selection of the proper view type is working. --- core/pom.xml | 2 +- .../main/java/hudson/model/Descriptor.java | 22 ++++++-- .../hudson/PluginManager/sidepanel.groovy | 37 ++++++++++++++ .../hudson/PluginManager/sidepanel.jelly | 40 --------------- .../resources/hudson/tasks/Ant/config.groovy | 51 +++++++++++++++++++ .../resources/hudson/tasks/Ant/config.jelly | 51 ------------------- .../main/resources/lib/form/hetero-list.jelly | 2 +- 7 files changed, 108 insertions(+), 97 deletions(-) create mode 100644 core/src/main/resources/hudson/PluginManager/sidepanel.groovy delete mode 100644 core/src/main/resources/hudson/PluginManager/sidepanel.jelly create mode 100644 core/src/main/resources/hudson/tasks/Ant/config.groovy delete mode 100644 core/src/main/resources/hudson/tasks/Ant/config.jelly diff --git a/core/pom.xml b/core/pom.xml index 968db674ee..a99d813ce5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -382,7 +382,7 @@ THE SOFTWARE. org.kohsuke.stapler stapler-groovy - 1.166 + 1.167-SNAPSHOT commons-jelly diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index 50ca708da0..843a420ff9 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -36,6 +36,7 @@ import hudson.views.ListViewColumn; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.*; +import org.kohsuke.stapler.jelly.JellyCompatibleFacet; import org.springframework.util.StringUtils; import org.jvnet.tiger_types.Types; import org.apache.commons.io.IOUtils; @@ -648,7 +649,14 @@ public abstract class Descriptor> implements Saveable { } public String getConfigPage() { - return getViewPage(clazz, "config.jelly"); + List names = new ArrayList(); + for (Facet f : WebApp.get(Hudson.getInstance().servletContext).facets) { + if (f instanceof JellyCompatibleFacet) { + JellyCompatibleFacet jcf = (JellyCompatibleFacet) f; + names.add("config"+jcf.getDefaultScriptExtension()); + } + } + return getViewPage(clazz,names,"config.jelly"); } public String getGlobalConfigPage() { @@ -656,10 +664,16 @@ public abstract class Descriptor> implements Saveable { } private String getViewPage(Class clazz, String pageName, String defaultValue) { + return getViewPage(clazz,Collections.singleton(pageName),defaultValue); + } + + private String getViewPage(Class clazz, Collection pageNames, String defaultValue) { while(clazz!=Object.class) { - String name = clazz.getName().replace('.', '/').replace('$', '/') + "/" + pageName; - if(clazz.getClassLoader().getResource(name)!=null) - return '/'+name; + for (String pageName : pageNames) { + String name = clazz.getName().replace('.', '/').replace('$', '/') + "/" + pageName; + if(clazz.getClassLoader().getResource(name)!=null) + return '/'+name; + } clazz = clazz.getSuperclass(); } return defaultValue; diff --git a/core/src/main/resources/hudson/PluginManager/sidepanel.groovy b/core/src/main/resources/hudson/PluginManager/sidepanel.groovy new file mode 100644 index 0000000000..593bfae961 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/sidepanel.groovy @@ -0,0 +1,37 @@ +/* + * The MIT License + * + * Copyright (c) 2011, CloudBees, Inc. + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +import hudson.taglibs.LayoutTagLib + +l=namespace(LayoutTagLib) + +l.header() +l.side_panel { + l.tasks { + l.task(icon:"images/24x24/up.png", href:rootURL+'/', title:_("Back to Dashboard")) + l.task(icon:"images/24x24/setting.png", href:"${rootURL}/manage", title:_("Manage Jenkins"), permission:app.ADMINISTER, it:app) + if (!app.updateCenter.jobs.isEmpty()) { + l.task(icon:"images/24x24/plugin.png", href:"${rootURL}/updateCenter/", title:_("Update Center")) + } + } +} diff --git a/core/src/main/resources/hudson/PluginManager/sidepanel.jelly b/core/src/main/resources/hudson/PluginManager/sidepanel.jelly deleted file mode 100644 index b6c634dae2..0000000000 --- a/core/src/main/resources/hudson/PluginManager/sidepanel.jelly +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/core/src/main/resources/hudson/tasks/Ant/config.groovy b/core/src/main/resources/hudson/tasks/Ant/config.groovy new file mode 100644 index 0000000000..3a7b6a6987 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Ant/config.groovy @@ -0,0 +1,51 @@ +/* + * The MIT License + * + * Copyright (c) 2011, CloudBees, Inc. + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +f=namespace("/lib/form") + +if (!descriptor.installations) { + f.entry(title:_("Ant Version")) { + select(class:"setting-input",name:"ant.antName") { + option(value:"(Default)", _("Default")) + descriptor.installations.each { + f.option(selected:it.name==instance?.ant?.name, value:it.name, it.name) + } + } + } +} + +f.entry(title:_("Targets"),help:"/help/ant/ant-targets.html") { + f.expandableTextbox(name:"ant.targets",value:instance?.targets) +} + +f.advanced { + f.entry(title:_("Build File"),help:"/help/ant/ant-buildfile.html") { + f.expandableTextbox(name:"ant.buildFile",value:instance?.buildFile) + } + f.entry(title:_("Properties"),help:"/help/ant/ant-properties.html") { + f.expandableTextbox(name:"ant.properties",value:instance?.properties) + } + f.entry(title:_("Java Options"),help:"/help/ant/ant-opts.html") { + f.expandableTextbox(name:"ant.antOpts",value:instance?.antOpts) + } +} diff --git a/core/src/main/resources/hudson/tasks/Ant/config.jelly b/core/src/main/resources/hudson/tasks/Ant/config.jelly deleted file mode 100644 index 2a011af5f5..0000000000 --- a/core/src/main/resources/hudson/tasks/Ant/config.jelly +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/src/main/resources/lib/form/hetero-list.jelly b/core/src/main/resources/lib/form/hetero-list.jelly index 643e477235..c8f5b0cbc5 100644 --- a/core/src/main/resources/lib/form/hetero-list.jelly +++ b/core/src/main/resources/lib/form/hetero-list.jelly @@ -110,7 +110,7 @@ THE SOFTWARE.

- + From 8d231c494c6dede6eb8e840699c7ad43740ec547 Mon Sep 17 00:00:00 2001 From: Andrew Bayer Date: Sun, 29 May 2011 08:36:11 -0400 Subject: [PATCH 15/28] Support global.groovy as well as config.groovy --- core/src/main/java/hudson/model/Descriptor.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index 843a420ff9..6dadf8bf8c 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -660,9 +660,16 @@ public abstract class Descriptor> implements Saveable { } public String getGlobalConfigPage() { - return getViewPage(clazz, "global.jelly",null); + List names = new ArrayList(); + for (Facet f : WebApp.get(Hudson.getInstance().servletContext).facets) { + if (f instanceof JellyCompatibleFacet) { + JellyCompatibleFacet jcf = (JellyCompatibleFacet) f; + names.add("global"+jcf.getDefaultScriptExtension()); + } + } + return getViewPage(clazz,names,null); } - + private String getViewPage(Class clazz, String pageName, String defaultValue) { return getViewPage(clazz,Collections.singleton(pageName),defaultValue); } From 1e35352b7e960c7d391d7efc4a6b7123284e6fce Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 29 May 2011 08:00:54 +0200 Subject: [PATCH 16/28] auto-completes instance and descriptor --- core/src/main/java/hudson/taglibs/IntelliJ.gdsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/hudson/taglibs/IntelliJ.gdsl b/core/src/main/java/hudson/taglibs/IntelliJ.gdsl index 0e5367ea7f..f16398adab 100644 --- a/core/src/main/java/hudson/taglibs/IntelliJ.gdsl +++ b/core/src/main/java/hudson/taglibs/IntelliJ.gdsl @@ -26,6 +26,8 @@ contributor(ctx) { def fqcn = contentPaths.reverse()[0..-2].join('.') property name:"my", type:fqcn // but this is still shadowed by JellyBuilder.getMy + property name:"instance", type:fqcn + property name:"descriptor", type:fqcn+".DescriptorImpl" } // normally, built-in delegateTo function would do, except in this case From ca9c4e06aa4668c3e32fc1de85b70b1898d10e3d Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 29 May 2011 08:06:14 +0200 Subject: [PATCH 17/28] Jenkins --- core/src/main/java/hudson/WebAppMain.java | 8 ++++---- core/src/main/java/hudson/security/HudsonFilter.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index 0b68ebbe47..0d804c839a 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -223,20 +223,20 @@ public final class WebAppMain implements ServletContextListener { } }, 1000*10); } catch (Error e) { - LOGGER.log(Level.SEVERE, "Failed to initialize Hudson",e); + LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",e); context.setAttribute(APP,new HudsonFailedToLoad(e)); throw e; } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Failed to initialize Hudson",e); + LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",e); context.setAttribute(APP,new HudsonFailedToLoad(e)); } } }.start(); } catch (Error e) { - LOGGER.log(Level.SEVERE, "Failed to initialize Hudson",e); + LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",e); throw e; } catch (RuntimeException e) { - LOGGER.log(Level.SEVERE, "Failed to initialize Hudson",e); + LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",e); throw e; } } diff --git a/core/src/main/java/hudson/security/HudsonFilter.java b/core/src/main/java/hudson/security/HudsonFilter.java index f4d6b43cd1..b8a37b3deb 100644 --- a/core/src/main/java/hudson/security/HudsonFilter.java +++ b/core/src/main/java/hudson/security/HudsonFilter.java @@ -42,7 +42,7 @@ import org.acegisecurity.ui.rememberme.RememberMeServices; import org.acegisecurity.userdetails.UserDetailsService; /** - * {@link Filter} that Hudson uses to implement security support. + * {@link Filter} that Jenkins uses to implement security support. * *

* This is the instance the servlet container creates, but @@ -59,7 +59,7 @@ public class HudsonFilter implements Filter { private volatile Filter filter; /** - * The {@link #init(FilterConfig)} may be called before the Hudson instance is up (which is + * The {@link #init(FilterConfig)} may be called before the Jenkins instance is up (which is * required for initialization of the filter). So we store the * filterConfig for later lazy-initialization of the filter. */ @@ -115,7 +115,7 @@ public class HudsonFilter implements Filter { // the whole thing fail hard before a nicer error check // in WebAppMain.contextInitialized. So for now, // just report it here, and let the WebAppMain handle the failure gracefully. - LOGGER.log(SEVERE, "Failed to initialize Hudson",e); + LOGGER.log(SEVERE, "Failed to initialize Jenkins",e); } } From a557e80d1a23189e27f848140a9b09d1801f6b75 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 29 May 2011 08:12:28 +0200 Subject: [PATCH 18/28] Converted a few more pages into Groovy to test the behaviour. Allow global.jelly to be written in Groovy. --- .../main/java/hudson/model/Descriptor.java | 29 ++++++++--------- .../hudson/tasks/Shell/config.groovy | 28 ++++++++++++++++ .../resources/hudson/tasks/Shell/config.jelly | 30 ----------------- .../hudson/tasks/Shell/global.groovy | 30 +++++++++++++++++ .../resources/hudson/tasks/Shell/global.jelly | 32 ------------------- 5 files changed, 71 insertions(+), 78 deletions(-) create mode 100644 core/src/main/resources/hudson/tasks/Shell/config.groovy delete mode 100644 core/src/main/resources/hudson/tasks/Shell/config.jelly create mode 100644 core/src/main/resources/hudson/tasks/Shell/global.groovy delete mode 100644 core/src/main/resources/hudson/tasks/Shell/global.jelly diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index 6dadf8bf8c..f097f16bce 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -649,25 +649,11 @@ public abstract class Descriptor> implements Saveable { } public String getConfigPage() { - List names = new ArrayList(); - for (Facet f : WebApp.get(Hudson.getInstance().servletContext).facets) { - if (f instanceof JellyCompatibleFacet) { - JellyCompatibleFacet jcf = (JellyCompatibleFacet) f; - names.add("config"+jcf.getDefaultScriptExtension()); - } - } - return getViewPage(clazz,names,"config.jelly"); + return getViewPage(clazz, getPossibleViewNames("config"), "config.jelly"); } public String getGlobalConfigPage() { - List names = new ArrayList(); - for (Facet f : WebApp.get(Hudson.getInstance().servletContext).facets) { - if (f instanceof JellyCompatibleFacet) { - JellyCompatibleFacet jcf = (JellyCompatibleFacet) f; - names.add("global"+jcf.getDefaultScriptExtension()); - } - } - return getViewPage(clazz,names,null); + return getViewPage(clazz, getPossibleViewNames("global"), null); } private String getViewPage(Class clazz, String pageName, String defaultValue) { @@ -695,6 +681,17 @@ public abstract class Descriptor> implements Saveable { return getViewPage(clazz,pageName,pageName); } + private List getPossibleViewNames(String baseName) { + List names = new ArrayList(); + for (Facet f : WebApp.get(Hudson.getInstance().servletContext).facets) { + if (f instanceof JellyCompatibleFacet) { + JellyCompatibleFacet jcf = (JellyCompatibleFacet) f; + names.add(baseName +jcf.getDefaultScriptExtension()); + } + } + return names; + } + /** * Saves the configuration info to the disk. diff --git a/core/src/main/resources/hudson/tasks/Shell/config.groovy b/core/src/main/resources/hudson/tasks/Shell/config.groovy new file mode 100644 index 0000000000..56cd525907 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Shell/config.groovy @@ -0,0 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2011, CloudBees, Inc. + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +f=namespace("/lib/form") + +f.entry(title:_("Command"),description:_("description",rootURL)) { + f.textarea(name:"command",value:instance?.command,class:"fixed-width") +} diff --git a/core/src/main/resources/hudson/tasks/Shell/config.jelly b/core/src/main/resources/hudson/tasks/Shell/config.jelly deleted file mode 100644 index bea70c99d6..0000000000 --- a/core/src/main/resources/hudson/tasks/Shell/config.jelly +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - diff --git a/core/src/main/resources/hudson/tasks/Shell/global.groovy b/core/src/main/resources/hudson/tasks/Shell/global.groovy new file mode 100644 index 0000000000..d11ec0536a --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Shell/global.groovy @@ -0,0 +1,30 @@ +/* + * The MIT License + * + * Copyright (c) 2011, CloudBees, Inc. + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +f=namespace("/lib/form") + +f.section(title:_("Shell")) { + f.entry(title:_("Shell executable"),help:"/help/shell/shellexe.html") { + f.textbox(name:"shell",value:descriptor.shell,checkUrl:"'${rootURL}/builder/Shell/check?value='+encodeURIComponent(this.value)") + } +} diff --git a/core/src/main/resources/hudson/tasks/Shell/global.jelly b/core/src/main/resources/hudson/tasks/Shell/global.jelly deleted file mode 100644 index cd5a3e2304..0000000000 --- a/core/src/main/resources/hudson/tasks/Shell/global.jelly +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - From 5542f28bca0a6a4e6e96097ee3d2aa034a2ef067 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 29 May 2011 08:12:53 +0200 Subject: [PATCH 19/28] fixed NPE --- core/src/main/java/hudson/ExtensionComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/hudson/ExtensionComponent.java b/core/src/main/java/hudson/ExtensionComponent.java index 8b0af778d4..8c48632c2c 100644 --- a/core/src/main/java/hudson/ExtensionComponent.java +++ b/core/src/main/java/hudson/ExtensionComponent.java @@ -77,7 +77,7 @@ public class ExtensionComponent implements Comparable> // make the order bit more deterministic among extensions of the same ordinal if (this.instance instanceof Descriptor) { - return ((Descriptor)this.instance).getDisplayName().compareTo(((Descriptor)that.instance).getDisplayName()); + return Util.fixNull(((Descriptor)this.instance).getDisplayName()).compareTo(Util.fixNull(((Descriptor)that.instance).getDisplayName())); } else { return this.instance.getClass().getName().compareTo(that.instance.getClass().getName()); } From 0981108ac1945a5b7d9bcbc79ee57ed1ce133290 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 30 May 2011 08:21:46 +0200 Subject: [PATCH 20/28] experimenting with the taglib interface generator --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 97226385c9..5bbe4d28f7 100644 --- a/pom.xml +++ b/pom.xml @@ -132,6 +132,11 @@ THE SOFTWARE. maven-resources-plugin 2.4.3 + + org.jenkins-ci.tools + maven-hpi-plugin + 1.70-SNAPSHOT + - - -JELLY TAG FILE ${value} \ No newline at end of file diff --git a/core/src/main/resources/lib/taglib b/core/src/main/resources/lib/taglib deleted file mode 100644 index e69de29bb2..0000000000 From 77290b9c98092f6830094b656bb09448f50444c1 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 6 Jun 2011 16:17:49 -0700 Subject: [PATCH 25/28] Rely on released versions --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 04168ddc01..7b88c7ca6b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -393,7 +393,7 @@ THE SOFTWARE. org.kohsuke.stapler stapler-groovy - 1.167-SNAPSHOT + 1.167 commons-jelly diff --git a/pom.xml b/pom.xml index 5bbe4d28f7..006a04f4fe 100644 --- a/pom.xml +++ b/pom.xml @@ -135,7 +135,7 @@ THE SOFTWARE. org.jenkins-ci.tools maven-hpi-plugin - 1.70-SNAPSHOT + 1.70 -P release,sign + + clean install -DskipTests javadoc:javadoc animal-sniffer:check deploy javadoc:aggregate false true