提交 3f205132 编写于 作者: K kohsuke

allow multi-level CLI target resolution, so that resolution of Run can piggy...

allow multi-level CLI target resolution, so that resolution of Run can piggy back on that of Job, and so on.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@21497 71c3de6d-444a-0410-be80-ed276b4c234a
上级 cbf4b410
......@@ -45,6 +45,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Stack;
import static java.util.logging.Level.SEVERE;
import java.util.logging.Logger;
......@@ -103,24 +104,40 @@ public class CLIRegisterer extends ExtensionFinder {
CmdLineParser parser = new CmdLineParser(null);
try {
try {
MethodBinder resolver = null;
if (!Modifier.isStatic(m.getModifiers())) {
// decide which instance receives the method call
Method r = findResolver(m.getDeclaringClass());
if (r==null) {
stderr.println("Unable to find the resolver method annotated with @CLIResolver for "+m.getReturnType());
// build up the call sequence
Stack<Method> chains = new Stack<Method>();
Method method = m;
while (true) {
chains.push(method);
if (Modifier.isStatic(method.getModifiers()))
break; // the chain is complete.
// the method in question is an instance method, so we need to resolve the instance by using another resolver
Class<?> type = method.getDeclaringClass();
method = findResolver(type);
if (method==null) {
stderr.println("Unable to find the resolver method annotated with @CLIResolver for "+type);
return 1;
}
resolver = new MethodBinder(r,parser);
}
MethodBinder invoker = new MethodBinder(m, parser);
List<MethodBinder> binders = new ArrayList<MethodBinder>();
while (!chains.isEmpty())
binders.add(new MethodBinder(chains.pop(),parser));
// fill up all the binders
parser.parseArgument(args);
Object instance = resolver==null ? null : resolver.call(null);
invoker.call(instance);
return 0;
// resolve them
Object instance = null;
for (MethodBinder binder : binders)
instance = binder.call(instance);
if (instance instanceof Integer)
return (Integer) instance;
else
return 0;
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Exception)
......
......@@ -29,6 +29,7 @@ import hudson.Util;
import hudson.XmlFile;
import hudson.PermalinkList;
import hudson.Extension;
import hudson.cli.declarative.CLIResolver;
import hudson.model.Descriptor.FormException;
import hudson.model.listeners.ItemListener;
import hudson.model.PermalinkProjectAction.Permalink;
......@@ -96,6 +97,8 @@ import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.WebMethod;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
/**
* A job is an runnable entity under the monitoring of Hudson.
......@@ -586,6 +589,19 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
return _getRuns().get(n);
}
@CLIResolver
public RunT getBuildForCLI(@Argument(required=true,metaVar="BUILD#",usage="Build number") String id) throws CmdLineException {
try {
int n = Integer.parseInt(id);
RunT r = getBuildByNumber(n);
if (r==null)
throw new CmdLineException("No such build '#"+n+"' exists");
return r;
} catch (NumberFormatException e) {
throw new CmdLineException(id+ "is not a number");
}
}
/**
* Gets the youngest build #m that satisfies <tt>n&lt;=m</tt>.
*
......
......@@ -32,6 +32,7 @@ import hudson.FeedAdapter;
import hudson.FilePath;
import hudson.Util;
import hudson.XmlFile;
import hudson.cli.declarative.CLIMethod;
import hudson.matrix.MatrixBuild;
import hudson.matrix.MatrixRun;
import hudson.model.listeners.RunListener;
......@@ -1424,6 +1425,7 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
/**
* Marks this build to keep the log.
*/
@CLIMethod(name="keep-build")
public final void keepLog() throws IOException {
keepLog(true);
}
......
......@@ -225,4 +225,5 @@ ProxyView.DisplayName=Include a global view
MyViewsProperty.ViewExistsCheck.NotExist=A view with name {0} does not exist
MyViewsProperty.ViewExistsCheck.AlreadyExists=A view with name {0} already exists
CLI.restart.shortDescription=Restart Hudson
\ No newline at end of file
CLI.restart.shortDescription=Restart Hudson
CLI.keep-build.shortDescription=Mark the build to keep the build forever.
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册