/** * The entry method. * * @return void */ public function main() { $run = 'hoa://Data/Variable/Run'; while (false !== ($c = $this->getOption($v))) { switch ($c) { case 'r': $run = $v; break; case 'h': case '?': return $this->usage(); case '__ambiguous': $this->resolveOptionAmbiguity($v); break; } } $this->parser->listInputs($workerId); if (null === $workerId) { return $this->usage(); } $run = resolve($run); Core::getInstance()->initialize(['protocol.Data/Variable/Run' => "\r" . $run . DS]); $password = $this->readPassword('Password: '); $sw = new Worker\Backend\Shared($workerId, $password); $sw->stop(); return; }
public function __construct() { $this->setMethodPrefix('case'); parent::__construct(); $protocol = Core::getInstance()->getProtocol(); $protocol['Test'] = new Core\Protocol\Generic('Test', null); $protocol['Test']['Vfs'] = new Test\Protocol\Vfs(); return; }
/** * Main method. * * @return int */ function main() { $operation = 0; $location = null; $updateServer = Updater::DEFAULT_UPDATE_SERVER; while (false !== ($c = $this->getOption($v))) { switch ($c) { case '__ambiguous': $this->resolveOptionAmbiguity($v); break; case 'f': $operation = static::OPERATION_FETCH | Updater::FORMAT_PHAR; break; case 'z': $operation = static::OPERATION_FETCH | Updater::FORMAT_ZIP; break; case 'a': $operation = static::OPERATION_APPLY; $location = $v; break; case 's': $updateServer = $v; break; case 'h': case '?': default: return $this->usage(); break; } } $updateServer = rtrim($updateServer, '/') . '/'; if (0 !== (static::OPERATION_FETCH & $operation)) { $updatesDotJson = Updater::getUpdateUrl($updateServer); $versions = @file_get_contents($updatesDotJson); if (empty($versions)) { throw new Exception\Console('Oh no! We are not able to check if a new version exists… ' . 'Contact us at http://sabre.io/ ' . '(tried URL %s).', 0, $updatesDotJson); } $versions = json_decode($versions, true); /** * Expected format: * { * "1.0.1": { * "phar": "https://…", * "zip" : "https://…" * }, * "1.0.0": { * "phar": "https://…", * "zip" : "https://…" * }, * … * } */ $versionsToFetch = Updater::filterVersions($versions, Version::VERSION, $operation); $windowWidth = Window::getSize()['x']; $progress = function ($percent) use($windowWidth) { Cursor::clear('↔'); $message = 'Downloading… '; $barWidth = $windowWidth - mb_strlen($message); if ($percent <= 0) { $color = '#c74844'; } elseif ($percent <= 25) { $color = '#cb9a3d'; } elseif ($percent <= 50) { $color = '#dcb11e'; } elseif ($percent <= 75) { $color = '#aed633'; } else { $color = '#54b455'; } echo $message; Cursor::colorize('foreground(' . $color . ') background(' . $color . ')'); echo str_repeat('|', $percent * $barWidth / 100); Cursor::colorize('normal'); }; foreach ($versionsToFetch as $versionNumber => $versionUrl) { list(, $versionUrlBasename) = Uri\split($versionUrl); $fileIn = new File\Read($versionUrl, File::MODE_READ, null, true); $fileOut = new File\Write(SABRE_KATANA_PREFIX . '/data/share/update/' . $versionUrlBasename); echo "\n", 'Fetch version ', $versionNumber, ' from ', $versionUrl, "\n", 'Waiting…', "\n"; $fileIn->on('connect', function () { Cursor::clear('↔'); echo 'Downloading… '; }); $fileIn->on('progress', function (Core\Event\Bucket $bucket) use($progress) { static $previousPercent = 0; $data = $bucket->getData(); $current = $data['transferred']; $max = $data['max']; $percent = $current * 100 / $max; $delta = $percent - $previousPercent; if (1 <= $delta) { $previousPercent = $percent; $progress($percent); } }); $fileIn->open(); $fileOut->writeAll($fileIn->readAll()); echo "\n", 'Fetched at ', $fileOut->getStreamName(), '.', "\n"; } return 0; } elseif (static::OPERATION_APPLY === $operation) { if (false === file_exists($location)) { throw new Exception\Console('Update %s is not found.', 1, $location); } $processus = new Console\Processus(Core::getPHPBinary(), [$location, '--extract' => SABRE_KATANA_PREFIX, '--overwrite']); $processus->on('input', function () { return false; }); $processus->on('output', function (Core\Event\Bucket $bucket) { echo $bucket->getData()['line'], "\n"; }); $processus->run(); if (true === $processus->isSuccessful()) { echo 'sabre/katana updated!', "\n"; } else { echo 'Something wrong happened!', "\n"; } return $processus->getExitCode(); } else { return $this->usage(); } }
/** * Try the handshake by trying different protocol implementation. * * @return void * @throws \Hoa\Websocket\Exception * @throws \Hoa\Websocket\Exception\BadProtocol */ protected function doHandshake() { static $_tail = ['A', 'Q', 'g', 'w']; $connection = $this->getConnection(); $connection->connect(); $connection->setStreamBlocking(true); $key = substr(base64_encode(Core::uuid()), 0, 21) . $_tail[mt_rand(0, 3)] . '=='; $expected = base64_encode(sha1($key . Protocol\Rfc6455::GUID, true)); if (null === ($host = $this->getHost())) { throw new Exception('Host name is null. Please, use the %s::setHost() method.', 0, __CLASS__); } $connection->writeAll($request = 'GET ' . $this->getEndPoint() . ' HTTP/1.1' . CRLF . 'Host: ' . $host . CRLF . 'User-Agent: Hoa' . CRLF . 'Upgrade: WebSocket' . CRLF . 'Connection: Upgrade' . CRLF . 'Pragma: no-cache' . CRLF . 'Cache-Control: no-cache' . CRLF . 'Sec-WebSocket-Key: ' . $key . CRLF . 'Sec-WebSocket-Version: 13' . CRLF . CRLF); $buffer = $connection->read(2048); $response = $this->getResponse(); $response->parse($buffer); if ($response::STATUS_SWITCHING_PROTOCOLS !== $response['status'] || 'websocket' !== strtolower($response['upgrade']) || 'upgrade' !== strtolower($response['connection']) || $expected !== $response['sec-websocket-accept']) { throw new Exception\BadProtocol('Handshake has failed, the server did not return a valid ' . 'response.' . "\n\n" . 'Client:' . "\n" . ' %s' . "\n" . 'Server:' . "\n" . ' %s', 0, [str_replace("\n", "\n" . ' ', $request), str_replace("\n", "\n" . ' ', $buffer)]); } $currentNode = $connection->getCurrentNode(); $currentNode->setHandshake(SUCCEED); $currentNode->setProtocolImplementation(new Protocol\Rfc6455($connection)); $this->_on->fire('open', new Core\Event\Bucket()); return; }
* @license New BSD License */ class _Protocol extends Core\Protocol { /** * Component's name. * * @var string */ protected $_name = 'Registry'; /** * ID of the component. * * @param string $id ID of the component. * @return mixed */ public function reachId($id) { return Registry::get($id); } } /** * Flex entity. */ Core\Consistency::flexEntity('Hoa\\Registry\\Registry'); /** * Add the hoa://Library/Registry component. Should be use to reach/get an entry * in the \Hoa\Registry, e.g.: resolve('hoa://Library/Registry#AnID'). */ $protocol = Core::getInstance()->getProtocol(); $protocol['Library'][] = new _Protocol();
/** * Singleton to manage a library family. * * @param string $from Library family's name. * @return void */ private function __construct($from) { $this->_from = preg_split('#\\s*(,|or)\\s*#', trim($from, '()')); $parameters = Core::getInstance()->getParameters(); $wildcard = $parameters->getFormattedParameter('namespace.prefix.*'); foreach ($this->_from as $f) { $this->setRoot($parameters->getFormattedParameter('namespace.prefix.' . $f) ?: $wildcard, $f); } return; }
/** * The entry method. * * @return int */ public function main() { $exists = true; $unfold = false; $tree = false; $verbose = Console::isDirect(STDOUT); while (false !== ($c = $this->getOption($v))) { switch ($c) { case 'E': $exists = false; break; case 'u': $unfold = true; break; case 't': $tree = true; break; case 'V': $verbose = false; break; case 'h': case '?': return $this->usage(); case '__ambiguous': $this->resolveOptionAmbiguity($v); break; } } $this->parser->listInputs($path); if (null === $path) { return $this->usage(); } if (true === $tree) { $protocol = Core::getProtocol(); $foo = substr($path, 0, 6); if ('hoa://' !== $foo) { return; } $path = substr($path, 6); $current = $protocol; foreach (explode('/', $path) as $component) { if (!isset($current[$component])) { break; } $current = $current[$component]; } echo $current; return; } if (true === $verbose) { echo Console\Chrome\Text::colorize($path, 'foreground(yellow)'), ' is equivalent to:', "\n"; } $resolved = resolve($path, $exists, $unfold); foreach ((array) $resolved as $r) { echo $r, "\n"; } return; }
* Set the default timezone. */ date_default_timezone_set('UTC'); /** * Load the autoloader. */ $autoloadFile = __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; if (false === file_exists($autoloadFile)) { echo 'Autoloader is not found. Did you run `composer install`?', "\n"; exit(1); } $autoloader = (require_once $autoloadFile); /** * Configure hoa:// (basis of katana://). */ Core::getInstance()->initialize(['root.application' => __DIR__ . DS, 'root.data' => __DIR__ . DS . 'data' . DS, 'protocol.bin' => '(:%root.application:)' . 'bin' . DS, 'protocol.data' => '(:%root.data:)', 'protocol.data/lib' => "\r" . '(:%root.application:)' . 'vendor' . DS, 'protocol.lib' => '(:%root.application:)' . 'lib' . DS, 'protocol.public' => '(:%root.application:)' . 'public' . DS, 'protocol.resource' => __DIR__ . DS . 'resource' . DS, 'protocol.tests' => '(:%root.application:)' . 'tests' . DS]); /** * Register the katana:// protocol. */ stream_wrapper_register(Katana\Protocol::SCHEME, 'Sabre\\Katana\\Protocol'); /** * sabre/katana is now defined and set up, let the world knows that. */ define('SABRE_KATANA', true); /** * Current version. */ define('SABRE_KATANA_VERSION', '0.1.1'); /** * Define the prefix. */
/** * The entry method. * * @return int */ public function main() { $sections = []; $mail = null; $diagnostic = []; while (false !== ($c = $this->getOption($v))) { switch ($c) { case 's': $sections = $this->parser->parseSpecialValue($v); break; case 'm': $mail = $v; break; case 'h': case '?': return $this->usage(); case '__ambiguous': $this->resolveOptionAmbiguity($v); break; } } $store = function ($sections, $key, $value = null) use(&$diagnostic) { if (is_array($key) && null === $value) { foreach ($key as $i => $name) { $diagnostic[$sections][$i] = $name; } } else { $diagnostic[$sections][$key] = $value; } return; }; $store('version', 'php', phpversion()); $store('version', 'zend_engine', zend_version()); $store('system', 'platform', php_uname()); $store('system', 'architecture', true === S_32_BITS ? '32bits' : '64bits'); $store('system', 'lang', isset($_SERVER['LANG']) ? $_SERVER['LANG'] : 'unknown'); $store('bin', 'self', $_SERVER['PHP_SELF']); $store('bin', 'hoa', Core::getInstance()->getParameters()->getFormattedParameter('root.hoa')); $store('bin', 'php_dir', PHP_BINDIR); $store('bin', 'php', defined('PHP_BINARY') ? PHP_BINARY : 'unknown'); foreach (get_loaded_extensions() as $extension) { $reflection = new \ReflectionExtension($extension); $entry = 'extension-' . strtolower($extension); if ('extension-standard' !== $entry && 'extension-core' !== $entry) { $entries = []; foreach ($reflection->getINIEntries() as $key => $value) { $entries[substr($key, strpos($key, '.') + 1)] = $value; } } else { $entries = $reflection->getINIEntries(); } $store($entry, 'version', $reflection->getVersion() ?: 'unknown'); $store($entry, $entries); } if (empty($sections) || in_array('all', $sections)) { $ini = $this->arrayToIni($diagnostic); } else { $handle = []; foreach ($sections as $section) { if (false === array_key_exists($section, $diagnostic)) { return 1; } $handle[$section] = $diagnostic[$section]; } $ini = $this->arrayToIni($handle); } echo $ini, "\n"; if (null !== $mail) { $subject = 'Diagnostic from ' . get_current_user(); return mail($mail, $subject, $ini) ? 0 : 1; } return; }
require_once $path; break; } } if (!defined('HOA')) { $core = [dirname(__DIR__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Core' . DIRECTORY_SEPARATOR . 'Core.php', dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'hoa' . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'Core.php', dirname(__DIR__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'Core.php']; foreach ($core as $path) { if (file_exists($path)) { require_once $path; break; } } } } Core::enableErrorHandler(); Core::enableExceptionHandler(); /** * Here we go! */ try { $router = new Router\Cli(); $router->get('g', '(?:(?<vendor>\\w+)\\s+)?(?<library>\\w+)?(?::(?<command>\\w+))?(?<_tail>.*?)', 'main', 'main', ['vendor' => 'hoa', 'library' => 'core', 'command' => 'welcome']); $dispatcher = new Dispatcher\ClassMethod(['synchronous.call' => '(:%variables.vendor:lU:)\\(:%variables.library:lU:)\\Bin\\(:%variables.command:lU:)', 'synchronous.able' => 'main']); $dispatcher->setKitName('Hoa\\Console\\Dispatcher\\Kit'); exit((int) $dispatcher->dispatch($router)); } catch (Core\Exception $e) { $message = $e->raise(true); $code = 1; } catch (\Exception $e) { $message = $e->getMessage(); $code = 2;
$name = $_SERVER['argv'][1]; } else { $name = 'Hoa.phar'; } if (file_exists($name) && false === unlink($name)) { throw new Hoa\Core\Exception('Phar %s already exists and we cannot delete it.', 1, $name); } class Filter extends FilterIterator { public function accept() { return false === strpos($this->current()->getPathname(), '.git'); } } $phar = new Phar(__DIR__ . DS . $name); $phar->setMetadata(['author' => 'Ivan Enderlin, Hoa community', 'license' => 'New BSD License', 'copyright' => \Hoa\Core::©(), 'version.name' => $name, 'datetime' => date('c')]); $phar->setSignatureAlgorithm(Phar::SHA1); $phar->buildFromIterator(new Filter(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root))), $root); $phar->setStub(<<<'STUB' <?php Phar::mapPhar('Hoa.phar'); require 'phar://Hoa.phar/Core/Core.php'; $phar = new Phar(__FILE__); foreach (array_slice($_SERVER['argv'], 1) ?: ['-h'] as $option) { switch (strtolower($option)) { case '-m': case '--metadata': echo 'Metadata:' . "\n\n";
/** * The entry method. * * @return int */ public function main() { $dryRun = false; $classes = []; while (false !== ($c = $this->getOption($v))) { switch ($c) { case 'n': foreach ($this->parser->parseSpecialValue($v) as $namespace) { $namespace = trim(str_replace('.', '\\', $namespace), '\\'); if (false === ($pos = strpos($namespace, '\\'))) { throw new Console\Exception('Namespace %s is too short.', 0, $namespace); } $tail = substr($namespace, strpos($namespace, '\\') + 1); $root = resolve('hoa://Library/' . str_replace('\\', '/', $tail)); $classes = array_merge($classes, static::findClasses($root, $namespace)); } break; case 'c': foreach ($this->parser->parseSpecialValue($v) as $class) { $classes[] = $class; } break; case 'd': $dryRun = $v; break; case '__ambiguous': $this->resolveOptionAmbiguity($v); break; case 'h': case '?': default: return $this->usage(); } } if (empty($classes)) { return $this->usage(); } foreach ($classes as $i => $class) { $classes[$i] = str_replace('.', '\\', $class); } $generator = new \Atoum\PraspelExtension\Praspel\Generator(); $generator->setTestNamespacer(function ($namespace) { $parts = explode('\\', $namespace); return implode('\\', array_slice($parts, 0, 2)) . '\\Test\\Praspel\\Unit' . (isset($parts[2]) ? '\\' . implode('\\', array_slice($parts, 2)) : ''); }); $phpBinary = Core::getPHPBinary() ?: Console\Processus::localte('php'); $envVariable = '__HOA_ATOUM_PRASPEL_EXTENSION_' . md5(Core::uuid()); $reflection = null; $buffer = null; $reflectionner = new Console\Processus($phpBinary); $reflectionner->on('input', function (Core\Event\Bucket $bucket) use($envVariable) { $bucket->getSource()->writeAll('<?php' . "\n" . 'require_once \'' . dirname(__DIR__) . DS . '.bootstrap.atoum.php\';' . "\n" . '$class = getenv(\'' . $envVariable . '\');' . "\n" . 'if (class_exists(\'\\mageekguy\\atoum\\scripts\\runner\', false)) {' . "\n" . ' \\atoum\\scripts\\runner::disableAutorun();' . "\n" . '}' . "\n" . '$reflection = new \\Atoum\\PraspelExtension\\Praspel\\Reflection\\RClass($class);' . "\n" . 'echo serialize($reflection), "\\n";'); return false; }); $reflectionner->on('output', function (Core\Event\Bucket $bucket) use(&$buffer) { $data = $bucket->getData(); $buffer .= $data['line'] . "\n"; return; }); $reflectionner->on('stop', function () use(&$buffer, &$reflection) { $handle = @unserialize($buffer); if (false === $handle) { echo $buffer, "\n"; return; } $reflection = $handle; return; }); foreach ($classes as $class) { $status = $class . ' (in '; echo ' ⌛ ', $status; putenv($envVariable . '=' . $class); $buffer = null; $reflection = null; $reflectionner->run(); $output = $generator->generate($reflection); $parts = explode('\\', $class); $paths = resolve('hoa://Library/' . $parts[1] . '/' . 'Test/Praspel/Unit/' . implode('/', array_slice($parts, 2)) . '.php', false, true); $max = 0; $thePath = 0; foreach ($paths as $path) { $length = Ustring\Search::lcp($reflection->getFilename(), $path); if ($length > $max) { $thePath = $path; } } $statusTail = (40 < strlen($thePath) ? '…' . substr($thePath, -39) : $thePath) . ')'; echo $statusTail; $status .= $statusTail; if (false === $reflection->isInstantiable()) { Console\Cursor::clear('↔'); echo ' ⚡️ ', $status, '; not instantiable.', "\n"; continue; } $dirname = dirname($thePath); if (false === is_dir($dirname)) { if (false === $dryRun) { mkdir($dirname, 0755, true); } else { echo "\n", static::info('Creating directory: ' . $dirname . '.'); } } if (false === $dryRun) { file_put_contents($thePath, $output); } else { echo "\n", static::info('Content of the ' . $thePath . ':'), "\n"; Console\Cursor::colorize('foreground(yellow)'); echo ' ┏', "\n", ' ┃ ', str_replace("\n", "\n" . ' ┃ ', trim($output)), "\n", ' ┗', "\n"; Console\Cursor::colorize('foreground(normal)'); } Console\Cursor::clear('↔'); echo ' ', Console\Chrome\Text::colorize('✔︎', 'foreground(green)'), ' ', $status, "\n"; } return; }
/** * The entry method. * * @return void */ public function main() { $run = 'hoa://Data/Variable/Run'; while (false !== ($c = $this->getOption($v))) { switch ($c) { case 'r': $run = $v; break; case 'h': case '?': return $this->usage(); break; case '__ambiguous': $this->resolveOptionAmbiguity($v); break; } } $run = resolve($run); Core::getInstance()->initialize(['protocol.Data/Variable/Run' => "\r" . $run . DS]); $outi = [['ID', 'PID', 'Socket', 'Uptime', 'Messages', 'Last']]; $outm = []; $now = new \DateTime(); $t = 0; echo Console\Chrome\Text::colorize('Shared worker informations', 'foreground(yellow)'), "\n\n"; foreach (glob($run . DS . '*.wid') as $wid) { $worker = new Worker\Shared(substr(basename($wid), 0, -4)); $infos = $worker->getInformations(); $uptime = new \DateTime(); $uptime->setTimestamp((int) $infos['start']); $last = new \DateTime(); $last->setTimestamp((int) $infos['last_message']); $outi[] = [$infos['id'], $infos['pid'], $infos['socket'], $uptime->diff($now)->format('%ad%H:%I:%S'), $infos['messages'], 0 === $infos['last_message'] ? '-' : $last->diff($now)->format('%ad%H:%I:%S')]; $outm[] = $infos; ++$t; } echo Console\Chrome\Text::columnize($outi, 0, 1, '|'), "\n"; $max_id = 0; $max_peak = 0; foreach ($outm as $m) { $max_id < strlen($m['id']) and $max_id = strlen($m['id']); $max_peak < $m['memory_peak'] and $max_peak = $m['memory_peak']; } foreach ($outm as $m) { $outmm = str_pad($m['id'], $max_id) . ' '; $max = (int) ($m['memory_peak'] * 39 / $max_peak); $peak = (int) ($m['memory_allocated_peak'] * 40 / $max_peak); $memory = (int) ($m['memory_allocated'] * 40 / $max_peak); for ($i = 0; $i < $memory - 1; ++$i) { $outmm .= Console\Chrome\Text::colorize('|', 'foreground(green)'); } for (; $i < $peak; ++$i) { $outmm .= Console\Chrome\Text::colorize('|', 'foreground(yellow)'); } for (; $i < $max; ++$i) { $outmm .= ' '; } $outmm .= Console\Chrome\Text::colorize('|', 'foreground(red)'); for (++$i; $i < 40; ++$i) { $outmm .= ' '; } $outmm .= ' ' . Console\Chrome\Text::colorize(number_format($m['memory_allocated'] / 1024) . 'Kb', 'foreground(green)') . ' ' . Console\Chrome\Text::colorize(number_format($m['memory_allocated_peak'] / 1024) . 'Kb', 'foreground(yellow)') . ' ' . Console\Chrome\Text::colorize(number_format($m['memory_peak'] / 1024) . 'Kb', 'foreground(red)'); echo $outmm . "\n"; } echo "\n", $t, ' shared worker', $t > 1 ? 's are' : ' is', ' running.', "\n"; return; }
/** * Get the real path of the given URL. * Could return false if the path cannot be reached. * * @param string $path Path (or URL). * @param bool $exists If true, try to find the first that exists, * @return mixed */ public static function realPath($path, $exists = true) { return Core::getProtocol()->resolve($path, $exists); }
if (false === static::$_enabled) { return; } echo "[?1003l"; echo "[?1000l"; static::$_enabled = false; return; } /** * Attach a callable to a listenable component. * * @param string $listenerId Listener ID. * @param mixed $callable Callable. * @return \Hoa\Core\Event\Listenable * @throws \Hoa\Core\Exception */ public function on($listenerId, $callable) { $this->_on->attach($listenerId, $callable); return $this; } } /** * Advanced interaction. */ Console::advancedInteraction(); /** * Untrack mouse. */ Core::registerShutdownFunction('\\Hoa\\Console\\Mouse', 'untrack');
} /** * Get the current tput instance of the current process. * * @return \Hoa\Console\Tput */ public static function getTput() { if (null === static::$_tput) { static::$_tput = new Tput(); } return static::$_tput; } /** * Check whether we are running behind TMUX(1). * * @return bool */ public static function isTmuxRunning() { return isset($_SERVER['TMUX']); } } /** * Restore interaction. */ Core::registerShutdownFunction('Hoa\\Console\\Console', 'restoreInteraction'); /** * Flex entity. */ Core\Consistency::flexEntity('Hoa\\Console\\Console');
/** * Destruct XYL object. * * @return void */ public function __destruct() { $protocol = Core::getInstance()->getProtocol(); unset($protocol['Library']['Xyl[' . $this->_i . ']']); return; }