Completed
Pull Request — develop (#1730)
by Mike
38:53 queued 29:03
created

Application/Cli/Command/RunCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright 2010-2015 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\Application\Cli\Command;
14
15
use League\Event\Emitter;
16
use League\Tactician\CommandBus;
17
use phpDocumentor\ApiReference\DocumentGroupDefinition;
18
use phpDocumentor\ApiReference\FileParsed;
19
use phpDocumentor\ApiReference\ParsingStarted;
20
use phpDocumentor\Application\Commands\ConfigureCache;
21
use phpDocumentor\Application\Commands\MergeConfigurationWithCommandLineOptions;
22
use phpDocumentor\Application\Commands\Render;
23
use phpDocumentor\DocumentationFactory;
24
use phpDocumentor\DocumentationRepository;
25
use phpDocumentor\Project\Version\DefinitionRepository;
26
use phpDocumentor\Renderer\RenderActionCompleted;
27
use phpDocumentor\Renderer\RenderingFinished;
28
use phpDocumentor\Renderer\RenderingStarted;
29
use Stash\Driver\FileSystem;
30
use Symfony\Component\Console\Command\Command;
31
use Symfony\Component\Console\Helper\HelperInterface;
32
use Symfony\Component\Console\Helper\ProgressBar;
33
use Symfony\Component\Console\Helper\ProgressHelper;
34
use Symfony\Component\Console\Input\ArrayInput;
35
use Symfony\Component\Console\Input\InputArgument;
36
use Symfony\Component\Console\Input\InputInterface;
37
use Symfony\Component\Console\Input\InputOption;
38
use Symfony\Component\Console\Output\OutputInterface;
39
40
/**
41
 * Parse and transform the given directory (-d|-f) to the given location (-t).
42
 *
43
 * phpDocumentor creates documentation from PHP source files. The simplest way
44
 * to use it is:
45
 *
46
 *     $ phpdoc run -d <directory to parse> -t <output directory>
47
 *
48
 * This will parse every file ending with .php, .php3 and .phtml in <directory
49
 * to parse> and then output a HTML site containing easily readable documentation
50
 * in <output directory>.
51
 *
52
 * phpDocumentor will try to look for a phpdoc.dist.xml or phpdoc.xml file in your
53
 * current working directory and use that to override the default settings if
54
 * present. In the configuration file can you specify the same settings (and
55
 * more) as the command line provides.
56
 */
57
final class RunCommand extends Command
0 ignored issues
show
The class RunCommand has a coupling between objects value of 21. Consider to reduce the number of dependencies under 13.
Loading history...
58
{
59
    /** @var CommandBus */
60
    private $commandBus;
61
62
    /** @var Emitter */
63
    private $emitter;
64
65
    /** @var DefinitionRepository */
66
    private $definitionRepository;
67
68
    /** @var DocumentationFactory */
69
    private $documentationFactory;
70
71
    /** @var DocumentationRepository */
72
    private $documentationRepository;
73
74
    /**
75
     * Initializes the command with all necessary dependencies
76
     *
77
     * @param DefinitionRepository    $definitionRepository
78
     * @param DocumentationRepository $documentationRepository
79
     * @param DocumentationFactory    $documentationFactory
80
     * @param CommandBus              $commandBus
81
     * @param Emitter                 $emitter
82
     */
83
    public function __construct(
84
        DefinitionRepository $definitionRepository,
85
        DocumentationRepository $documentationRepository,
86
        DocumentationFactory $documentationFactory,
87
        CommandBus $commandBus,
88
        Emitter $emitter
89
    ) {
90
        $this->commandBus                   = $commandBus;
91
        $this->emitter                      = $emitter;
92
        $this->definitionRepository         = $definitionRepository;
93
        $this->documentationFactory         = $documentationFactory;
94
        $this->documentationRepository      = $documentationRepository;
95
96
        parent::__construct('project:run');
97
    }
98
99
    /**
100
     * Initializes this command and sets the name, description, options and
101
     * arguments.
102
     *
103
     * @return void
104
     */
105
    protected function configure()
106
    {
107
        $this
108
            ->setAliases(array('run'))
109
            ->setDescription(
110
                'Parses and transforms the given files to a specified location'
111
            )
112
            ->setHelp(
113
                <<<HELP
114
phpDocumentor creates documentation from PHP source files. The simplest way
115
to use it is:
116
117
    <info>$ phpdoc run -d [directory to parse] -t [output directory]</info>
118
119
This will parse every file ending with .php, .php3 and .phtml in <directory
120
to parse> and then output a HTML site containing easily readable documentation
121
in <output directory>.
122
123
phpDocumentor will try to look for a phpdoc.dist.xml or phpdoc.xml file in your
124
current working directory and use that to override the default settings if
125
present. In the configuration file can you specify the same settings (and
126
more) as the command line provides.
127
128
<comment>Other commands</comment>
129
In addition to this command phpDocumentor also supports additional commands:
130
131
<comment>Available commands:</comment>
132
<info>  help
133
  list
134
  parse
135
  run
136
  transform
137
<comment>project</comment>
138
  project:parse
139
  project:run
140
  project:transform
141
<comment>template</comment>
142
  template:generate
143
  template:list
144
  template:package</info>
145
146
You can get a more detailed listing of the commands using the <info>list</info>
147
command and get help by prepending the word <info>help</info> to the command
148
name.
149
HELP
150
            )
151
            ->addOption(
152
                'target',
153
                't',
154
                InputOption::VALUE_OPTIONAL,
155
                'Path where to store the generated output'
156
            )
157
            ->addOption(
158
                'cache-folder',
159
                null,
160
                InputOption::VALUE_OPTIONAL,
161
                'Path where to store the cache files'
162
            )
163
            ->addOption(
164
                'filename',
165
                'f',
166
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
167
                'Comma-separated list of files to parse. The wildcards ? and * are supported'
168
            )
169
            ->addOption(
170
                'directory',
171
                'd',
172
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
173
                'Comma-separated list of directories to (recursively) parse'
174
            )
175
            ->addOption(
176
                'encoding',
177
                null,
178
                InputOption::VALUE_OPTIONAL,
179
                'encoding to be used to interpret source files with'
180
            )
181
            ->addOption(
182
                'extensions',
183
                'e',
184
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
185
                'Comma-separated list of extensions to parse, defaults to php, php3 and phtml'
186
            )
187
            ->addOption(
188
                'ignore',
189
                'i',
190
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
191
                'Comma-separated list of file(s) and directories (relative to the source-code directory) that will be '
192
                . 'ignored. Wildcards * and ? are supported'
193
            )
194
            ->addOption(
195
                'markers',
196
                'm',
197
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
198
                'Comma-separated list of markers/tags to filter'
199
            )
200
            ->addOption(
201
                'title',
202
                null,
203
                InputOption::VALUE_OPTIONAL,
204
                'Sets the title for this project; default is the phpDocumentor logo'
205
            )
206
            ->addOption(
207
                'force',
208
                null,
209
                InputOption::VALUE_NONE,
210
                'Forces a full build of the documentation, does not increment existing documentation'
211
            )
212
            ->addOption(
213
                'visibility',
214
                null,
215
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
216
                'Specifies the parse visibility that should be displayed in the documentation (comma separated e.g. '
217
                . '"public,protected")'
218
            )
219
            ->addOption(
220
                'defaultpackagename',
221
                null,
222
                InputOption::VALUE_OPTIONAL,
223
                'Name to use for the default package.'
224
            )
225
            ->addOption(
226
                'sourcecode',
227
                null,
228
                InputOption::VALUE_NONE,
229
                'Whether to include syntax highlighted source code'
230
            )
231
            ->addOption(
232
                'progressbar',
233
                'p',
234
                InputOption::VALUE_NONE,
235
                'Whether to show a progress bar; will automatically quiet logging to stdout'
236
            )
237
            ->addOption(
238
                'template',
239
                null,
240
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
241
                'Name of the template to use (optional)'
242
            )
243
            ->addOption(
244
                'parseprivate',
245
                null,
246
                InputOption::VALUE_NONE,
247
                'Whether to parse DocBlocks marked with @internal tag'
248
            )
249
            ->addArgument(
250
                'paths',
251
                InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
252
                'One or more files and folders to process',
253
                array()
254
            );
255
256
        parent::configure();
257
    }
258
259
    /**
260
     * Executes the business logic involved with this command.
261
     *
262
     * @param InputInterface $input
263
     * @param OutputInterface $output
264
     *
265
     * @return int
266
     */
267
    protected function execute(InputInterface $input, OutputInterface $output)
268
    {
269
        $output->writeln(
270
            sprintf(
271
                '<info>%s</info> version <comment>%s</comment>' . PHP_EOL,
272
                $this->getApplication()->getName(),
273
                $this->getApplication()->getVersion()
274
            )
275
        );
276
        $this->attachListeners($input, $output);
277
278
        $this->commandBus->handle(
279
            new MergeConfigurationWithCommandLineOptions($input->getOptions(), $input->getArguments())
280
        );
281
282
        $this->commandBus->handle(
283
            new ConfigureCache()
284
        );
285
286
        foreach ($this->definitionRepository->fetchAll() as $definition) {
287
            $documentation = $this->documentationRepository->findByVersionNumber($definition->getVersionNumber());
288
289
            if ($documentation === null) {
290
                $documentation = $this->documentationFactory->create($definition);
291
                $this->documentationRepository->save($documentation);
292
            }
293
            $this->commandBus->handle(
294
                new Render($documentation, sys_get_temp_dir() . '/phpdoc', $input->getOption('template') ?: ['clean'])
295
            );
296
        }
297
298
        $output->writeln(sprintf(PHP_EOL . '<fg=black;bg=green>OK (%s)</>', sys_get_temp_dir()));
299
300
        return 0;
301
    }
302
303
    /**
304
     * Connect a series of output messages to various events to display progress.
305
     *
306
     * @param InputInterface  $input
307
     * @param OutputInterface $output
308
     *
309
     * @return void
310
     */
311
    private function attachListeners(InputInterface $input, OutputInterface $output)
312
    {
313
        $this->emitter->addListener(
314
            ParsingStarted::class,
315
            function (ParsingStarted $event) use ($output) {
316
                /** @var DocumentGroupDefinition $definition */
317
                $definition = $event->definition();
318
                $output->writeln(
319
                    sprintf('Parsing <info>%d</info> files', count($definition->getFiles()))
320
                );
321
            }
322
        );
323
        $this->emitter->addListener(
324
            FileParsed::class,
325
            function (FileParsed $event) use ($output) {
326
                $output->writeln(sprintf('  Parsed <info>%s</info>', (string)$event->filename()));
327
            }
328
        );
329
        $this->emitter->addListener(
330
            RenderingStarted::class,
331
            function (RenderingStarted $event) use ($output) {
332
                $output->writeln('Started rendering');
333
            }
334
        );
335
        $this->emitter->addListener(
336
            RenderingFinished::class,
337
            function (RenderingFinished $event) use ($output) {
338
                $output->writeln('Completed rendering');
339
            }
340
        );
341
        $this->emitter->addListener(
342
            RenderActionCompleted::class,
343
            function (RenderActionCompleted $event) use ($output) {
344
                $output->writeln(sprintf('  %s', (string)$event->action()));
345
            }
346
        );
347
    }
348
}
349