提交 11ab9be6 编写于 作者: J Jesse Glick

[FIXED JENKINS-23027] Added Launcher.ProcStarter.quiet option.

上级 d0340b25
......@@ -76,6 +76,9 @@ Upcoming changes</a>
<li class="rfe">
Added support for host:port format in X-Forwarded-Host header.
(<a href="https://github.com/jenkinsci/jenkins/commit/19d8b80bb2f33e4877c7170bcca8bfa318ebe77d">commit 19d8b80</a>)
<li class="rfe">
API to launch processes without printing the command line.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-23027">issue 23027</a>)
<li class="rfe">
Added option to increase impact of test failures on the weather report.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-24006">issue 24006</a>)
......
......@@ -146,6 +146,7 @@ public abstract class Launcher {
public final class ProcStarter {
protected List<String> commands;
protected boolean[] masks;
private boolean quiet;
protected FilePath pwd;
protected OutputStream stdout = NULL_OUTPUT_STREAM, stderr;
protected InputStream stdin = NULL_INPUT_STREAM;
......@@ -212,6 +213,25 @@ public abstract class Launcher {
return masks;
}
/**
* Allows {@link #maskedPrintCommandLine(List, boolean[], FilePath)} to be suppressed from {@link hudson.Launcher.LocalLauncher#launch(hudson.Launcher.ProcStarter)}.
* Useful when the actual command being printed is noisy and unreadable and the caller would rather print diagnostic information in a customized way.
* @param quiet to suppress printing the command line when starting the process; false to keep default behavior of printing
* @return this
* @since 1.576
*/
public ProcStarter quiet(boolean quiet) {
this.quiet = quiet;
return this;
}
/**
* @since 1.576
*/
public boolean quiet() {
return quiet;
}
public ProcStarter pwd(FilePath workDir) {
this.pwd = workDir;
return this;
......@@ -371,7 +391,7 @@ public abstract class Launcher {
* Copies a {@link ProcStarter}.
*/
public ProcStarter copy() {
ProcStarter rhs = new ProcStarter().cmds(commands).pwd(pwd).masks(masks).stdin(stdin).stdout(stdout).stderr(stderr).envs(envs);
ProcStarter rhs = new ProcStarter().cmds(commands).pwd(pwd).masks(masks).stdin(stdin).stdout(stdout).stderr(stderr).envs(envs).quiet(quiet);
rhs.reverseStdin = this.reverseStdin;
rhs.reverseStderr = this.reverseStderr;
rhs.reverseStdout = this.reverseStdout;
......@@ -768,7 +788,9 @@ public abstract class Launcher {
@Override
public Proc launch(ProcStarter ps) throws IOException {
maskedPrintCommandLine(ps.commands, ps.masks, ps.pwd);
if (!ps.quiet) {
maskedPrintCommandLine(ps.commands, ps.masks, ps.pwd);
}
EnvVars jobEnv = inherit(ps.envs);
......@@ -890,7 +912,7 @@ public abstract class Launcher {
final String workDir = ps.pwd==null ? null : ps.pwd.getRemote();
try {
return new ProcImpl(getChannel().call(new RemoteLaunchCallable(ps.commands, ps.masks, ps.envs, in, ps.reverseStdin, out, ps.reverseStdout, err, ps.reverseStderr, workDir, listener)));
return new ProcImpl(getChannel().call(new RemoteLaunchCallable(ps.commands, ps.masks, ps.envs, in, ps.reverseStdin, out, ps.reverseStdout, err, ps.reverseStderr, ps.quiet, workDir, listener)));
} catch (InterruptedException e) {
throw (IOException)new InterruptedIOException().initCause(e);
}
......@@ -1085,8 +1107,9 @@ public abstract class Launcher {
private final String workDir;
private final TaskListener listener;
private final boolean reverseStdin, reverseStdout, reverseStderr;
private final boolean quiet;
RemoteLaunchCallable(List<String> cmd, boolean[] masks, String[] env, InputStream in, boolean reverseStdin, OutputStream out, boolean reverseStdout, OutputStream err, boolean reverseStderr, String workDir, TaskListener listener) {
RemoteLaunchCallable(List<String> cmd, boolean[] masks, String[] env, InputStream in, boolean reverseStdin, OutputStream out, boolean reverseStdout, OutputStream err, boolean reverseStderr, boolean quiet, String workDir, TaskListener listener) {
this.cmd = new ArrayList<String>(cmd);
this.masks = masks;
this.env = env;
......@@ -1098,11 +1121,12 @@ public abstract class Launcher {
this.reverseStdin = reverseStdin;
this.reverseStdout = reverseStdout;
this.reverseStderr = reverseStderr;
this.quiet = quiet;
}
public RemoteProcess call() throws IOException {
Launcher.ProcStarter ps = new LocalLauncher(listener).launch();
ps.cmds(cmd).masks(masks).envs(env).stdin(in).stdout(out).stderr(err);
ps.cmds(cmd).masks(masks).envs(env).stdin(in).stdout(out).stderr(err).quiet(quiet);
if(workDir!=null) ps.pwd(workDir);
if (reverseStdin) ps.writeStdin();
if (reverseStdout) ps.readStdout();
......
......@@ -23,14 +23,21 @@
*/
package hudson;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Node;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Slave;
import hudson.model.StringParameterDefinition;
import hudson.model.TaskListener;
import hudson.tasks.BatchFile;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import hudson.tasks.CommandInterpreter;
import hudson.tasks.Shell;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
......@@ -86,4 +93,64 @@ public class LauncherTest {
rule.assertLogContains("original value and new value", build);
}
@Issue("JENKINS-23027")
@Test public void quiet() throws Exception {
Slave s = rule.createSlave();
boolean windows = Functions.isWindows();
FreeStyleProject p = rule.createFreeStyleProject();
p.getBuildersList().add(windows ? new BatchFile("echo printed text") : new Shell("echo printed text"));
for (Node n : new Node[] {rule.jenkins, s}) {
rule.assertLogContains(windows ? "cmd /c" : "sh -xe", runOn(p, n));
}
p.getBuildersList().clear(); // TODO .replace does not seem to work
p.getBuildersList().add(windows ? new QuietBatchFile("echo printed text") : new QuietShell("echo printed text"));
for (Node n : new Node[] {rule.jenkins, s}) {
rule.assertLogNotContains(windows ? "cmd /c" : "sh -xe", runOn(p, n));
}
}
private FreeStyleBuild runOn(FreeStyleProject p, Node n) throws Exception {
p.setAssignedNode(n);
FreeStyleBuild b = rule.buildAndAssertSuccess(p);
rule.assertLogContains("printed text", b);
return b;
}
private static final class QuietLauncher extends Launcher.DecoratedLauncher {
QuietLauncher(Launcher inner) {
super(inner);
}
@Override public Proc launch(ProcStarter starter) throws IOException {
return super.launch(starter.quiet(true));
}
}
private static final class QuietShell extends Shell {
QuietShell(String command) {
super(command);
}
@Override public boolean perform(AbstractBuild<?,?> build, Launcher launcher, TaskListener listener) throws InterruptedException {
return super.perform(build, new QuietLauncher(launcher), listener);
}
@Extension public static final class DescriptorImpl extends Shell.DescriptorImpl {
@Override public String getDisplayName() {
return "QuietShell";
}
}
}
private static final class QuietBatchFile extends BatchFile {
QuietBatchFile(String command) {
super(command);
}
@Override public boolean perform(AbstractBuild<?,?> build, Launcher launcher, TaskListener listener) throws InterruptedException {
return super.perform(build, new QuietLauncher(launcher), listener);
}
@Extension public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
@Override public String getDisplayName() {
return "QuietBatchFile";
}
@SuppressWarnings("rawtypes")
@Override public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册