/******************************************************************************** * CruiseControl, a Continuous Integration Toolkit * Copyright (c) 2003, ThoughtWorks, Inc. * 200 E. Randolph, 25th Floor * Chicago, IL 60601 USA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * + Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * + Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the * names of its contributors may be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************************/ package net.sourceforge.cruisecontrol.builders; import java.util.StringTokenizer; import org.jdom.Element; import org.jdom.CDATA; import net.sourceforge.cruisecontrol.CruiseControlException; import net.sourceforge.cruisecontrol.Progress; import net.sourceforge.cruisecontrol.util.Commandline; import net.sourceforge.cruisecontrol.util.StreamConsumer; /** * Rake script class. * * Contains all the details related to running a Rake based build. * @author Kirk Knoernschild * @author Florian Gilcher */ public class RakeScript implements Script, StreamConsumer { private boolean isWindows; private String buildFile = null; private String target = ""; private Progress progress; private int exitCode; private Element buildLogElement; private String rubyExecutable; private String rakeExecutable; public RakeScript() { setExecutables("ruby", "rake"); } public RakeScript(String rubyExecutable, String rakeExecutable) { super(); setExecutables(rubyExecutable, rakeExecutable); } /** * construct the command that we're going to execute. * Takes the form {@code "<rubyExecutable> -S <rakeExecutable> rakeArguments"} * * @return Commandline holding command to be executed * @throws CruiseControlException on unquotable attributes */ public Commandline buildCommandline() throws CruiseControlException { final Commandline cmdLine = new Commandline(); if (isWindows) { cmdLine.setExecutable("cmd"); cmdLine.createArgument().setValue("/c"); cmdLine.createArgument().setValue(rubyExecutable); } else { cmdLine.setExecutable(rubyExecutable); } cmdLine.createArgument().setValue("-S"); cmdLine.createArgument().setValue(rakeExecutable); if (buildFile != null) { cmdLine.createArgument().setValue("-f"); cmdLine.createArgument().setValue(buildFile); } final StringTokenizer targets = new StringTokenizer(target); while (targets.hasMoreTokens()) { cmdLine.createArgument().setValue(targets.nextToken()); } return cmdLine; } /** * set the "header" for this part of the build log. * @param buildLogElement the element of the build log */ public void setBuildLogHeader(final Element buildLogElement) { this.buildLogElement = buildLogElement; } /** * @param isWindows The isWindows to set. */ public void setWindows(final boolean isWindows) { this.isWindows = isWindows; } /** * @param rubyExecutable the ruby executable * @param rakeExecutable the rake executable */ private void setExecutables(final String rubyExecutable, final String rakeExecutable) { this.rubyExecutable = rubyExecutable; this.rakeExecutable = rakeExecutable; } /** * @param buildFile The buildFile to set. */ public void setBuildFile(final String buildFile) { this.buildFile = buildFile; } /** * @param target The target to set. */ public void setTarget(final String target) { this.target = target; } /** @param progress The progress callback object to set. */ public void setProgress(final Progress progress) { this.progress = progress; } /** * @return Returns the exitCode. */ public int getExitCode() { return exitCode; } /** * @param exitCode The exitCode to set. */ public void setExitCode(final int exitCode) { this.exitCode = exitCode; } /** * Ugly parsing of Rake output into some Elements. * Gets called from StreamPumper. * @param line the line of output to parse */ public synchronized void consumeLine(final String line) { if (line == null || line.length() == 0 || buildLogElement == null) { return; } synchronized (buildLogElement) { if (line.startsWith("rake aborted!")) { buildLogElement.setAttribute("error", "BUILD FAILED detected"); } else { final Element msg = new Element("message"); msg.addContent(new CDATA(line)); msg.setAttribute("priority", "info"); buildLogElement.addContent(msg); } if (progress != null) { progress.setValue(line); } } } }