Run the interactive Shell

The shell command runs Flow's interactive shell. This shell allows for
entering commands like through the regular command line interface but
additionally supports autocompletion and a user-based command history.

@return void
198596
public function shellCommand()
    {
        if (!function_exists('readline_read_history')) {
            $this->outputLine('Interactive Shell is not available on this system!');
            $this->quit(1);
        }
        $subProcess = false;
        $pipes = [];

        $historyPathAndFilename = getenv('HOME') . '/.flow_' . md5(FLOW_PATH_ROOT);
        readline_read_history($historyPathAndFilename);
        readline_completion_function([$this, 'autocomplete']);

        echo "Flow Interactive Shell\n\n";

        while (true) {
            $commandLine = readline('Flow > ');
            if ($commandLine === '') {
                echo "\n";
                break;
            }

            readline_add_history($commandLine);
            readline_write_history($historyPathAndFilename);

            $request = $this->requestBuilder->build($commandLine);
            $response = new Response();
            $command = $request->getCommand();

            if ($request === false || $command->getCommandIdentifier() === false) {
                echo "Bad command\n";
                continue;
            }
            if ($this->bootstrap->isCompiletimeCommand($command->getCommandIdentifier())) {
                $this->dispatcher->dispatch($request, $response);
                $response->send();
                if (is_resource($subProcess)) {
                    $this->quitSubProcess($subProcess, $pipes);
                }
            } else {
                if (is_resource($subProcess)) {
                    $subProcessStatus = proc_get_status($subProcess);
                    if ($subProcessStatus['running'] === false) {
                        proc_close($subProcess);
                    }
                };
                if (!is_resource($subProcess)) {
                    list($subProcess, $pipes) = $this->launchSubProcess();
                    if ($subProcess === false || !is_array($pipes)) {
                        echo "Failed launching the shell sub process for executing the runtime command.\n";
                        continue;
                    }
                    $this->echoSubProcessResponse($pipes);
                }

                fwrite($pipes[0], $commandLine . "\n");
                fflush($pipes[0]);
                $this->echoSubProcessResponse($pipes);

                if ($command->isFlushingCaches()) {
                    $this->quitSubProcess($subProcess, $pipes);
                }
            }
        }

        if (is_resource($subProcess)) {
            $this->quitSubProcess($subProcess, $pipes);
        }

        echo "Bye!\n";
    }
1297533
public function run()
    {
        foreach ($this->getCommands() as $command)
        {
            $this->transformer->transform($command);

            $this->application->add($command);
        }

        return $this->application->run();
    }
