Completed
Push — develop ( 87aefd...53f18f )
by Mike
07:16
created

RunCommand::observeProgressToShowProgressBars()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 34
ccs 0
cts 33
cp 0
crap 6
rs 9.376
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Application\Console\Command\Project;
17
18
use League\Pipeline\Pipeline;
19
use Monolog\Logger;
20
use phpDocumentor\Application\Console\Command\Command;
21
use phpDocumentor\Descriptor\ProjectDescriptorBuilder;
22
use phpDocumentor\Event\Dispatcher;
23
use phpDocumentor\Parser\Event\PreFileEvent;
24
use phpDocumentor\Parser\Event\PreParsingEvent;
25
use phpDocumentor\Transformer\Event\PostTransformationEvent;
26
use phpDocumentor\Transformer\Event\PostTransformEvent;
27
use phpDocumentor\Transformer\Event\PreTransformEvent;
28
use phpDocumentor\Transformer\Transformer;
29
use Psr\Log\LoggerInterface;
30
use Symfony\Bridge\Monolog\Handler\ConsoleHandler;
31
use Symfony\Component\Console\Helper\ProgressBar;
32
use Symfony\Component\Console\Input\InputInterface;
33
use Symfony\Component\Console\Input\InputOption;
34
use Symfony\Component\Console\Output\OutputInterface;
35
36
/**
37
 * Parse and transform the given directory (-d|-f) to the given location (-t).
38
 *
39
 * phpDocumentor creates documentation from PHP source files. The simplest way
40
 * to use it is:
41
 *
42
 *     $ phpdoc run -d <directory to parse> -t <output directory>
43
 *
44
 * This will parse every file ending with .php, .php3 and .phtml in <directory
45
 * to parse> and then output a HTML site containing easily readable documentation
46
 * in <output directory>.
47
 *
48
 * phpDocumentor will try to look for a phpdoc.dist.xml or phpdoc.xml file in your
49
 * current working directory and use that to override the default settings if
50
 * present. In the configuration file can you specify the same settings (and
51
 * more) as the command line provides.
52
 */
