diff --git a/lib/cli_compiler.php b/lib/cli_compiler.php new file mode 100755 index 000000000..48e314b71 --- /dev/null +++ b/lib/cli_compiler.php @@ -0,0 +1,320 @@ +#!/usr/bin/env php + + +Welcome to the interactive Doctrine Compiler 0.0.2 (Beta). + +To see the available command-line options, run: + --help + + + +Usage: + [path] + + [path] is the path to Doctrine's lib directory. This + is normally the directory containing the core + Doctrine class, 'Doctrine.php'. + +While the program is running: + + Default responses to questions are capitalized. Just + hit enter to provide a question's default response. + + You can quit the program at any time by pressing 'q'. + + 1) { + $doctrinePath = $argv[1]; +} else { + $doctrinePath = dirname(__FILE__); +} + +// Get Doctrine's library path + +$usablePath = false; +while (!$usablePath) { + $path = ask("Please enter the path to Doctrine's lib directory:", $doctrinePath, array($doctrinePath), false); + autoQuit($path); + try { + addIncludePath($path); + include_once 'Doctrine.php'; + spl_autoload_register(array('Doctrine', 'autoload')); + $usablePath = true; + } catch (Exception $e) { + showMessage("The path '$path' does not seem to contain the expected Doctrine class ('Doctrine.php')."); + if (($answer = ask("Would you like to specify another path?")) != 'y') { + quit(); + } + } +} + +// Process target filename command line argument + +if ($argc > 2) { + $targetFile = $argv[2]; +} else { + $targetFile = $path.DIRECTORY_SEPARATOR.'Doctrine.compiled.php'; +} + +clearstatcache(); +$usableFilename = false; +while (!$usableFilename) { + $target = ask("Please enter the target filename for the 'compiled' Doctrine file that will be created:", $targetFile, array($targetFile), false); + autoQuit($target); + if (file_exists($target)) { + if (is_writable($target) && (!is_dir($target))) { + $usableFilename = true; + } else { + $msg = "The target filename '$target' cannot be used (it is not writable, or it is a directory)."; + } + } else { + if (is_writable(dirname($target))) { + $usableFilename = true; + } else { + $msg = "The directory in which the target file will be created is not writable."; + } + } + if (!$usableFilename) { + showMessage($msg); + if (($answer = ask("Would you like to specify a different target filename?")) != 'y') { + quit(); + } + } +} + +// Define the default drivers - unfortunately, this is hard-coded for now + +$drivers = array( + 'Db2', + 'Firebird', + 'Informix', + 'Mssql', + 'Mysql', + 'Oracle', + 'Pgsql', + 'Sqlite' +); + +$includeDrivers = array(); +$excludeDrivers = array(); + +// Determine driver support + +foreach ($drivers as $driver) { + if (($answer = ask("Would you like to enable support for $driver?")) == 'y') { + $includeDrivers[] = $driver; + } else { + $excludeDrivers[] = $driver; + } + autoQuit($answer); +} + +// Verify driver support + +if (!count($includeDrivers)) { + showMessage("You have not selected any drivers. Usually this is not a good idea, unless you know what you're doing."); + if (($answer = ask("Are you sure you want to compile without any drivers?")) != 'y') { + quit(); + } + autoQuit($answer); +} + +// Try to prevent errors related to memory allocation + +$requiredMemory = '32M'; +showMessage("Trying to set the PHP memory limit to $requiredMemory..."); +ini_set('memory_limit', $requiredMemory); +if (ini_get('memory_limit') != $requiredMemory) { + showMessage("WARNING: The program could not set the PHP memory limit to $requiredMemory. The compilation might fail."); + if (($answer = ask("Do you still want to continue?")) != 'y') { + quit; + } +} else { + showMessage("PHP memory limit adjusted successfully."); +} + +// Build / 'Compile' Doctrine... + + +try { + + $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY); + + foreach ($it as $file) { + $e = explode('.', $file->getFileName()); + + // We don't want to require versioning files, or cli files + + if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false && strpos($file->getFileName(), 'cli') !== 0) { + require_once $file->getPathName(); + } + } + + $classes = array_merge(get_declared_classes(), get_declared_interfaces()); + + $ret = array(); + + foreach ($classes as $class) { + $e = explode('_', $class); + + if ($e[0] !== 'Doctrine') { + continue; + } + + // Skip excluded drivers + + $skipClass = false; + foreach ($excludeDrivers as $excludeDriver) { + if (in_array($excludeDriver, $e)) { + $skipClass = true; + break; + } + } + if ($skipClass) { + echo "\nExcluding -> $class"; + continue; + } + + $refl = new ReflectionClass($class); + $file = $refl->getFileName(); + + echo "\nIncluding -> $file"; + + $lines = file($file); + + $start = $refl->getStartLine() - 1; + $end = $refl->getEndLine(); + + $ret = array_merge($ret, array_slice($lines, $start, ($end - $start))); + } + + // first write the 'compiled' data to a text file, so + // that we can use php_strip_whitespace (which only works on files) + + $fp = @fopen($target, 'w'); + + if ($fp === false) { + throw new Exception("Couldn't write compiled data. Failed to open $target"); + } + fwrite($fp, " \ No newline at end of file