1241330
public function follow()
	{
		// This really only makes sense in interactive mode...duh
		if (!$this->output->isInteractive())
		{
			$this->output->error('This feature is only available in interactive mode!');
		}

		// Set tty icanon so keystrokes are captured without enter
		// Save settings first so we can reapply them when all is said and done
		exec('stty -g', $settings);
		exec('stty -icanon');

		// Get file to follow and a few other arguments
		$log        = $this->arguments->getOpt(3);
		$filters    = (array)$this->arguments->getOpt('filter');
		$threshold  = $this->arguments->getOpt('threshold');
		$noBeep     = $this->arguments->getOpt('no-beep');
		$prompt     = trim($this->arguments->getOpt('prompt', '>'));
		$dateFormat = $this->arguments->getOpt('date-format', 'normal');

		// Get class for this log type
		$class = __NAMESPACE__ . '\\Log\\' . ucfirst($log);

		// Make sure class exists
		if (!class_exists($class))
		{
			$this->output->error('Log does not current support the provided log type!');
		}
		else
		{
			$path = $class::path();
		}

		// Validate given log path
		if (!is_file($path) || !is_readable($path))
		{
			$this->output->error("{$path} does not appear to be a valid log file");
		}

		// Set log and prompt character
		$this->log = $class;
		$this->promptChar = $prompt;

		// Parse thresholds
		if ($threshold)
		{
			$threshold = $this->parseThresholds($threshold);
		}

		// Parse date format
		$dateFormat = $this->mapDateFormat($dateFormat);

		// Set up pipes
		$descs = array(
			0 => array('pipe', 'r'),
			1 => array('pipe', 'w'),
			2 => array('pipe', 'w')
		);

		// Tail the given log
		$proc = proc_open("tail -f {$path}", $descs, $fp);

		// Set streams to be non-blocking so we aren't sitting and waiting
		stream_set_blocking(STDIN, 0);
		stream_set_blocking($fp[1], 0);

		// Print log info/formatting
		$class::format($this->output);

		// Print initial prompt character
		$this->printPrompt();

		// Vars to track state/mode
		$pause = false;
		$input = false;

		// Loop indefinitely
		while (true)
		{
			// Check for new log entries
			$buffer = fgets($fp[1]);

			// If we found one and not paused and not in input mode
			if ($buffer !== false && !$pause && !$input)
			{
				// Parse the log line (log class will handle output)
				$class::parse($buffer, $this->output, array('threshold'=>$threshold, 'noBeep'=>$noBeep, 'dateFormat'=>$dateFormat));

				// Add new prompt character
				$this->printPrompt();
			}

			// Listen for keystrokes from stdin
			if (!$input)
			{
				$char = fgetc(STDIN);
				if ($char !== false)
				{
					$newPrompt = true;

					switch (ord($char))
					{
						// Line feed and carriage return
						case 10:
						case 13:
							// Do nothing
							break;

						// Numbers 0-9 -> toggle individual fields
						case 48:
						case 49:
						case 50:
						case 51:
						case 52:
						case 53:
						case 54:
						case 55:
						case 56:
						case 57:
							$this->output->backspace();
							// Toggle will return true if we have a valid field number
							if ($result = $class::toggle($char))
							{
								$this->output->addLine($result);
							}
							else
							{
								// Unknown field
								$this->output->addLine('Unknown identifier', 'warning');
							}
							break;

						// b - toggle beep
						case 98:
							$this->output->backspace();
							$noBeep = ($noBeep) ? false : true;
							$this->output->addLine('(b)eep ' . (($noBeep) ? 'off' : 'on'));
							break;

						// f - show fields
						case 102:
							$this->output->backspace();
							$class::format($this->output);
							break;

						// h - help info
						case 104:
							$this->output->backspace();
							$help = "q: quit, h: help, i: input mode, p: pause/play, b: beep on/off, f: fields, r: rerender last 100 lines";
							$this->output->addLine($help);
							break;

						// i - input mode
						case 105:
							$this->output->backspace((2+strlen($prompt)));
							$this->output->addLine('You\'re entering input mode. Pausing log streaming. Type "done" or "i" to return.');
							$this->output->addString('input mode >>> ');

							// Set input mode to true and undo icanon setting
							$input = true;
							exec('stty icanon');
							$newPrompt = false;
							break;

						// p - toggle play/pause
						case 112:
							$this->output->backspace();
							$pause = ($pause) ? false : true;
							$this->output->addLine((($pause) ? '(p)ause' : '(p)lay'));
							break;

						// q - quit
						case 113:
							$this->output->backspace();
							$this->output->addLine('(q)uit');

							// Don't just close the process, terminate it!
							proc_terminate($proc);
							break 2;

						// r - rerender last 100 lines
						case 114:
							$this->output->backspace();
							$this->output->addLine('(r)erender last 100 lines');

							// Grab the lines again
							$content = shell_exec("tail -100 {$path}");

							// Split them up and loop through them
							$lines   = explode("\n", trim($content));
							foreach ($lines as $line)
							{
								$this->printPrompt();
								$class::parse($line, $this->output, array('threshold'=>$threshold, 'noBeep'=>$noBeep, 'dateFormat'=>$dateFormat));
							}
							break;

						// Default
						default:
							// Just delete the typed character
							$this->output->backspace(1, true);
							$newPrompt = false;
							break;
					}

					// Should we print a new prompt character?
					if ($newPrompt)
					{
						$this->printPrompt();
					}
				}
			}
			// Input mode
			else
			{
				$string = fgets(STDIN);

				if ($string !== false)
				{
					// Initialize vars
					$string = trim($string);
					$arg    = null;
					$parts  = array();

					// If a space is present, we'll assume some sort of command/arguments scenario
					if (strpos($string, ' '))
					{
						$parts  = explode(' ', $string, 2);
						$string = $parts[0];
						$arg    = isset($parts[1]) ? $parts[1] : null;
					}

					switch ($string)
					{
						// Quit completely
						case 'quit':
							proc_terminate($proc);
							break 2;

						// Set date format
						case 'date':
							// Make sure arg is set
							if (isset($arg))
							{
								$dateFormat = $this->mapDateFormat($arg);
								$this->output->addLine('Date format changed', 'success');
							}

							$this->output->addLine('You can set the date format using: "date [format]". Options include: full, long, normal/default, and short.');
							$this->output->addString('input mode >>> ');
							break;

						// Close input mode
						case 'done':
						case 'i':
							$input = false;
							exec('stty -icanon');
							$this->printPrompt();
							break;

						// Show fields
						case 'fields':
							$this->output->addSpacer();
							$class::format($this->output);
							$this->output->addString('input mode >>> ');
							break;

						// Show or set threshold value(s)
						case 'threshold':
							// If arg is set, we're setting threshold
							if (isset($arg))
							{
								$threshold = $this->parseThresholds($arg);
								$this->output->addLine('Threshold(s) set');
							}
							else
							{
								if ($threshold)
								{
									// Parse threshold array
									$printable = array();
									foreach ($threshold as $t)
									{
										$printable[] = $t['key'] . $t['operator'] . $t['value'];
									}
									$this->output->addString('Threshold is currently set to ' . implode(', ', $printable) . '. ');
								}
								else
								{
									$this->output->addString('No thresholds are currently set. ');
								}

								$this->output->addLine('You can set thresholds using the format: "threshold field>value[,field=value]"');
							}

							$this->output->addString('input mode >>> ');
							break;

						// Hide/show fields
						case 'show':
						case 'hide':
							// Toggle will return false or string indicating fields changed
							if ($result = $class::toggle($arg, (($string == 'show') ? true : false)))
							{
								$this->output->addLine($result, 'success');
							}
							else
							{
								$this->output->addLine("{$arg} is not an available field", 'warning');
							}

						// Default - just show new prompt
						default:
							$this->output->addString('input mode >>> ');
							break;
					}
				}
			}

			// Sleep for a bit so we don't run away with the CPU
			usleep(50000);
		}

		// Restore tty settings
		exec("stty {$settings[0]}");
	}
