| /* |
| * Copyright 2009 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.ant.taskdefs; |
| |
| import org.apache.tools.ant.BuildException; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.LineNumberReader; |
| |
| /** |
| * Utility class to run external commands. |
| */ |
| class CommandRunner { |
| |
| /** |
| * Returns the output of running a command as a string. Will fail if the |
| * invoked process returns a non-zero status code and |
| * <code>checkStatusCode</code> is <code>true</code>. |
| */ |
| public static String getCommandOutput(boolean checkStatusCode, File workDir, |
| String... cmd) { |
| Process process = runCommandIgnoringErr(workDir, cmd); |
| StringBuilder output = new StringBuilder(); |
| LineNumberReader lnr = new LineNumberReader(new InputStreamReader( |
| process.getInputStream())); |
| try { |
| for (String line = lnr.readLine(); line != null; line = lnr.readLine()) { |
| output.append(line); |
| output.append('\n'); |
| } |
| int statusCode = process.waitFor(); |
| if (checkStatusCode && statusCode != 0) { |
| throw new BuildException("Non-zero status code result (" + statusCode |
| + ") running command: " + makeCmdString(cmd)); |
| } |
| return output.toString(); |
| } catch (IOException e) { |
| throw new BuildException("Unable to read command: " + makeCmdString(cmd), |
| e); |
| } catch (InterruptedException e) { |
| throw new BuildException("Interrupted waiting for command: " |
| + makeCmdString(cmd), e); |
| } |
| } |
| |
| /** |
| * Returns the output of running a command as a string. Will fail if the |
| * invoked process returns a non-zero status code. |
| */ |
| public static String getCommandOutput(File workDir, String... cmd) { |
| return getCommandOutput(true, workDir, cmd); |
| } |
| |
| /** |
| * Runs the specified command and returns the {@link Process}. The caller |
| * must handle both the output and error streams to avoid blocking the |
| * underlying process. |
| */ |
| public static Process runCommand(File workDir, String... cmd) { |
| ProcessBuilder pb = new ProcessBuilder(cmd); |
| pb.directory(workDir); |
| try { |
| return pb.start(); |
| } catch (IOException e) { |
| throw new BuildException("Unable to launch command: " |
| + makeCmdString(cmd), e); |
| } |
| } |
| |
| /** |
| * Runs the specified command and returns the {@link Process}. The resulting |
| * process's error stream will be continually drained in a daemon thread to |
| * prevent the underlying process from blocking. The caller must handle both |
| * output stream to avoid blocking the underlying process. |
| */ |
| public static Process runCommandIgnoringErr(File workDir, String... cmd) { |
| final Process process = runCommand(workDir, cmd); |
| // Consume error output on another thread to avoid blocking. |
| Thread errThread = new Thread(new Runnable() { |
| public void run() { |
| InputStream errorStream = process.getErrorStream(); |
| try { |
| byte[] buf = new byte[8192]; |
| int read; |
| do { |
| read = errorStream.read(buf); |
| } while (read >= 0); |
| } catch (IOException e) { |
| } finally { |
| try { |
| errorStream.close(); |
| } catch (IOException e) { |
| } |
| } |
| } |
| }); |
| errThread.setDaemon(true); |
| errThread.start(); |
| return process; |
| } |
| |
| /** |
| * Turns a command array into a printable string. |
| */ |
| static String makeCmdString(String... cmd) { |
| StringBuilder sb = new StringBuilder(); |
| for (String arg : cmd) { |
| if (sb.length() > 0) { |
| sb.append(' '); |
| } |
| sb.append(arg); |
| } |
| String cmdString = sb.toString(); |
| return cmdString; |
| } |
| } |