diff options
Diffstat (limited to 'buildscripts/phing/classes/phing/Phing.php')
-rw-r--r-- | buildscripts/phing/classes/phing/Phing.php | 1161 |
1 files changed, 0 insertions, 1161 deletions
diff --git a/buildscripts/phing/classes/phing/Phing.php b/buildscripts/phing/classes/phing/Phing.php deleted file mode 100644 index bb8d67f6..00000000 --- a/buildscripts/phing/classes/phing/Phing.php +++ /dev/null @@ -1,1161 +0,0 @@ -<?php -/* - * $Id: Phing.php,v 1.51 2006/01/06 15:12:33 hlellelid Exp $ - * - * 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/Project.php'; -require_once 'phing/ProjectComponent.php'; -require_once 'phing/Target.php'; -require_once 'phing/Task.php'; - -include_once 'phing/BuildException.php'; -include_once 'phing/BuildEvent.php'; - -include_once 'phing/parser/Location.php'; -include_once 'phing/parser/ExpatParser.php'; -include_once 'phing/parser/AbstractHandler.php'; -include_once 'phing/parser/ProjectConfigurator.php'; -include_once 'phing/parser/RootHandler.php'; -include_once 'phing/parser/ProjectHandler.php'; -include_once 'phing/parser/TaskHandler.php'; -include_once 'phing/parser/TargetHandler.php'; -include_once 'phing/parser/DataTypeHandler.php'; -include_once 'phing/parser/NestedElementHandler.php'; - -include_once 'phing/system/util/Properties.php'; -include_once 'phing/util/StringHelper.php'; -include_once 'phing/system/io/PhingFile.php'; -include_once 'phing/system/io/FileReader.php'; -include_once 'phing/system/util/Register.php'; - -/** - * Entry point into Phing. This class handles the full lifecycle of a build -- from - * parsing & handling commandline arguments to assembling the project to shutting down - * and cleaning up in the end. - * - * If you are invoking Phing from an external application, this is still - * the class to use. Your applicaiton can invoke the start() method, passing - * any commandline arguments or additional properties. - * - * @author Andreas Aderhold <andi@binarycloud.com> - * @author Hans Lellelid <hans@xmpl.org> - * @version $Revision: 1.51 $ - * @package phing - */ -class Phing { - - /** The default build file name */ - const DEFAULT_BUILD_FILENAME = "build.xml"; - - /** Our current message output status. Follows PROJECT_MSG_XXX */ - private static $msgOutputLevel = PROJECT_MSG_INFO; - - /** PhingFile that we are using for configuration */ - private $buildFile = null; - - /** The build targets */ - private $targets = array(); - - /** - * Set of properties that are passed in from commandline or invoking code. - * @var Properties - */ - private static $definedProps; - - /** Names of classes to add as listeners to project */ - private $listeners = array(); - - private $loggerClassname = null; - - /** The class to handle input (can be only one). */ - private $inputHandlerClassname; - - /** Indicates if this phing should be run */ - private $readyToRun = false; - - /** Indicates we should only parse and display the project help information */ - private $projectHelp = false; - - /** Used by utility function getResourcePath() */ - private static $importPaths; - - /** System-wide static properties (moved from System) */ - private static $properties = array(); - - /** Static system timer. */ - private static $timer; - - /** The current Project */ - private static $currentProject; - - /** Whether to capture PHP errors to buffer. */ - private static $phpErrorCapture = false; - - /** Array of captured PHP errors */ - private static $capturedPhpErrors = array(); - - /** - * Prints the message of the Exception if it's not null. - */ - function printMessage(Exception $t) { - print($t->getMessage() . "\n"); - if (self::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { - print($t->getTraceAsString()."\n"); - if ($t instanceof Exception) { - $c = $t->getCause(); - if ($c !== null) { - print("Wrapped exception trace:\n"); - print($c->getTraceAsString() . "\n"); - } - } - } // if output level is DEBUG - } - - /** - * Entry point allowing for more options from other front ends. - * - * This method encapsulates the complete build lifecycle. - * - * @param array &$args The commandline args passed to phing shell script. - * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this). - * These additional properties will be available using the getDefinedProperty() method and will - * be added to the project's "user" properties. - * @return void - * @see execute() - * @see runBuild() - */ - public static function start(&$args, $additionalUserProperties = null) { - - try { - $m = new Phing(); - $m->execute($args); - } catch (Exception $exc) { - $m->printMessage($exc); - self::halt(-1); // Parameter error - } - - if ($additionalUserProperties !== null) { - $keys = $m->additionalUserProperties->keys(); - while(count($keys)) { - $key = array_shift($keys); - $property = $m->additionalUserProperties->getProperty($key); - $m->setDefinedProperty($key, $property); - } - } - - try { - $m->runBuild(); - } catch(Exception $exc) { - self::halt(1); // Errors occured - } - - // everything fine, shutdown - self::halt(0); // no errors, everything is cake - } - - /** - * Making output level a static property so that this property - * can be accessed by other parts of the system, enabling - * us to display more information -- e.g. backtraces -- for "debug" level. - * @return int - */ - public static function getMsgOutputLevel() { - return self::$msgOutputLevel; - } - - /** - * Command line entry point. This method kicks off the building - * of a project object and executes a build using either a given - * target or the default target. - * - * @param array $args Command line args. - * @return void - */ - public static function fire($args) { - self::start($args, null); - } - - /** - * Setup/initialize Phing environment from commandline args. - * @param array $args commandline args passed to phing shell. - * @return void - */ - public function execute($args) { - - self::$definedProps = new Properties(); - $this->searchForThis = null; - - // cycle through given args - for ($i = 0, $argcount = count($args); $i < $argcount; ++$i) { - // ++$i intentional here, as first param is script name - $arg = $args[$i]; - - if ($arg == "-help" || $arg == "-h") { - $this->printUsage(); - return; - } elseif ($arg == "-version" || $arg == "-v") { - $this->printVersion(); - return; - } elseif ($arg == "-quiet" || $arg == "-q") { - self::$msgOutputLevel = PROJECT_MSG_WARN; - } elseif ($arg == "-verbose") { - $this->printVersion(); - self::$msgOutputLevel = PROJECT_MSG_VERBOSE; - } elseif ($arg == "-debug") { - $this->printVersion(); - self::$msgOutputLevel = PROJECT_MSG_DEBUG; - } elseif ($arg == "-logfile") { - try { // try to set logfile - if (!isset($args[$i+1])) { - print("You must specify a log file when using the -logfile argument\n"); - return; - } else { - $logFile = new PhingFile($args[++$i]); - $this->loggerClassname = 'phing.listener.PearLogger'; - $this->setDefinedProperty('pear.log.name', $logFile->getAbsolutePath()); - } - } catch (IOException $ioe) { - print("Cannot write on the specified log file. Make sure the path exists and you have write permissions.\n"); - throw $ioe; - } - } elseif ($arg == "-buildfile" || $arg == "-file" || $arg == "-f") { - if (!isset($args[$i+1])) { - print("You must specify a buildfile when using the -buildfile argument\n"); - return; - } else { - $this->buildFile = new PhingFile($args[++$i]); - } - } elseif ($arg == "-listener") { - if (!isset($args[$i+1])) { - print("You must specify a listener class when using the -listener argument\n"); - return; - } else { - $this->listeners[] = $args[++$i]; - } - - } elseif (StringHelper::startsWith("-D", $arg)) { - $name = substr($arg, 2); - $value = null; - $posEq = strpos($name, "="); - if ($posEq !== false) { - $value = substr($name, $posEq+1); - $name = substr($name, 0, $posEq); - } elseif ($i < count($args)-1) { - $value = $args[++$i]; - } - self::$definedProps->setProperty($name, $value); - } elseif ($arg == "-logger") { - if (!isset($args[$i+1])) { - print("You must specify a classname when using the -logger argument\n"); - return; - } else { - $this->loggerClassname = $args[++$i]; - } - } elseif ($arg == "-inputhandler") { - if ($this->inputHandlerClassname !== null) { - throw new BuildException("Only one input handler class may be specified."); - } - if (!isset($args[$i+1])) { - print("You must specify a classname when using the -inputhandler argument\n"); - return; - } else { - $this->inputHandlerClassname = $args[++$i]; - } - } elseif ($arg == "-projecthelp" || $arg == "-targets" || $arg == "-list" || $arg == "-l") { - // set the flag to display the targets and quit - $this->projectHelp = true; - } elseif ($arg == "-find") { - // eat up next arg if present, default to build.xml - if ($i < count($args)-1) { - $this->searchForThis = $args[++$i]; - } else { - $this->searchForThis = self::DEFAULT_BUILD_FILENAME; - } - } elseif (substr($arg,0,1) == "-") { - // we don't have any more args - print("Unknown argument: $arg\n"); - $this->printUsage(); - return; - } else { - // if it's no other arg, it may be the target - array_push($this->targets, $arg); - } - } - - // if buildFile was not specified on the command line, - if ($this->buildFile === null) { - // but -find then search for it - if ($this->searchForThis !== null) { - $this->buildFile = $this->_findBuildFile(self::getProperty("user.dir"), $this->searchForThis); - } else { - $this->buildFile = new PhingFile(self::DEFAULT_BUILD_FILENAME); - } - } - // make sure buildfile exists - if (!$this->buildFile->exists()) { - throw new BuildException("Buildfile: " . $this->buildFile->__toString() . " does not exist!"); - } - - // make sure it's not a directory - if ($this->buildFile->isDirectory()) { - throw new BuildException("Buildfile: " . $this->buildFile->__toString() . " is a dir!"); - } - - $this->readyToRun = true; - } - - /** - * Helper to get the parent file for a given file. - * - * @param PhingFile $file - * @return PhingFile Parent file or null if none - */ - function _getParentFile(PhingFile $file) { - $filename = $file->getAbsolutePath(); - $file = new PhingFile($filename); - $filename = $file->getParent(); - - if ($filename !== null && self::$msgOutputLevel >= PROJECT_MSG_VERBOSE) { - print("Searching in $filename\n"); - } - - return ($filename === null) ? null : new PhingFile($filename); - } - - /** - * Search parent directories for the build file. - * - * Takes the given target as a suffix to append to each - * parent directory in search of a build file. Once the - * root of the file-system has been reached an exception - * is thrown. - * - * @param string $start Start file path. - * @param string $suffix Suffix filename to look for in parents. - * @return PhingFile A handle to the build file - * - * @throws BuildException Failed to locate a build file - */ - function _findBuildFile($start, $suffix) { - if (self::$msgOutputLevel >= PROJECT_MSG_INFO) { - print("Searching for $suffix ...\n"); - } - $startf = new PhingFile($start); - $parent = new PhingFile($startf->getAbsolutePath()); - $file = new PhingFile($parent, $suffix); - - // check if the target file exists in the current directory - while (!$file->exists()) { - // change to parent directory - $parent = $this->_getParentFile($parent); - - // if parent is null, then we are at the root of the fs, - // complain that we can't find the build file. - if ($parent === null) { - throw new BuildException("Could not locate a build file!"); - } - // refresh our file handle - $file = new PhingFile($parent, $suffix); - } - return $file; - } - - /** - * Executes the build. - * @return void - */ - function runBuild() { - - if (!$this->readyToRun) { - return; - } - - $project = new Project(); - - self::setCurrentProject($project); - set_error_handler(array('Phing', 'handlePhpError')); - - $error = null; - - $this->addBuildListeners($project); - $this->addInputHandler($project); - - // set this right away, so that it can be used in logging. - $project->setUserProperty("phing.file", $this->buildFile->getAbsolutePath()); - - try { - $project->fireBuildStarted(); - $project->init(); - } catch (Exception $exc) { - $project->fireBuildFinished($exc); - throw $exc; - } - - $project->setUserProperty("phing.version", $this->getPhingVersion()); - - $e = self::$definedProps->keys(); - while (count($e)) { - $arg = (string) array_shift($e); - $value = (string) self::$definedProps->getProperty($arg); - $project->setUserProperty($arg, $value); - } - unset($e); - - $project->setUserProperty("phing.file", $this->buildFile->getAbsolutePath()); - - // first use the Configurator to create the project object - // from the given build file. - - try { - ProjectConfigurator::configureProject($project, $this->buildFile); - } catch (Exception $exc) { - $project->fireBuildFinished($exc); - restore_error_handler(); - self::unsetCurrentProject(); - throw $exc; - } - - // make sure that we have a target to execute - if (count($this->targets) === 0) { - $this->targets[] = $project->getDefaultTarget(); - } - - // execute targets if help param was not given - if (!$this->projectHelp) { - - try { - $project->executeTargets($this->targets); - } catch (Exception $exc) { - $project->fireBuildFinished($exc); - restore_error_handler(); - self::unsetCurrentProject(); - throw $exc; - } - } - // if help is requested print it - if ($this->projectHelp) { - try { - $this->printDescription($project); - $this->printTargets($project); - } catch (Exception $exc) { - $project->fireBuildFinished($exc); - restore_error_handler(); - self::unsetCurrentProject(); - throw $exc; - } - } - - // finally { - if (!$this->projectHelp) { - $project->fireBuildFinished(null); - } - - restore_error_handler(); - self::unsetCurrentProject(); - } - - /** - * Bind any default build listeners to this project. - * Currently this means adding the logger. - * @param Project $project - * @return void - */ - private function addBuildListeners(Project $project) { - // Add the default listener - $project->addBuildListener($this->createLogger()); - } - - /** - * Creates the InputHandler and adds it to the project. - * - * @param Project $project the project instance. - * - * @throws BuildException if a specified InputHandler - * class could not be loaded. - */ - private function addInputHandler(Project $project) { - if ($this->inputHandlerClassname === null) { - $handler = new DefaultInputHandler(); - } else { - try { - $clz = Phing::import($this->inputHandlerClassname); - $handler = new $clz(); - if ($project !== null && method_exists($handler, 'setProject')) { - $handler->setProject($project); - } - } catch (Exception $e) { - $msg = "Unable to instantiate specified input handler " - . "class " . $this->inputHandlerClassname . " : " - . $e->getMessage(); - throw new BuildException($msg); - } - } - $project->setInputHandler($handler); - } - - /** - * Creates the default build logger for sending build events to the log. - * @return BuildListener The created Logger - */ - private function createLogger() { - if ($this->loggerClassname !== null) { - self::import($this->loggerClassname); - // get class name part - $classname = self::import($this->loggerClassname); - $logger = new $classname; - } else { - require_once 'phing/listener/DefaultLogger.php'; - $logger = new DefaultLogger(); - } - $logger->setMessageOutputLevel(self::$msgOutputLevel); - return $logger; - } - - /** - * Sets the current Project - * @param Project $p - */ - public static function setCurrentProject($p) { - self::$currentProject = $p; - } - - /** - * Unsets the current Project - */ - public static function unsetCurrentProject() { - self::$currentProject = null; - } - - /** - * Gets the current Project. - * @return Project Current Project or NULL if none is set yet/still. - */ - public static function getCurrentProject() { - return self::$currentProject; - } - - /** - * A static convenience method to send a log to the current (last-setup) Project. - * If there is no currently-configured Project, then this will do nothing. - * @param string $message - * @param int $priority PROJECT_MSG_INFO, etc. - */ - public static function log($message, $priority = PROJECT_MSG_INFO) { - $p = self::getCurrentProject(); - if ($p) { - $p->log($message, $priority); - } - } - - /** - * Error handler for PHP errors encountered during the build. - * This uses the logging for the currently configured project. - */ - public static function handlePhpError($level, $message, $file, $line) { - - // don't want to print supressed errors - if (error_reporting() > 0) { - - if (self::$phpErrorCapture) { - - self::$capturedPhpErrors[] = array('message' => $message, 'level' => $level, 'line' => $line, 'file' => $file); - - } else { - - $message = '[PHP Error] ' . $message; - $message .= ' [line ' . $line . ' of ' . $file . ']'; - - switch ($level) { - - case E_STRICT: - case E_NOTICE: - case E_USER_NOTICE: - self::log($message, PROJECT_MSG_VERBOSE); - break; - case E_WARNING: - case E_USER_WARNING: - self::log($message, PROJECT_MSG_WARN); - break; - case E_ERROR: - case E_USER_ERROR: - default: - self::log($message, PROJECT_MSG_ERR); - - } // switch - - } // if phpErrorCapture - - } // if not @ - - } - - /** - * Begins capturing PHP errors to a buffer. - * While errors are being captured, they are not logged. - */ - public static function startPhpErrorCapture() { - self::$phpErrorCapture = true; - self::$capturedPhpErrors = array(); - } - - /** - * Stops capturing PHP errors to a buffer. - * The errors will once again be logged after calling this method. - */ - public static function stopPhpErrorCapture() { - self::$phpErrorCapture = false; - } - - /** - * Clears the captured errors without affecting the starting/stopping of the capture. - */ - public static function clearCapturedPhpErrors() { - self::$capturedPhpErrors = array(); - } - - /** - * Gets any PHP errors that were captured to buffer. - * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level) - */ - public static function getCapturedPhpErrors() { - return self::$capturedPhpErrors; - } - - /** Prints the usage of how to use this class */ - function printUsage() { - $lSep = self::getProperty("line.separator"); - $msg = ""; - $msg .= "phing [options] [target [target2 [target3] ...]]" . $lSep; - $msg .= "Options: " . $lSep; - $msg .= " -h -help print this message" . $lSep; - $msg .= " -l -list list available targets in this project" . $lSep; - $msg .= " -v -version print the version information and exit" . $lSep; - $msg .= " -q -quiet be extra quiet" . $lSep; - $msg .= " -verbose be extra verbose" . $lSep; - $msg .= " -debug print debugging information" . $lSep; - $msg .= " -logfile <file> use given file for log" . $lSep; - $msg .= " -logger <classname> the class which is to perform logging" . $lSep; - $msg .= " -f -buildfile <file> use given buildfile" . $lSep; - $msg .= " -D<property>=<value> use value for given property" . $lSep; - $msg .= " -find <file> search for buildfile towards the root of the" . $lSep; - $msg .= " filesystem and use it" . $lSep; - //$msg .= " -recursive <file> search for buildfile downwards and use it" . $lSep; - $msg .= $lSep; - $msg .= "Report bugs to <dev@phing.tigris.org>".$lSep; - print($msg); - } - - function printVersion() { - print(self::getPhingVersion()."\n"); - } - - function getPhingVersion() { - $versionPath = self::getResourcePath("phing/etc/VERSION.TXT"); - if ($versionPath === null) { - $versionPath = self::getResourcePath("etc/VERSION.TXT"); - } - try { // try to read file - $buffer = null; - $file = new PhingFile($versionPath); - $reader = new FileReader($file); - $reader->readInto($buffer); - $buffer = trim($buffer); - //$buffer = "PHING version 1.0, Released 2002-??-??"; - $phingVersion = $buffer; - } catch (IOException $iox) { - print("Can't read version information file\n"); - throw new BuildException("Build failed"); - } - return $phingVersion; - } - - /** Print the project description, if any */ - function printDescription(Project $project) { - if ($project->getDescription() !== null) { - print($project->getDescription()."\n"); - } - } - - /** Print out a list of all targets in the current buildfile */ - function printTargets($project) { - // find the target with the longest name - $maxLength = 0; - $targets = $project->getTargets(); - $targetNames = array_keys($targets); - $targetName = null; - $targetDescription = null; - $currentTarget = null; - - // split the targets in top-level and sub-targets depending - // on the presence of a description - - $subNames = array(); - $topNameDescMap = array(); - - foreach($targets as $currentTarget) { - $targetName = $currentTarget->getName(); - $targetDescription = $currentTarget->getDescription(); - - // subtargets are targets w/o descriptions - if ($targetDescription === null) { - $subNames[] = $targetName; - } else { - // topNames and topDescriptions are handled later - // here we store in hash map (for sorting purposes) - $topNameDescMap[$targetName] = $targetDescription; - if (strlen($targetName) > $maxLength) { - $maxLength = strlen($targetName); - } - } - } - - // Sort the arrays - sort($subNames); // sort array values, resetting keys (which are numeric) - ksort($topNameDescMap); // sort the keys (targetName) keeping key=>val associations - - $topNames = array_keys($topNameDescMap); - $topDescriptions = array_values($topNameDescMap); - - $defaultTarget = $project->getDefaultTarget(); - - if ($defaultTarget !== null && $defaultTarget !== "") { - $defaultName = array(); - $defaultDesc = array(); - $defaultName[] = $defaultTarget; - - $indexOfDefDesc = array_search($defaultTarget, $topNames, true); - if ($indexOfDefDesc !== false && $indexOfDefDesc >= 0) { - $defaultDesc = array(); - $defaultDesc[] = $topDescriptions[$indexOfDefDesc]; - } - - $this->_printTargets($defaultName, $defaultDesc, "Default target:", $maxLength); - - } - $this->_printTargets($topNames, $topDescriptions, "Main targets:", $maxLength); - $this->_printTargets($subNames, null, "Subtargets:", 0); - } - - /** - * Writes a formatted list of target names with an optional description. - * - * @param array $names The names to be printed. - * Must not be <code>null</code>. - * @param array $descriptions The associated target descriptions. - * May be <code>null</code>, in which case - * no descriptions are displayed. - * If non-<code>null</code>, this should have - * as many elements as <code>names</code>. - * @param string $heading The heading to display. - * Should not be <code>null</code>. - * @param int $maxlen The maximum length of the names of the targets. - * If descriptions are given, they are padded to this - * position so they line up (so long as the names really - * <i>are</i> shorter than this). - */ - private function _printTargets($names, $descriptions, $heading, $maxlen) { - $lSep = self::getProperty("line.separator"); - $spaces = ' '; - while (strlen($spaces) < $maxlen) { - $spaces .= $spaces; - } - $msg = ""; - $msg .= $heading . $lSep; - $msg .= str_repeat("-",79) . $lSep; - - $total = count($names); - for($i=0; $i < $total; $i++) { - $msg .= " "; - $msg .= $names[$i]; - if (!empty($descriptions)) { - $msg .= substr($spaces, 0, $maxlen - strlen($names[$i]) + 2); - $msg .= $descriptions[$i]; - } - $msg .= $lSep; - } - if ($total > 0) { - print $msg . $lSep; - } - } - - /** - * Import a dot-path notation class path. - * @param string $dotPath - * @param mixed $classpath String or object supporting __toString() - * @return string The unqualified classname (which can be instantiated). - * @throws BuildException - if cannot find the specified file - */ - public static function import($dotPath, $classpath = null) { - - // first check to see that the class specified hasn't already been included. - // (this also handles case where this method is called w/ a classname rather than dotpath) - $classname = StringHelper::unqualify($dotPath); - if (class_exists($classname, false)) { - return $classname; - } - - $dotClassname = basename($dotPath); - $dotClassnamePos = strlen($dotPath) - strlen($dotClassname); - $classFile = strtr($dotClassname, '.', DIRECTORY_SEPARATOR) . ".php"; - $path = substr_replace($dotPath, $classFile, $dotClassnamePos); - - Phing::__import($path, $classpath); - - return $classname; - } - - /** - * Import a PHP file - * @param string $path Path to the PHP file - * @param mixed $classpath String or object supporting __toString() - * @throws BuildException - if cannot find the specified file - */ - public static function __import($path, $classpath = null) { - - if ($classpath) { - - // Apparently casting to (string) no longer invokes __toString() automatically. - if (is_object($classpath)) { - $classpath = $classpath->__toString(); - } - - // classpaths are currently additive, but we also don't want to just - // indiscriminantly prepand/append stuff to the include_path. This means - // we need to parse current incldue_path, and prepend any - // specified classpath locations that are not already in the include_path. - // - // NOTE: the reason why we do it this way instead of just changing include_path - // and then changing it back, is that in many cases applications (e.g. Propel) will - // include/require class files from within method calls. This means that not all - // necessary files will be included in this import() call, and hence we can't - // change the include_path back without breaking those apps. While this method could - // be more expensive than switching & switching back (not sure, but maybe), it makes it - // possible to write far less expensive run-time applications (e.g. using Propel), which is - // really where speed matters more. - - $curr_parts = explode(PATH_SEPARATOR, ini_get('include_path')); - $add_parts = explode(PATH_SEPARATOR, $classpath); - $new_parts = array_diff($add_parts, $curr_parts); - if ($new_parts) { - if (self::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { - print("Phing::import() prepending new include_path components: " . implode(PATH_SEPARATOR, $new_parts) . "\n"); - } - ini_set('include_path', implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts))); - } - } - - $ret = include_once($path); - - if ($ret === false) { - $e = new BuildException("Error importing $path"); - if (self::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { - // We can't log this because listeners belong - // to projects. We'll just print it -- of course - // that isn't very compatible w/ other frontends (but - // there aren't any right now, so I'm not stressing) - print("Error importing $path\n"); - print($e->getTraceAsString()."\n"); - } - throw $e; - } - - return; - } - - /** - * Looks on include path for specified file. - * @return string File found (null if no file found). - */ - public static function getResourcePath($path) { - - if (self::$importPaths === null) { - $paths = ini_get("include_path"); - self::$importPaths = explode(PATH_SEPARATOR, ini_get("include_path")); - } - - $path = str_replace('\\', DIRECTORY_SEPARATOR, $path); - $path = str_replace('/', DIRECTORY_SEPARATOR, $path); - - foreach (self::$importPaths as $prefix) { - $foo_path = $prefix . DIRECTORY_SEPARATOR . $path; - if (file_exists($foo_path)) { - return $foo_path; - } - } - - // Check for the property phing.home - $home_dir = self::getProperty('phing.home'); - - if ($home_dir) - { - $home_path = $home_dir . DIRECTORY_SEPARATOR . $path; - - if (file_exists($home_path)) - { - return $home_path; - } - } - - // If we are using this via PEAR then check for the file in the data dir - // This is a bit of a hack, but works better than previous solution of assuming - // data_dir is on the include_path. - $data_dir = '@DATA-DIR@'; - if ($data_dir{0} != '@') { // if we're using PEAR then the @ DATA-DIR @ token will have been substituted. - $data_path = $data_dir . DIRECTORY_SEPARATOR . $path; - if (file_exists($data_path)) { - return $data_path; - } - } - - return null; - } - - // ------------------------------------------------------------------------------------------- - // System-wide methods (moved from System class, which had namespace conflicts w/ PEAR System) - // ------------------------------------------------------------------------------------------- - - /** - * Set System constants which can be retrieved by calling Phing::getProperty($propName). - * @return void - */ - private static function setSystemConstants() { - - /* - * PHP_OS returns on - * WindowsNT4.0sp6 => WINNT - * Windows2000 => WINNT - * Windows ME => WIN32 - * Windows 98SE => WIN32 - * FreeBSD 4.5p7 => FreeBSD - * Redhat Linux => Linux - * Mac OS X => Darwin - */ - self::setProperty('host.os', PHP_OS); - - // this is used by some tasks too - self::setProperty('os.name', PHP_OS); - - // it's still possible this won't be defined, - // e.g. if Phing is being included in another app w/o - // using the phing.php script. - if (!defined('PHP_CLASSPATH')) { - define('PHP_CLASSPATH', get_include_path()); - } - - self::setProperty('php.classpath', PHP_CLASSPATH); - - // try to determine the host filesystem and set system property - // used by Fileself::getFileSystem to instantiate the correct - // abstraction layer - - switch (strtoupper(PHP_OS)) { - case 'WINNT': - self::setProperty('host.fstype', 'WINNT'); - break; - case 'WIN32': - self::setProperty('host.fstype', 'WIN32'); - break; - default: - self::setProperty('host.fstype', 'UNIX'); - break; - } - - self::setProperty('php.version', PHP_VERSION); - self::setProperty('user.home', getenv('HOME')); - self::setProperty('application.startdir', getcwd()); - self::setProperty('line.separator', "\n"); - - // try to detect machine dependent information - $sysInfo = array(); - if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && function_exists("posix_uname")) { - $sysInfo = posix_uname(); - } else { - $sysInfo['nodename'] = php_uname('n'); - $sysInfo['machine']= php_uname('m') ; - //this is a not so ideal substition, but maybe better than nothing - $sysInfo['domain'] = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : "unknown"; - $sysInfo['release'] = php_uname('r'); - $sysInfo['version'] = php_uname('v'); - } - - - self::setProperty("host.name", isset($sysInfo['nodename']) ? $sysInfo['nodename'] : "unknown"); - self::setProperty("host.arch", isset($sysInfo['machine']) ? $sysInfo['machine'] : "unknown"); - self::setProperty("host.domain",isset($sysInfo['domain']) ? $sysInfo['domain'] : "unknown"); - self::setProperty("host.os.release", isset($sysInfo['release']) ? $sysInfo['release'] : "unknown"); - self::setProperty("host.os.version", isset($sysInfo['version']) ? $sysInfo['version'] : "unknown"); - unset($sysInfo); - } - - /** - * This gets a property that was set via command line or otherwise passed into Phing. - * "Defined" in this case means "externally defined". The reason this method exists is to - * provide a public means of accessing commandline properties for (e.g.) logger or listener - * scripts. E.g. to specify which logfile to use, PearLogger needs to be able to access - * the pear.log.name property. - * - * @param string $name - * @return string value of found property (or null, if none found). - */ - public static function getDefinedProperty($name) { - return self::$definedProps->getProperty($name); - } - - /** - * This sets a property that was set via command line or otherwise passed into Phing. - * - * @param string $name - * @return string value of found property (or null, if none found). - */ - public static function setDefinedProperty($name, $value) { - return self::$definedProps->setProperty($name, $value); - } - - /** - * Returns property value for a System property. - * System properties are "global" properties like line.separator, - * and user.dir. Many of these correspond to similar properties in Java - * or Ant. - * - * @param string $paramName - * @return string Value of found property (or null, if none found). - */ - public static function getProperty($propName) { - - // some properties are detemined on each access - // some are cached, see below - - // default is the cached value: - $val = isset(self::$properties[$propName]) ? self::$properties[$propName] : null; - - // special exceptions - switch($propName) { - case 'user.dir': - $val = getcwd(); - break; - } - - return $val; - } - - /** Retuns reference to all properties*/ - public static function &getProperties() { - return self::$properties; - } - - public static function setProperty($propName, $propValue) { - $propName = (string) $propName; - $oldValue = self::getProperty($propName); - self::$properties[$propName] = $propValue; - return $oldValue; - } - - public static function currentTimeMillis() { - list($usec, $sec) = explode(" ",microtime()); - return ((float)$usec + (float)$sec); - } - - /** - * Sets the include path based on PHP_CLASSPATH constant (set in phing.php). - * @return void - */ - private static function setIncludePaths() { - $success = false; - - if (defined('PHP_CLASSPATH')) { - $success = ini_set('include_path', PHP_CLASSPATH); - } else { - // don't do anything, just assume that include_path has been properly set. - $success = true; - } - - if ($success === false) { - print("SYSTEM FAILURE: Could not set PHP include path\n"); - self::halt(-1); - } - } - - /** - * Sets PHP INI values that Phing needs. - * @return void - */ - private static function setIni() { - error_reporting(E_ALL); - set_time_limit(0); - ini_set('magic_quotes_gpc', 'off'); - ini_set('short_open_tag', 'off'); - ini_set('default_charset', 'iso-8859-1'); - ini_set('register_globals', 'off'); - ini_set('allow_call_time_pass_reference', 'on'); - - // should return memory limit in MB - $mem_limit = (int) ini_get('memory_limit'); - if ($mem_limit < 32) { - ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects - } - } - - /** - * Returns reference to Timer object. - * @return Timer - */ - public static function getTimer() { - if (self::$timer === null) { - include_once 'phing/system/util/Timer.php'; - self::$timer= new Timer(); - } - return self::$timer; - } - - /** - * Start up Phing. - * Sets up the Phing environment -- does NOT initiate the build process. - * @return void - */ - public static function startup() { - - register_shutdown_function(array('Phing', 'shutdown')); - - // some init stuff - self::getTimer()->start(); - - self::setSystemConstants(); - self::setIncludePaths(); - self::setIni(); - } - - /** - * Halts the system. - * @see shutdown() - */ - public static function halt($code=0) { - self::shutdown($code); - } - - /** - * Stops timers & exits. - * @return void - */ - public static function shutdown($exitcode = 0) { - //print("[AUTOMATIC SYSTEM SHUTDOWN]\n"); - self::getTimer()->stop(); - exit($exitcode); // final point where everything stops - } - -} |