467165
public function run()
    {
        parent::run();

        while (\count($this->running) || \count($this->pending)) {
            foreach ($this->running as $key => $test) {
                try {
                    if (!$this->testIsStillRunning($test)) {
                        unset($this->running[$key]);
                        $this->releaseToken($key);
                    }
                } catch (\Exception $e) {
                    if ($this->options->verbose) {
                        echo "An error for $key: {$e->getMessage()}" . PHP_EOL;
                        echo "Command: {$test->getLastCommand()}" . PHP_EOL;
                        echo 'StdErr: ' . $test->getStderr() . PHP_EOL;
                        echo 'StdOut: ' . $test->getStdout() . PHP_EOL;
                    }
                    throw $e;
                }
            }
            $this->fillRunQueue();
            usleep(10000);
        }
        $this->complete();
    }
225916
public function init()
    {
        if (Console::isCli()) {
            // fix for fcgi
            defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));

            if (!isset($_SERVER['argv'])) {
                die('This script must be run from the command line.');
            }
            $this->_runner = $this->createCommandRunner();
            $this->_runner->commands = $this->commandMap;
            $this->_runner->addCommands($this->getCommandPath());

            $env = @getenv('CONSOLE_COMMANDS');
            if (!empty($env)) {
                $this->_runner->addCommands($env);
            }

            foreach ($this->modules as $name => $settings) {
                $modulePath = Alias::get("Modules." . $name . ".Commands");
                if ($modulePath) {
                    $this->_runner->addCommands($modulePath);
                }
            }
        } else {
            // preload 'request' so that it has chance to respond to onBeginRequest event.
            $this->getComponent('request');
        }
    }
