sonarrradarrplexorganizrnginxdashboardmuximuxlandingpagestartpagelandinghtpcserverhomepagesabnzbdheimdallembycouchpotatonzbgetbookmarkapplication-dashboard
		
		
		
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							337 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							337 lines
						
					
					
						
							11 KiB
						
					
					
				| <?php | |
| 
 | |
| /* | |
|  * This file is part of Psy Shell. | |
|  * | |
|  * (c) 2012-2017 Justin Hileman | |
|  * | |
|  * For the full copyright and license information, please view the LICENSE | |
|  * file that was distributed with this source code. | |
|  */ | |
| 
 | |
| namespace Psy; | |
| 
 | |
| use Psy\VersionUpdater\GitHubChecker; | |
| use Symfony\Component\Console\Input\ArgvInput; | |
| use Symfony\Component\Console\Input\InputArgument; | |
| use Symfony\Component\Console\Input\InputDefinition; | |
| use Symfony\Component\Console\Input\InputOption; | |
| use XdgBaseDir\Xdg; | |
| 
 | |
| if (!function_exists('Psy\sh')) { | |
|     /** | |
|      * Command to return the eval-able code to startup PsySH. | |
|      * | |
|      *     eval(\Psy\sh()); | |
|      * | |
|      * @return string | |
|      */ | |
|     function sh() | |
|     { | |
|         return 'extract(\Psy\debug(get_defined_vars(), isset($this) ? $this : null));'; | |
|     } | |
| } | |
| 
 | |
| if (!function_exists('Psy\debug')) { | |
|     /** | |
|      * Invoke a Psy Shell from the current context. | |
|      * | |
|      * For example: | |
|      * | |
|      *     foreach ($items as $item) { | |
|      *         \Psy\debug(get_defined_vars()); | |
|      *     } | |
|      * | |
|      * If you would like your shell interaction to affect the state of the | |
|      * current context, you can extract() the values returned from this call: | |
|      * | |
|      *     foreach ($items as $item) { | |
|      *         extract(\Psy\debug(get_defined_vars())); | |
|      *         var_dump($item); // will be whatever you set $item to in Psy Shell | |
|      *     } | |
|      * | |
|      * Optionally, supply an object as the `$boundObject` parameter. This | |
|      * determines the value `$this` will have in the shell, and sets up class | |
|      * scope so that private and protected members are accessible: | |
|      * | |
|      *     class Foo { | |
|      *         function bar() { | |
|      *             \Psy\debug(get_defined_vars(), $this); | |
|      *         } | |
|      *     } | |
|      * | |
|      * This only really works in PHP 5.4+ and HHVM 3.5+, so upgrade already. | |
|      * | |
|      * @param array  $vars        Scope variables from the calling context (default: array()) | |
|      * @param object $boundObject Bound object ($this) value for the shell | |
|      * | |
|      * @return array Scope variables from the debugger session | |
|      */ | |
|     function debug(array $vars = array(), $boundObject = null) | |
|     { | |
|         echo PHP_EOL; | |
| 
 | |
|         $sh = new Shell(); | |
|         $sh->setScopeVariables($vars); | |
| 
 | |
|         // Show a couple of lines of call context for the debug session. | |
|         // | |
|         // @todo come up with a better way of doing this which doesn't involve injecting input :-P | |
|         if ($sh->has('whereami')) { | |
|             $sh->addInput('whereami -n2', true); | |
|         } | |
| 
 | |
|         if ($boundObject !== null) { | |
|             $sh->setBoundObject($boundObject); | |
|         } | |
| 
 | |
|         $sh->run(); | |
| 
 | |
|         return $sh->getScopeVariables(false); | |
|     } | |
| } | |
| 
 | |
