Yaffs site version 1.1
[yaffs-website] / vendor / psy / psysh / src / Psy / Command / WtfCommand.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2017 Justin Hileman
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Psy\Command;
13
14 use Psy\Context;
15 use Psy\ContextAware;
16 use Psy\Input\FilterOptions;
17 use Psy\Output\ShellOutput;
18 use Symfony\Component\Console\Input\InputArgument;
19 use Symfony\Component\Console\Input\InputInterface;
20 use Symfony\Component\Console\Input\InputOption;
21 use Symfony\Component\Console\Output\OutputInterface;
22
23 /**
24  * Show the last uncaught exception.
25  */
26 class WtfCommand extends TraceCommand implements ContextAware
27 {
28     /**
29      * Context instance (for ContextAware interface).
30      *
31      * @var Context
32      */
33     protected $context;
34
35     /**
36      * ContextAware interface.
37      *
38      * @param Context $context
39      */
40     public function setContext(Context $context)
41     {
42         $this->context = $context;
43     }
44
45     /**
46      * {@inheritdoc}
47      */
48     protected function configure()
49     {
50         list($grep, $insensitive, $invert) = FilterOptions::getOptions();
51
52         $this
53             ->setName('wtf')
54             ->setAliases(array('last-exception', 'wtf?'))
55             ->setDefinition(array(
56                 new InputArgument('incredulity', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Number of lines to show'),
57                 new InputOption('all', 'a',  InputOption::VALUE_NONE, 'Show entire backtrace.'),
58
59                 $grep,
60                 $insensitive,
61                 $invert,
62             ))
63             ->setDescription('Show the backtrace of the most recent exception.')
64             ->setHelp(
65                 <<<'HELP'
66 Shows a few lines of the backtrace of the most recent exception.
67
68 If you want to see more lines, add more question marks or exclamation marks:
69
70 e.g.
71 <return>>>> wtf ?</return>
72 <return>>>> wtf ?!???!?!?</return>
73
74 To see the entire backtrace, pass the -a/--all flag:
75
76 e.g.
77 <return>>>> wtf -v</return>
78 HELP
79             );
80     }
81
82     /**
83      * {@inheritdoc}
84      */
85     protected function execute(InputInterface $input, OutputInterface $output)
86     {
87         $this->filter->bind($input);
88
89         $incredulity = implode('', $input->getArgument('incredulity'));
90         if (strlen(preg_replace('/[\\?!]/', '', $incredulity))) {
91             throw new \InvalidArgumentException('Incredulity must include only "?" and "!".');
92         }
93
94         $exception = $this->context->getLastException();
95         $count     = $input->getOption('all') ? PHP_INT_MAX : max(3, pow(2, strlen($incredulity) + 1));
96
97         $shell = $this->getApplication();
98         $output->startPaging();
99         do {
100             $traceCount = count($exception->getTrace());
101             $showLines = $count;
102             // Show the whole trace if we'd only be hiding a few lines
103             if ($traceCount < max($count * 1.2, $count + 2)) {
104                 $showLines = PHP_INT_MAX;
105             }
106
107             $trace = $this->getBacktrace($exception, $showLines);
108             $moreLines = $traceCount - count($trace);
109
110             $output->writeln($shell->formatException($exception));
111             $output->writeln('--');
112             $output->write($trace, true, ShellOutput::NUMBER_LINES);
113             $output->writeln('');
114
115             if ($moreLines > 0) {
116                 $output->writeln(sprintf(
117                     '<aside>Use <return>wtf -a</return> to see %d more lines</aside>',
118                     $moreLines
119                 ));
120                 $output->writeln('');
121             }
122         } while ($exception = $exception->getPrevious());
123         $output->stopPaging();
124     }
125 }