222357
public function run()
	{
		$container = $this->createContainer();
		$this->export( $container, false );
		$container->close();
	}
83706
protected function run()
    {
        foreach ($this->input as $key => $value) {
            $key = 'o_' . $key;
            if ($this->config->has($key)) {
                $this->config->set($key, $value);
                $this->raise(new OptionWasChanged($key, $value));
            }
        }

        $this->config->save();
    }
651690
public function runCommand($command)
    {
        $this->setAutoExit(false);
        $argv = explode(' ','application '.$command);
        $input = new ArgvInput($argv);
        $this->run($input);
    }
1222597
public function run()
  {
    $this->renderContent();
    $content=ob_get_clean();
    if($this->hideOnEmpty && trim($content)==='')
      return;
    echo $this->_beginTag;
    echo $content;
    echo '</div>';
    echo Html::endTag($this->tagName);    
  }
242960
public function run()
    {
        $tag = ArrayHelper::remove($this->containerOptions, 'tag', 'div');
        echo Html::endTag($tag);
        if ($this->renderInnerContainer) {
            echo Html::endTag('div');
        }
        $tag = ArrayHelper::remove($this->options, 'tag', 'nav');
        echo Html::endTag($tag, $this->options);
    }
51541
public function run()
    {
        $this->container->get('app')->run(
            $this->container->get('app.input'),
            $this->container->get('app.output')
        );
    }
1084847
public function run()
	{
		return $this->style->getCharacter()->setIsStrikethrough(
			$this->parameter === null || (bool) $this->parameter
		);
	}
237434
public function run()
    {
        if ($this->app->getName()) {
            $this->output->writeln($this->app->getName());
            $this->output->newline();
        }

        $commandName = $this->parameter->getArgument('command_name');

        if ($this->parameter->getCommandName() === $this->name && $commandName) {
            $this->showCommandHelp($this->parameter->getArgument('command_name'));
        } else {
            $this->showGeneralHelp();
        }

        return $this;
    }
1264647
public function run()
    {


        $input = new ConsoleInput();
        $input->message = 'Filename config.ini';
        $input->defaultValue = $filename = getcwd().DIRECTORY_SEPARATOR.'config.ini';

        $config = new ProjectConfigWriter();
        $config->filename =$input->getValue();   //  ProjectConfig::$projectPath . 'config.ini';
        $config->writeFile();

    }
428570
public function run()
    {
        $command = new \ReflectionClass($this);
        $options = input()->get();

        if (empty($options)) {
            if ($this->welcomeNote instanceof Format or $this->welcomeNote instanceof Text) {
                output()->write($this->welcomeNote);
            } elseif (is_string($this->welcomeNote) and $this->welcomeNote !== '') {
                output()->write(
                    (new Format())
                        ->setString(language()->getLine($this->welcomeNote))
                        ->setNewLinesAfter(1)
                );
            }

            output()->write(
                (new Format())
                    ->setString($this->name . ' v' . $this->version)
                    ->setNewLinesBefore(2)
                    ->setNewLinesAfter(1)
            );

            // Run help option
            $this->optionHelp();
        } else {

            foreach ($options as $method => $arguments) {

                if ($method === 'h') {
                    $method = 'help';
                } elseif ($method === 'v') {
                    $method = 'version';
                } elseif ($method === 'vv') {
                    $method = 'verbose';
                }

                $optionMethod = camelcase('option-' . $method);

                if ($command->hasMethod($optionMethod)) {

                    $commandMethod = $command->getMethod($optionMethod);

                    if ($commandMethod->getNumberOfRequiredParameters() == 0) {
                        call_user_func([&$this, $optionMethod]);
                    } else {
                        $optionArguments = is_array($arguments)
                            ? $arguments
                            : [$arguments];

                        call_user_func_array([&$this, $optionMethod], $optionArguments);
                    }
                }
            }
        }
    }