| if (!function_exists('Psy\info')) { | |
|     /** | |
|      * Get a bunch of debugging info about the current PsySH environment and | |
|      * configuration. | |
|      * | |
|      * If a Configuration param is passed, that configuration is stored and | |
|      * used for the current shell session, and no debugging info is returned. | |
|      * | |
|      * @param Configuration|null $config | |
|      * | |
|      * @return array|null | |
|      */ | |
|     function info(Configuration $config = null) | |
|     { | |
|         static $lastConfig; | |
|         if ($config !== null) { | |
|             $lastConfig = $config; | |
| 
 | |
|             return; | |
|         } | |
| 
 | |
|         $xdg = new Xdg(); | |
|         $home = rtrim(str_replace('\\', '/', $xdg->getHomeDir()), '/'); | |
|         $homePattern = '#^' . preg_quote($home, '#') . '/#'; | |
| 
 | |
|         $prettyPath = function ($path) use ($homePattern) { | |
|             if (is_string($path)) { | |
|                 return preg_replace($homePattern, '~/', $path); | |
|             } else { | |
|                 return $path; | |
|             } | |
|         }; | |
| 
 | |
|         $config = $lastConfig ?: new Configuration(); | |
| 
 | |
|         $core = array( | |
|             'PsySH version'       => Shell::VERSION, | |
|             'PHP version'         => PHP_VERSION, | |
|             'default includes'    => $config->getDefaultIncludes(), | |
|             'require semicolons'  => $config->requireSemicolons(), | |
|             'error logging level' => $config->errorLoggingLevel(), | |
|             'config file'         => array( | |
|                 'default config file' => $prettyPath($config->getConfigFile()), | |
|                 'local config file'   => $prettyPath($config->getLocalConfigFile()), | |
|                 'PSYSH_CONFIG env'    => $prettyPath(getenv('PSYSH_CONFIG')), | |
|             ), | |
|             // 'config dir'  => $config->getConfigDir(), | |
|             // 'data dir'    => $config->getDataDir(), | |
|             // 'runtime dir' => $config->getRuntimeDir(), | |
|         ); | |
| 
 | |
|         // Use an explicit, fresh update check here, rather than relying on whatever is in $config. | |
|         $checker = new GitHubChecker(); | |
|         $updateAvailable = null; | |
|         $latest = null; | |
|         try { | |
|             $updateAvailable = !$checker->isLatest(); | |
|             $latest = $checker->getLatest(); | |
|         } catch (\Exception $e) { | |
|         } | |
| 
 | |
|         $updates = array( | |
|             'update available'       => $updateAvailable, | |
|             'latest release version' => $latest, | |
|             'update check interval'  => $config->getUpdateCheck(), | |
|             'update cache file'      => $prettyPath($config->getUpdateCheckCacheFile()), | |
|         ); | |
| 
 | |
|         if ($config->hasReadline()) { | |
|             $info = readline_info(); | |
| 
 | |
|             $readline = array( | |
|                 'readline available' => true, | |
|                 'readline enabled'   => $config->useReadline(), | |
|                 'readline service'   => get_class($config->getReadline()), | |
|             ); | |
| 
 | |
|             if (isset($info['library_version'])) { | |
|                 $readline['readline library'] = $info['library_version']; | |
|             } | |
| 
 | |
|             if (isset($info['readline_name']) && $info['readline_name'] !== '') { | |
|                 $readline['readline name'] = $info['readline_name']; | |
|             } | |
|         } else { | |
|             $readline = array( | |
|                 'readline available' => false, | |
|             ); | |
|         } | |
| 
 | |
|         $pcntl = array( | |
|             'pcntl available' => function_exists('pcntl_signal'), | |
|             'posix available' => function_exists('posix_getpid'), | |
|         ); | |
| 
 | |
|         $disabledFuncs = array_map('trim', explode(',', ini_get('disable_functions'))); | |
|         if (in_array('pcntl_signal', $disabledFuncs) || in_array('pcntl_fork', $disabledFuncs)) { | |
|             $pcntl['pcntl disabled'] = true; | |
|         } | |
| 
 | |
|         $history = array( | |
|             'history file'     => $prettyPath($config->getHistoryFile()), | |
|             'history size'     => $config->getHistorySize(), | |
|             'erase duplicates' => $config->getEraseDuplicates(), | |
|         ); | |
| 
 | |
|         $docs = array( | |
|             'manual db file'   => $prettyPath($config->getManualDbFile()), | |
|             'sqlite available' => true, | |
|         ); | |
| 
 | |
|         try { | |
|             if ($db = $config->getManualDb()) { | |
|                 if ($q = $db->query('SELECT * FROM meta;')) { | |
|                     $q->setFetchMode(\PDO::FETCH_KEY_PAIR); | |
|                     $meta = $q->fetchAll(); | |
| 
 | |
|                     foreach ($meta as $key => $val) { | |
|                         switch ($key) { | |
|                             case 'built_at': | |
|                                 $d = new \DateTime('@' . $val); | |
|                                 $val = $d->format(\DateTime::RFC2822); | |
|                                 break; | |
|                         } | |
|                         $key = 'db ' . str_replace('_', ' ', $key); | |
|                         $docs[$key] = $val; | |
|                     } | |
|                 } else { | |
|                     $docs['db schema'] = '0.1.0'; | |
|                 } | |
|             } | |
|         } catch (Exception\RuntimeException $e) { | |
|             if ($e->getMessage() === 'SQLite PDO driver not found') { | |
|                 $docs['sqlite available'] = false; | |
|             } else { | |
|                 throw $e; | |
|             } | |
|         } | |
| 
 | |
|         $autocomplete = array( | |
|             'tab completion enabled' => $config->getTabCompletion(), | |
|             'custom matchers'        => array_map('get_class', $config->getTabCompletionMatchers()), | |
|             'bracketed paste'        => $config->useBracketedPaste(), | |
|         ); | |
| 
 | |
|         return array_merge($core, compact('updates', 'pcntl', 'readline', 'history', 'docs', 'autocomplete')); | |
|     } | |
| } | |
| 
 | |