53
class RunCommand extends Command
54
{
55
    /** @var ProjectDescriptorBuilder */
56
    private $projectDescriptorBuilder;
57
58
    /** @var Pipeline */
59
    private $pipeline;
60
61
    /** @var ProgressBar */
62
    private $progressBar;
63
64
    /** @var ProgressBar */
65
    private $transformerProgressBar;
66
67
    /** @var LoggerInterface */
68
    private $logger;
69
70
    /**
71
     * RunCommand constructor.
72
     */
73
    public function __construct(
74
        ProjectDescriptorBuilder $projectDescriptorBuilder,
75
        Pipeline $pipeline,
76
        LoggerInterface $logger
77
    ) {
78
        parent::__construct('project:run');
79
80
        $this->projectDescriptorBuilder = $projectDescriptorBuilder;
81
        $this->pipeline = $pipeline;
82
        $this->logger = $logger;
83
    }
84
85
    /**
86
     * Initializes this command and sets the name, description, options and
87
     * arguments.
88
     */
89
    protected function configure(): void
90
    {
91
        $this->setName('project:run')
92
            ->setAliases(['run'])
93
            ->setDescription(
94
                'Parses and transforms the given files to a specified location'
95
            )
96
            ->setHelp(
97
<<<HELP
98
phpDocumentor creates documentation from PHP source files. The simplest way
99
to use it is:
100
101
    <info>$ phpdoc run -d [directory to parse] -t [output directory]</info>
102
103
This will parse every file ending with .php, .php3 and .phtml in <directory
104
to parse> and then output a HTML site containing easily readable documentation
105
in <output directory>.
106
107
phpDocumentor will try to look for a phpdoc.dist.xml or phpdoc.xml file in your
108
current working directory and use that to override the default settings if
109
present. In the configuration file can you specify the same settings (and
110
more) as the command line provides.
111
112
<comment>Other commands</comment>
113
In addition to this command phpDocumentor also supports additional commands:
114
115
<comment>Available commands:</comment>
116
<info>  help
117
  list
118
  parse
119
  run
120
  transform
121
<comment>project</comment>
122
  project:parse
123
  project:run
124
  project:transform
125
<comment>template</comment>
126
  template:generate
127
  template:list
128
  template:package</info>
129
130
You can get a more detailed listing of the commands using the <info>list</info>
131
command and get help by prepending the word <info>help</info> to the command
132
name.
133
HELP
134
            )
135
            ->addOption(
136
                'target',
137
                't',
138
                InputOption::VALUE_OPTIONAL,
139
                'Path where to store the generated output'
140
            )
141
            ->addOption(
142
                'cache-folder',
143
                null,
144
                InputOption::VALUE_OPTIONAL,
145
                'Path where to store the cache files'
146
            )
147
            ->addOption(
148
                'filename',
149
                'f',
150
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
151
                'Comma-separated list of files to parse. The wildcards ? and * are supported'
152
            )
153
            ->addOption(
154
                'directory',
155
                'd',
156
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
157
                'Comma-separated list of directories to (recursively) parse'
158
            )
159
            ->addOption(
160
                'encoding',
161
                null,
162
                InputOption::VALUE_OPTIONAL,
163
                'encoding to be used to interpret source files with'
164
            )
165
            ->addOption(
166
                'extensions',
167
                null,
168
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
169
                'Comma-separated list of extensions to parse, defaults to php, php3 and phtml'
170
            )
171
            ->addOption(
172
                'ignore',
173
                'i',
174
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
175
                'Comma-separated list of file(s) and directories (relative to the source-code directory) that will be '
176
                . 'ignored. Wildcards * and ? are supported'
177
            )
178
            ->addOption(
179
                'ignore-tags',
180
                null,
181
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
182
                'Comma-separated list of tags that will be ignored, defaults to none. package, subpackage and ignore '
183
                . 'may not be ignored.'
184
            )
185
            ->addOption(
186
                'hidden',
187
                null,
188
                InputOption::VALUE_NONE,
189
                'Use this option to tell phpDocumentor to parse files and directories that begin with a period (.), '
190
                . 'by default these are ignored'
191
            )
192
            ->addOption(
193
                'ignore-symlinks',
194
                null,
195
                InputOption::VALUE_NONE,
196
                'Ignore symlinks to other files or directories, default is on'
197
            )
198
            ->addOption(
199
                'markers',
200
                'm',
201
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
202
                'Comma-separated list of markers/tags to filter'
203
            )
204
            ->addOption(
205
                'title',
206
                null,
207
                InputOption::VALUE_OPTIONAL,
208
                'Sets the title for this project; default is the phpDocumentor logo'
209
            )
210
            ->addOption(
211
                'force',
212
                null,
213
                InputOption::VALUE_NONE,
214
                'Forces a full build of the documentation, does not increment existing documentation'
215
            )
216
            ->addOption(
217
                'validate',
218
                null,
219
                InputOption::VALUE_NONE,
220
                'Validates every processed file using PHP Lint, costs a lot of performance'
221
            )
222
            ->addOption(
223
                'visibility',
224
                null,
225
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
226
                'Specifies the parse visibility that should be displayed in the documentation (comma separated e.g. '
227
                . '"public,protected")'
228
            )
229
            ->addOption(
230
                'defaultpackagename',
231
                null,
232
                InputOption::VALUE_OPTIONAL,
233
                'Name to use for the default package.',
234
                'Default'
235
            )
236
            ->addOption(
237
                'sourcecode',
238
                null,
239
                InputOption::VALUE_NONE,
240
                'Whether to include syntax highlighted source code'
241
            )
242
            ->addOption(
243
                'progressbar',
244
                'p',
245
                InputOption::VALUE_NONE,
246
                'Whether to show a progress bar; will automatically quiet logging to stdout'
247
            )
248
            ->addOption(
249
                'template',
250
                null,
251
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
252
                'Name of the template to use (optional)'
253
            )
254
            ->addOption(
255
                'parseprivate',
256
                null,
257
                InputOption::VALUE_NONE,
258
                'Whether to parse DocBlocks marked with @internal tag'
259
            );
260
261
        parent::configure();
262
    }
263
264
    /**
265
     * Executes the business logic involved with this command.
266
     */
267
    protected function execute(InputInterface $input, OutputInterface $output): int
268
    {
269
        $output->writeln('phpDocumentor ' . $this->getApplication()->getVersion());
270
        $output->writeln('');
271
272
        $this->observeProgressToShowProgressBars($output);
273
274
        $pipeLine = $this->pipeline;
275
        $pipeLine($input->getOptions());
276
277
        if ($output->getVerbosity() === OutputInterface::VERBOSITY_DEBUG) {
278
            file_put_contents('ast.dump', serialize($this->projectDescriptorBuilder->getProjectDescriptor()));
279
        }
280
281
        $output->writeln('');
282
        $output->writeln('All done!');
283
284
        return 0;
285
    }
286
287
    private function observeProgressToShowProgressBars(OutputInterface $output): void
288
    {
289
        if ($output->getVerbosity() !== OutputInterface::VERBOSITY_NORMAL) {
290
            return;
291
        }
292
293
        Dispatcher::getInstance()->addListener(
294
            'parser.pre',
295
            function (PreParsingEvent $event) use ($output) {
296
                $output->writeln('Parsing files');
297
                $this->progressBar = new ProgressBar($output, $event->getFileCount());
298
            }
299
        );
300
        Dispatcher::getInstance()->addListener(
301
            'parser.file.pre',
302
            function (PreFileEvent $event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
303
                $this->progressBar->advance();
304
            }
305
        );
306
        Dispatcher::getInstance()->addListener(
307
            Transformer::EVENT_PRE_TRANSFORM,
308
            function (PreTransformEvent $event) use ($output) {
309
                $output->writeln('');
310
                $output->writeln('Applying transformations (can take a while)');
311
                $this->transformerProgressBar = new ProgressBar($output, count($event->getSubject()->getTemplates()->getTransformations()));
312
            }
313
        );
314
        Dispatcher::getInstance()->addListener(
315
            Transformer::EVENT_POST_TRANSFORMATION,
316
            function (PostTransformationEvent $event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
317
                $this->transformerProgressBar->advance();
318
            }
319
        );
320
    }
321
}
322