924691
public function run()
  {
    if ( \count((array)$this->obj) === 0 ){
      header('HTTP/1.0 404 Not Found');
      exit();
    }

    if ( $this->mode === 'cli' ){
      if ( !headers_sent() && !$this->obj->content ){
        exit('No output...');
      }
      if ( $this->obj->content ){
        echo $this->obj->content;
      }
      @ob_end_flush();
      exit();
    }

    if ( isset($this->obj->prescript) ){
      if ( empty($this->obj->prescript) ){
        unset($this->obj->prescript);
      }
      else if ( !BBN_IS_DEV ){
        try{
          $tmp = \JShrink\Minifier::minify($this->obj->prescript);
        }
        catch ( \RuntimeException $e ){
          \bbn\x::log($this->obj->prescript, 'js_shrink');
        }
        if ( $tmp ){
          $this->obj->prescript = $tmp;
        }
      }
    }
    if ( isset($this->obj->script) ){
      if ( empty($this->obj->script) ){
        unset($this->obj->script);
      }
      else if ( !BBN_IS_DEV ){
        try{
          $tmp = \JShrink\Minifier::minify($this->obj->script);
        }
        catch ( \RuntimeException $e ){
          \bbn\x::log($this->obj->script, 'js_shrink');
        }
        if ( $tmp ){
          $this->obj->script = $tmp;
        }

      }
    }
    if ( isset($this->obj->postscript) ){
      if ( empty($this->obj->postscript) ){
        unset($this->obj->postscript);
      }
      else if ( !BBN_IS_DEV ){
        try{
          $tmp = \JShrink\Minifier::minify($this->obj->postscript);
        }
        catch ( \RuntimeException $e ){
          \bbn\x::log($this->obj->postscript, 'js_shrink');
        }
        if ( $tmp ){
          $this->obj->postscript = $tmp;
        }
      }
    }
    if ( empty($this->obj->content) || ( ($this->mode === 'file') || ($this->mode === 'image') ) ){
      if (!empty($this->obj->file)){
        if (\is_string($this->obj->file) && is_file($this->obj->file)){
          $this->obj->file = new bbn\file($this->obj->file);
        }
        if (\is_object($this->obj->file) &&
          method_exists($this->obj->file, 'download') &&
          method_exists($this->obj->file, 'test') &&
          $this->obj->file->test()
        ){
          $this->mode = 'file';
        }
      }
      else if (!empty($this->obj->img)){
        if (\is_string($this->obj->img) && is_file($this->obj->img)){
          $this->obj->img = new bbn\file\image($this->obj->img);
        }
        if (\is_object($this->obj->img) &&
          method_exists($this->obj->img, 'display') &&
          method_exists($this->obj->img, 'test') &&
          $this->obj->img->test()
        ){
          $this->mode = 'image';
        }
      }
    }
    switch ( $this->mode ){
      case 'public':
      case 'json':
      case 'js':
      case 'css':
      case 'doc':
      case 'html':
        if ( !ob_start("ob_gzhandler" ) ){
          ob_start();
        }
        else{
          header('Content-Encoding: gzip');
        }
        break;
      default:
        ob_start();
    }
    if ( (empty($this->obj->content) && empty($this->obj->file) && empty($this->obj->img) && ($this->mode !==
          'public')) ||
      (($this->mode === 'public') && empty($this->obj)) ){
      $this->mode = '';
    }
    else if ( !empty($this->obj->content) && !empty($this->obj->help) ){
      $Parsedown = new \Parsedown();
      $this->obj->help = $Parsedown->text($this->obj->help);
    }
    switch ( $this->mode ){

      case 'public':
        header('Content-type: application/json; charset=utf-8');
        echo json_encode($this->obj);
        break;

      case 'js':
        header('Content-type: application/javascript; charset=utf-8');
        echo $this->obj->content;
        break;

      case 'css':
        header('Content-type: text/css; charset=utf-8');
        echo $this->obj->content;
        break;

      case 'text':
        header('Content-type: text/plain; charset=utf-8');
        echo $this->obj->content;
        break;

      case 'xml':
        header('Content-type: text/xml; charset=utf-8');
        echo $this->obj->content;
        break;

      case 'image':
        if ( isset($this->obj->img) && \is_object($this->obj->img) ){
          $this->obj->img->display();
        }
        else{
          $this->log("Impossible to display the following image: ".$this->obj->img->name);
          header('HTTP/1.0 404 Not Found');

        }
        break;

      case 'file':
        if ( isset($this->obj->file) && \is_object($this->obj->file) && method_exists($this->obj->file, 'download') ){
          $this->obj->file->download();
        }
        else{
          $this->log("Impossible to display the following controller", $this);
          header('HTTP/1.0 404 Not Found');
          exit();
        }
        break;

      default:
        header('Content-type: text/html; charset=utf-8');
        echo isset($this->obj->content) ? $this->obj->content : '';

    }
  }
