Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/** $Id: CvsTask.php 227 2007-08-28 02:17:00Z hans $** 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 COPYRIGHT* OWNER 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.** This software consists of voluntary contributions made by many individuals* and is licensed under the LGPL. For more information please see* <http://phing.info>.*/require_once 'phing/Task.php';include_once 'phing/tasks/system/ExecTask.php';include_once 'phing/types/Commandline.php';/*** Task for performing CVS operations.** NOTE: This implementation has been moved here from Cvs.java with* the addition of some accessors for extensibility. Another task* can extend this with some customized output processing.** @author Hans Lellelid <hans@xmpl.org> (Phing)* @author costin@dnt.ro (Ant)* @author stefano@apache.org (Ant)* @author Wolfgang Werner <wwerner@picturesafe.de> (Ant)* @author Kevin Ross <kevin.ross@bredex.com> (Ant)* @version $Revision: 1.14 $* @package phing.tasks.system*/class CvsTask extends Task {/*** Default compression level to use, if compression is enabled via* setCompression( true ).*/const DEFAULT_COMPRESSION_LEVEL = 3;private $cmd;/*** List of Commandline children* @var array Commandline[]*/private $commandlines = array();/*** the CVSROOT variable.*/private $cvsRoot;/*** the CVS_RSH variable.*/private $cvsRsh;/*** the package/module to check out.*/private $cvsModule;/*** the default command.*/private static $default_command = "checkout";/*** the CVS command to execute.*/private $command = null;/*** suppress information messages.*/private $quiet = false;/*** compression level to use.*/private $compression = 0;/*** report only, don't change any files.*/private $noexec = false;/*** CVS port*/private $port = 0;/*** CVS password file* @var File*/private $passFile = null;/*** the directory where the checked out files should be placed.* @var File*/private $dest;private $error;private $output;/*** If true it will stop the build if cvs exits with error.* Default is false. (Iulian)* @var boolean*/private $failOnError = false;public function init() {$this->cmd = new Commandline();}/*** Sets up the environment for toExecute and then runs it.* @param Commandline $toExecute* @throws BuildException*/protected function runCommand(Commandline $toExecute) {// We are putting variables into the script's environment// and not removing them (!) This should be fine, but is// worth remembering and testing.if ($this->port > 0) {putenv("CVS_CLIENT_PORT=".$this->port);}// Need a better cross platform integration with <cvspass>, so// use the same filename.if ($this->passFile === null) {$defaultPassFile = new PhingFile(Phing::getProperty("cygwin.user.home", Phing::getProperty("user.home")). DIRECTORY_SEPARATOR . ".cvspass");if($defaultPassFile->exists()) {$this->setPassfile($defaultPassFile);}}if ($this->passFile !== null) {if ($this->passFile->isFile() && $this->passFile->canRead()) {putenv("CVS_PASSFILE=" . $this->passFile->__toString());$this->log("Using cvs passfile: " . $this->passFile->__toString(), Project::MSG_INFO);} elseif (!$this->passFile->canRead()) {$this->log("cvs passfile: " . $this->passFile->__toString(). " ignored as it is not readable", Project::MSG_WARN);} else {$this->log("cvs passfile: " . $this->passFile->__toString(). " ignored as it is not a file",Project::MSG_WARN);}}if ($this->cvsRsh !== null) {putenv("CVS_RSH=".$this->cvsRsh);}// Use the ExecTask to handle execution of the command$exe = new ExecTask($this->project);$exe->setProject($this->project);//exe.setAntRun(project);if ($this->dest === null) {$this->dest = $this->project->getBaseDir();}if (!$this->dest->exists()) {$this->dest->mkdirs();}if ($this->output !== null) {$exe->setOutput($this->output);}if ($this->error !== null) {$exe->setError($this->error);}$exe->setDir($this->dest);if (is_object($toExecute)) {$toExecuteStr = $toExecute->__toString(); // unfortunately no more automagic for initial 5.0.0 release :(}$exe->setCommand($toExecuteStr);try {$actualCommandLine = $toExecuteStr; // we converted to string above$this->log($actualCommandLine, Project::MSG_INFO);$retCode = $exe->execute();$this->log("retCode=" . $retCode, Project::MSG_DEBUG);/*Throw an exception if cvs exited with error. (Iulian)*/if ($this->failOnError && $retCode !== 0) {throw new BuildException("cvs exited with error code ". $retCode. PHP_EOL. "Command line was [". $toExecute->describeCommand() . "]", $this->getLocation());}} catch (IOException $e) {if ($this->failOnError) {throw new BuildException($e, $this->getLocation());} else {$this->log("Caught exception: " . $e, Project::MSG_WARN);}} catch (BuildException $e) {if ($this->failOnError) {throw $e;} else {$t = $e->getCause();if ($t === null) {$t = $e;}$this->log("Caught exception: " . $t, Project::MSG_WARN);}} catch (Exception $e) {if ($this->failOnError) {throw new BuildException($e, $this->getLocation());} else {$this->log("Caught exception: " . $e, Project::MSG_WARN);}}}/**** @return void* @throws BuildException*/public function main() {$savedCommand = $this->getCommand();if ($this->getCommand() === null && empty($this->commandlines)) {// re-implement legacy behaviour:$this->setCommand(self::$default_command);}$c = $this->getCommand();$cloned = null;if ($c !== null) {$cloned = $this->cmd->__copy();$cloned->createArgument(true)->setLine($c);$this->addConfiguredCommandline($cloned, true);}try {for ($i = 0, $vecsize=count($this->commandlines); $i < $vecsize; $i++) {$this->runCommand($this->commandlines[$i]);}// finally {if ($cloned !== null) {$this->removeCommandline($cloned);}$this->setCommand($savedCommand);} catch (Exception $e) {// finally {if ($cloned !== null) {$this->removeCommandline($cloned);}$this->setCommand($savedCommand);throw $e;}}/*** The CVSROOT variable.** @param string $root*/public function setCvsRoot($root) {// Check if not real cvsroot => set it to nullif ($root !== null) {if (trim($root) == "") {$root = null;}}$this->cvsRoot = $root;}public function getCvsRoot() {return $this->cvsRoot;}/*** The CVS_RSH variable.** @param rsh*/public function setCvsRsh($rsh) {// Check if not real cvsrsh => set it to nullif ($rsh !== null) {if (trim($rsh) == "") {$rsh = null;}}$this->cvsRsh = $rsh;}public function getCvsRsh() {return $this->cvsRsh;}/*** Port used by CVS to communicate with the server.** @param int $port*/public function setPort($port){$this->port = $port;}/*** @return int*/public function getPort() {return $this->port;}/*** Password file to read passwords from.** @param passFile*/public function setPassfile(PhingFile $passFile) {$this->passFile = $passFile;}/*** @return File*/public function getPassFile() {return $this->passFile;}/*** The directory where the checked out files should be placed.** @param PhingFile $dest*/public function setDest(PhingFile $dest) {$this->dest = $dest;}public function getDest() {return $this->dest;}/*** The package/module to operate upon.** @param string $p*/public function setModule($m) {$this->cvsModule = $m;}public function getModule(){return $this->cvsModule;}/*** The tag of the package/module to operate upon.* @param string $p*/public function setTag($p) {// Check if not real tag => set it to nullif ($p !== null && trim($p) !== "") {$this->appendCommandArgument("-r");$this->appendCommandArgument($p);}}/*** This needs to be public to allow configuration* of commands externally.*/public function appendCommandArgument($arg) {$this->cmd->createArgument()->setValue($arg);}/*** Use the most recent revision no later than the given date.* @param p*/public function setDate($p) {if ($p !== null && trim($p) !== "") {$this->appendCommandArgument("-D");$this->appendCommandArgument($p);}}/*** The CVS command to execute.* @param string $c*/public function setCommand($c) {$this->command = $c;}public function getCommand() {return $this->command;}/*** If true, suppress informational messages.* @param boolean $q*/public function setQuiet($q) {$this->quiet = $q;}/*** If true, report only and don't change any files.** @param boolean $ne*/public function setNoexec($ne) {$this->noexec = (boolean) $ne;}/*** Stop the build process if the command exits with* a return code other than 0.* Defaults to false.* @param boolean $failOnError*/public function setFailOnError($failOnError) {$this->failOnError = (boolean) $failOnError;}/*** Configure a commandline element for things like cvsRoot, quiet, etc.* @return string*/protected function configureCommandline($c) {if ($c === null) {return;}$c->setExecutable("cvs");if ($this->cvsModule !== null) {$c->createArgument()->setLine($this->cvsModule);}if ($this->compression > 0 && $this->compression < 10) {$c->createArgument(true)->setValue("-z" . $this->compression);}if ($this->quiet) {$c->createArgument(true)->setValue("-q");}if ($this->noexec) {$c->createArgument(true)->setValue("-n");}if ($this->cvsRoot !== null) {$c->createArgument(true)->setLine("-d" . $this->cvsRoot);}}protected function removeCommandline(Commandline $c) {$idx = array_search($c, $this->commandlines, true);if ($idx === false) {return false;}$this->commandlines = array_splice($this->commandlines, $idx, 1);return true;}/*** Configures and adds the given Commandline.* @param insertAtStart If true, c is*/public function addConfiguredCommandline(Commandline $c, $insertAtStart = false) {if ($c === null) {return;}$this->configureCommandline($c);if ($insertAtStart) {array_unshift($this->commandlines, $c);} else {array_push($this->commandlines, $c);}}/*** If set to a value 1-9 it adds -zN to the cvs command line, else* it disables compression.* @param int $level*/public function setCompressionLevel($level) {$this->compression = $level;}/*** If true, this is the same as compressionlevel="3".** @param boolean $usecomp If true, turns on compression using default* level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL.*/public function setCompression($usecomp) {$this->setCompressionLevel($usecomp ?self::DEFAULT_COMPRESSION_LEVEL : 0);}/*** File to which output should be written.* @param PhingFile $output*/function setOutput(PhingFile $f) {$this->output = $f;}/*** File to which error output should be written.* @param PhingFile $output*/function setError(PhingFile $f) {$this->error = $f;}}