package hudson.plugins.synergy.impl; import hudson.FilePath; import hudson.Launcher; import hudson.model.TaskListener; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; public class Commands implements Serializable { /** * Path to ccm executable. */ private String ccmExe; /** * Path to UI Log. */ private String ccmUiLog; /** * Path to Engine log. */ private String ccmEngLog; /** * Path to CCM_HOME. */ private String ccmHome; /** * Launcher. */ private Launcher launcher; /** * Address. */ private String ccmAddr; /** * Build listener. */ private TaskListener buildListener; public TaskListener getTaskListener() { return buildListener; } public void setTaskListener(TaskListener buildListener) { this.buildListener = buildListener; } public String getCcmAddr() { return ccmAddr; } public void setCcmAddr(String ccmAddr) { this.ccmAddr = ccmAddr; } public Launcher getLauncher() { return launcher; } public void setLauncher(Launcher launcher) { this.launcher = launcher; } public String getCcmEngLog() { return ccmEngLog; } public void setCcmEngLog(String ccmEngLog) { this.ccmEngLog = ccmEngLog; } public String getCcmUiLog() { return ccmUiLog; } public void setCcmUiLog(String ccmUiLog) { this.ccmUiLog = ccmUiLog; } public String getCcmExe() { return ccmExe; } public void setCcmExe(String ccmExe) { this.ccmExe = ccmExe; } public String getHome() { return ccmHome; } public void setCcmHome(String ccmHome) { this.ccmHome = ccmHome; } /** * Builds a compare project command. */ public String[] buildCompareProjectCommand(String newProject, String oldProject) { String[] query = new String[] { getCcmExe(), "query", "\"type!='project' and type!='dir' and is_member_of('" + newProject+ "') and not is_member_of('" + oldProject+ "')\"", "-u", "-f", "%%objectname" }; return query; } /** * Executes a Synergy command. * @param path Current directory * @param command Command and arguments * @throws IOException * @throws InterruptedException */ public void executeSynergyCommand(FilePath path, Command command) throws IOException, InterruptedException, SynergyException { Map<String, String> system = System.getenv(); List<String> param = new ArrayList<String>(); if (!launcher.isUnix() || ccmHome==null || ccmHome.length()==0){ for (Map.Entry<String, String> entry : system.entrySet()) { String s = entry.getKey() + "=" + entry.getValue(); param.add(s); } } if (ccmAddr!=null) { param.add("CCM_ADDR=" + ccmAddr); } if (ccmUiLog!=null) { param.add("CCM_UILOG=" + ccmUiLog); } if (ccmEngLog!=null) { param.add("CCM_ENGLOG=" + ccmEngLog); } if (launcher.isUnix() && ccmHome!=null && ccmHome.length()!=0){ param.add("CCM_HOME=" + ccmHome); param.add("PATH=$CCM_HOME/bin:$PATH"); } String[] env = param.toArray(new String[param.size()]); ByteArrayOutputStream out = new ByteArrayOutputStream(); String[] commands = command.buildCommand(ccmExe); boolean[] mask = command.buildMask(); if (launcher.isUnix()){ // Print Synergy command otherwise does not get printed // by launcher printCommandLine(commands, null, mask); } int result = launcher.launch().cmds(commands).masks(mask).envs(env).stdout(out).pwd(path).join(); String output = out.toString(); if (!command.isStatusOK(result, output)) { buildListener.getLogger().println("ccm command failed"); buildListener.getLogger().println(output); buildListener.getLogger().println("Command: The environment was :"); for (String s : param) { buildListener.getLogger().println(s); } throw new SynergyException(result); } else { buildListener.getLogger().println(output); } if (output!=null) { // TODO better way to handle this : distinguish mono an multi line result // and use a BufferedReader to read the lines. if (output.endsWith("\r\n")) { // DOS endline. output = output.substring(0, output.length()-2); } else if (output.endsWith("\n")) { // UNIX endline. output = output.substring(0, output.length()-1); } } command.parseResult(output); } /** * Executes a Synergy command. * @param path Current directory * @param command Command and arguments * @throws IOException * @throws InterruptedException */ public void executeSynergyCommand(FilePath path, StreamCommand command) throws IOException, InterruptedException, SynergyException { Map<String, String> system =System.getenv(); List<String> param = new ArrayList<String>(); if (!launcher.isUnix() || ccmHome==null || ccmHome.length()!=0){ for (Map.Entry<String, String> entry : system.entrySet()) { String s = entry.getKey() + "=" + entry.getValue(); param.add(s); } } if (ccmAddr!=null) { param.add("CCM_ADDR=" + ccmAddr); } if (ccmUiLog!=null) { param.add("CCM_UILOG=" + ccmUiLog); } if (ccmEngLog!=null) { param.add("CCM_ENGLOG=" + ccmEngLog); } if (launcher.isUnix() && ccmHome!=null && ccmHome.length()!=0){ param.add("CCM_HOME=" + ccmHome); param.add("PATH=$CCM_HOME/bin:$PATH"); } String[] env = param.toArray(new String[param.size()]); OutputStream out = command.buildResultOutputer(); int result; try { String[] commands = command.buildCommand(ccmExe); boolean[] mask = command.buildMask(); if (launcher.isUnix()){ // Print Synergy command otherwise does not get printed // by launcher printCommandLine(commands, null, mask); } result = launcher.launch().cmds(commands).masks(mask).envs(env).stdout(out).pwd(path).join(); } finally { out.close(); } if (result!=0 && result!=1) { buildListener.getLogger().println("ccm command failed"); buildListener.getLogger().println("StreamCommand : The environment was :"); for (String s : param) { buildListener.getLogger().println(s); } throw new SynergyException(result); } } /** * Prints out the command line to the listener so that users know what we are doing. */ protected final void printCommandLine(String[] cmd, FilePath workDir, boolean[] mask) { StringBuilder buf = new StringBuilder(); int arg_index = 0; if (workDir != null) { buf.append('['); buf.append(workDir.getRemote().replaceFirst("^.+[/\\\\]", "")); buf.append("] "); } buf.append('$'); for (String c : cmd) { String c_masked; buf.append(' '); /* determine if argument should be masked * TODO: consider displaying the password when debug mode is enabled */ if (mask[arg_index] == true){ c_masked = "******"; }else{ c_masked = c; } if(c.indexOf(' ')>=0) { if(c.indexOf('"')>=0) buf.append('\'').append(c_masked).append('\''); else buf.append('"').append(c_masked).append('"'); } else{ buf.append(c_masked); } arg_index++; } buildListener.getLogger().println(buf.toString()); } }