200962
public function run()
	{
		// streams
		$read = [$this->_input];

		$write  = null;
		$except = null;

		// stream ends?
		$end_of_stream = false;

		$waitForMinComputationTime = defined('PROKKIBOT_MIN_COMPUTATION_TIME') && !empty(PROKKIBOT_MIN_COMPUTATION_TIME);

		do
		{

			$changed_streams = stream_select($read, $write, $except, PROKKIBOT_MAX_SERVER_TIMEOUT);

			if( $waitForMinComputationTime )
			{
				$time_start = get_microtime_float();
			}
			
			if( false === $changed_streams )
			{
				die();
			}

			foreach( $read as $_handle )
			{

				$string = trim(fgets($_handle));

				if( empty($string) )
				{
					$end_of_stream = true;
					continue;
				}

				Debugger::Log(sprintf("received: %s\n", $string));

				$end_of_stream = feof($_handle);

				try
				{

					$command = $this->_bot->getParser()->run($string);

//					Debugger::Log(get_class($command) . "\n");

					$command->apply($this->_bot);

//					Debugger::Log("applied\n");

//					Debugger::Log(sprintf("Round: %d, Remaining: %d, Last: %d\n",
//						$this->_environment->getCurrentRoundNo(),
//						$this->_environment->getRemainingRounds(),
//						$this->_environment->isLastRound()
//					));

					if( $command->isComputable() )
					{

						/** @var Computable $command */
						$send = $command->compute($this->_bot);

						if( $waitForMinComputationTime )
						{
							self::_WaitForMinCompuitationTime($time_start);
						}

						fwrite($this->_output, $send . "\n");

						Debugger::Log(sprintf("send: %s\n", $send));
					}

				}
				catch( \Exception $exception )
				{
					Debugger::Log(sprintf("Exception:%s\n\n%s", $exception->getMessage(), $exception->getTraceAsString()));

					$send = "Aborting due an error :-(";

					fwrite($this->_output, $send . "\n");

					Debugger::Log(sprintf("send: %s\n", $send));

					$end_of_stream = true;
				}

			}
		}
		while( !$end_of_stream && !empty($changed_streams) );

		Debugger::Log("MEM: " . size_to_readable_string(memory_get_usage(true)) . "\n");

		Debugger::Log("END!\n");

		fclose($this->_input);
	}