| if (!function_exists('Psy\bin')) { | |
|     /** | |
|      * `psysh` command line executable. | |
|      * | |
|      * @return Closure | |
|      */ | |
|     function bin() | |
|     { | |
|         return function () { | |
|             $usageException = null; | |
| 
 | |
|             $input = new ArgvInput(); | |
|             try { | |
|                 $input->bind(new InputDefinition(array( | |
|                     new InputOption('help',     'h',  InputOption::VALUE_NONE), | |
|                     new InputOption('config',   'c',  InputOption::VALUE_REQUIRED), | |
|                     new InputOption('version',  'v',  InputOption::VALUE_NONE), | |
|                     new InputOption('cwd',      null, InputOption::VALUE_REQUIRED), | |
|                     new InputOption('color',    null, InputOption::VALUE_NONE), | |
|                     new InputOption('no-color', null, InputOption::VALUE_NONE), | |
| 
 | |
|                     new InputArgument('include', InputArgument::IS_ARRAY), | |
|                 ))); | |
|             } catch (\RuntimeException $e) { | |
|                 $usageException = $e; | |
|             } | |
| 
 | |
|             $config = array(); | |
| 
 | |
|             // Handle --config | |
|             if ($configFile = $input->getOption('config')) { | |
|                 $config['configFile'] = $configFile; | |
|             } | |
| 
 | |
|             // Handle --color and --no-color | |
|             if ($input->getOption('color') && $input->getOption('no-color')) { | |
|                 $usageException = new \RuntimeException('Using both "--color" and "--no-color" options is invalid.'); | |
|             } elseif ($input->getOption('color')) { | |
|                 $config['colorMode'] = Configuration::COLOR_MODE_FORCED; | |
|             } elseif ($input->getOption('no-color')) { | |
|                 $config['colorMode'] = Configuration::COLOR_MODE_DISABLED; | |
|             } | |
| 
 | |
|             $shell = new Shell(new Configuration($config)); | |
| 
 | |
|             // Handle --help | |
|             if ($usageException !== null || $input->getOption('help')) { | |
|                 if ($usageException !== null) { | |
|                     echo $usageException->getMessage() . PHP_EOL . PHP_EOL; | |
|                 } | |
| 
 | |
|                 $version = $shell->getVersion(); | |
|                 $name    = basename(reset($_SERVER['argv'])); | |
|                 echo <<<EOL | |
| $version | |
|  | |
| Usage: | |
|   $name [--version] [--help] [files...] | |
|  | |
| Options: | |
|   --help     -h Display this help message. | |
|   --config   -c Use an alternate PsySH config file location. | |
|   --cwd         Use an alternate working directory. | |
|   --version  -v Display the PsySH version. | |
|   --color       Force colors in output. | |
|   --no-color    Disable colors in output. | |
|  | |
| EOL; | |
|                 exit($usageException === null ? 0 : 1); | |
|             } | |
| 
 | |
|             // Handle --version | |
|             if ($input->getOption('version')) { | |
|                 echo $shell->getVersion() . PHP_EOL; | |
|                 exit(0); | |
|             } | |
| 
 | |
|             // Pass additional arguments to Shell as 'includes' | |
|             $shell->setIncludes($input->getArgument('include')); | |
| 
 | |
|             try { | |
|                 // And go! | |
|                 $shell->run(); | |
|             } catch (Exception $e) { | |
|                 echo $e->getMessage() . PHP_EOL; | |
| 
 | |
|                 // @todo this triggers the "exited unexpectedly" logic in the | |
|                 // ForkingLoop, so we can't exit(1) after starting the shell... | |
|                 // fix this :) | |
|  | |
|                 // exit(1); | |
|             } | |
|         }; | |
|     } | |
| }
 | |
| 
 |