HelpHandler::getAsciiDocDir()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/*
4
 * This file is part of the webmozart/console package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
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 Webmozart\Console\Handler\Help;
13
14
use Symfony\Component\Process\ExecutableFinder;
15
use Webmozart\Assert\Assert;
16
use Webmozart\Console\Api\Application\Application;
17
use Webmozart\Console\Api\Args\Args;
18
use Webmozart\Console\Api\Command\Command;
19
use Webmozart\Console\Api\IO\IO;
20
use Webmozart\Console\Handler\DelegatingHandler;
21
use Webmozart\Console\Process\ProcessLauncher;
22
23
/**
24
 * Handler for the "help" command.
25
 *
26
 * @since  1.0
27
 *
28
 * @author Bernhard Schussek <[email protected]>
29
 */
30
class HelpHandler extends DelegatingHandler
31
{
32
    /**
33
     * @var ExecutableFinder
34
     */
35
    private $executableFinder;
36
37
    /**
38
     * @var ProcessLauncher
39
     */
40
    private $processLauncher;
41
42
    /**
43
     * @var string
44
     */
45
    private $manBinary;
46
47
    /**
48
     * @var string
49
     */
50
    private $manDir;
51
52
    /**
53
     * @var string
54
     */
55
    private $lessBinary;
56
57
    /**
58
     * @var string
59
     */
60
    private $asciiDocDir;
61
62
    /**
63
     * @var string
64
     */
65
    private $applicationPage;
66
67
    /**
68
     * @var string
69
     */
70
    private $commandPagePrefix;
71
72
    /**
73
     * Creates the handler.
74
     *
75
     * @param ExecutableFinder $executableFinder The finder used to find the
0 ignored issues
show
Documentation introduced by
Should the type for parameter $executableFinder not be null|ExecutableFinder?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
76
     *                                           "less"/"man" binaries.
77
     * @param ProcessLauncher  $processLauncher  The launcher for executing the
0 ignored issues
show
Documentation introduced by
Should the type for parameter $processLauncher not be null|ProcessLauncher?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
78
     *                                           "less"/"man" binaries.
79
     */
80 52
    public function __construct(ExecutableFinder $executableFinder = null, ProcessLauncher $processLauncher = null)
81
    {
82 52
        $this->executableFinder = $executableFinder ?: new ExecutableFinder();
83 52
        $this->processLauncher = $processLauncher ?: new ProcessLauncher();
84 52
        $this->asciiDocDir = getcwd().'/docs/ascii-doc';
85 52
        $this->manDir = getcwd().'/docs/man';
86
87 52
        $this->register('ascii-doc', array($this, 'createAsciiDocHandler'));
88 52
        $this->register('json', array($this, 'createJsonHandler'));
89 52
        $this->register('man', array($this, 'createManHandler'));
90 52
        $this->register('text', array($this, 'createTextHandler'));
91 52
        $this->register('xml', array($this, 'createXmlHandler'));
92 52
        $this->selectHandler(array($this, 'getHandlerToRun'));
93 52
    }
94
95
    /**
96
     * Callback for creating the "--ascii-doc" handler.
97
     *
98
     * @param Args    $args    The console arguments.
99
     * @param IO      $io      The I/O.
100
     * @param Command $command The handled command.
101
     *
102
     * @return HelpAsciiDocHandler The created handler.
103
     */
104 11 View Code Duplication
    public function createAsciiDocHandler(Args $args, IO $io, Command $command)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
    {
106 11
        $path = $this->getAsciiDocPage($command->getApplication(), $args);
107
108 11
        $handler = new HelpAsciiDocHandler($path, $this->executableFinder, $this->processLauncher);
109 11
        $handler->setLessBinary($this->lessBinary);
110
111 11
        return $handler;
112
    }
113
114
    /**
115
     * Callback for creating the "--json" handler.
116
     *
117
     * @return HelpJsonHandler The created handler.
118
     */
119 4
    public function createJsonHandler()
120
    {
121 4
        return new HelpJsonHandler();
122
    }
123
124
    /**
125
     * Callback for creating the "--man" handler.
126
     *
127
     * @param Args    $args    The console arguments.
128
     * @param IO      $io      The I/O.
129
     * @param Command $command The handled command.
130
     *
131
     * @return HelpManHandler The created handler.
132
     */
133 13 View Code Duplication
    public function createManHandler(Args $args, IO $io, Command $command)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
134
    {
135 13
        $path = $this->getManPage($command->getApplication(), $args);
136
137 13
        $handler = new HelpManHandler($path, $this->executableFinder, $this->processLauncher);
138 13
        $handler->setManBinary($this->manBinary);
139
140 13
        return $handler;
141
    }
142
143
    /**
144
     * Callback for creating the "--text" handler.
145
     *
146
     * @return HelpTextHandler The created handler.
147
     */
148 20
    public function createTextHandler()
149
    {
150 20
        return new HelpTextHandler();
151
    }
152
153
    /**
154
     * Callback for creating the "--xml" handler.
155
     *
156
     * @return HelpXmlHandler The created handler.
157
     */
158 4
    public function createXmlHandler()
159
    {
160 4
        return new HelpXmlHandler();
161
    }
162
163
    /**
164
     * Callback for selecting the handler that should be run.
165
     *
166
     * @param Args    $args    The console arguments.
167
     * @param IO      $io      The I/O.
168
     * @param Command $command The handled command.
169
     *
170
     * @return string The name of the handler to run.
0 ignored issues
show
Documentation introduced by
Should the return type not be string|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
171
     */
172 52
    public function getHandlerToRun(Args $args, IO $io, Command $command)
173
    {
174 52
        $rawArgs = $args->getRawArgs();
175
176
        // The raw arguments should always be available, but check anyway
177 52
        if (!$rawArgs) {
178
            return 'text';
179
        }
180
181
        // If "-h" is given, always print the short text usage
182 52
        if ($rawArgs->hasToken('-h')) {
183 7
            return 'text';
184
        }
185
186
        // Check if any of the options is set
187 45
        foreach ($this->getRegisteredNames() as $handlerName) {
188 45
            if ($rawArgs->hasToken('--'.$handlerName)) {
189 45
                return $handlerName;
190
            }
191
        }
192
193
        // No format option is set, "-h" is not set
194
        // If a command is given or if "--help" is set, display the manual
195 17
        if ($rawArgs->hasToken('--help')) {
196
            // Return "man" if the binary is available and the man page exists
197
            // The process launcher must be supported on the system
198 14
            $manPage = $this->getManPage($command->getApplication(), $args);
199
200 14
            if (file_exists($manPage) && $this->processLauncher->isSupported()) {
201 6
                if (!$this->manBinary) {
202 6
                    $this->manBinary = $this->executableFinder->find('man');
203
                }
204
205 6
                if ($this->manBinary) {
206 5
                    return 'man';
207
                }
208
            }
209
210
            // Return "ascii-doc" if the AsciiDoc page exists
211 9
            $asciiDocPage = $this->getAsciiDocPage($command->getApplication(), $args);
212
213 9
            if (file_exists($asciiDocPage)) {
214 3
                return 'ascii-doc';
215
            }
216
        }
217
218
        // No command, no option -> display command list as text
219 9
        return 'text';
220
    }
221
222
    /**
223
     * Returns the "man" binary used to display the man pages.
224
     *
225
     * @return string The "man" binary or `null` if the binary is auto-detected.
226
     */
227
    public function getManBinary()
228
    {
229
        return $this->manBinary;
230
    }
231
232
    /**
233
     * Sets the "man" binary used to display the AsciiDoc pages.
234
     *
235
     * @param string $manBinary The "man" binary to use.
236
     */
237
    public function setManBinary($manBinary)
238
    {
239
        if (null !== $manBinary) {
240
            Assert::string($manBinary, 'The man binary must be a string or null. Got: %s');
241
            Assert::notEmpty($manBinary, 'The man binary must not be empty.');
242
        }
243
244
        $this->manBinary = $manBinary;
245
    }
246
247
    /**
248
     * Returns the "less" binary used to display the AsciiDoc pages.
249
     *
250
     * @return string The "less" binary or `null` if the binary is auto-detected.
251
     */
252
    public function getLessBinary()
253
    {
254
        return $this->lessBinary;
255
    }
256
257
    /**
258
     * Sets the "less" binary used to display the AsciiDoc pages.
259
     *
260
     * @param string $lessBinary The "less" binary to use.
261
     */
262 View Code Duplication
    public function setLessBinary($lessBinary)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
263
    {
264
        if (null !== $lessBinary) {
265
            Assert::string($lessBinary, 'The less binary must be a string or null. Got: %s');
266
            Assert::notEmpty($lessBinary, 'The less binary must not be empty.');
267
        }
268
269
        $this->lessBinary = $lessBinary;
270
    }
271
272
    /**
273
     * Returns the directory containing the man pages.
274
     *
275
     * @return string The directory that contains the man pages.
276
     */
277
    public function getManDir()
278
    {
279
        return $this->manDir;
280
    }
281
282
    /**
283
     * Sets the directory containing the man pages.
284
     *
285
     * @param string $dir The directory that contains the man pages.
286
     */
287 41
    public function setManDir($dir)
288
    {
289 41
        Assert::directory($dir);
290
291 41
        $this->manDir = $dir;
292 41
    }
293
294
    /**
295
     * Returns the directory containing the AsciiDoc pages.
296
     *
297
     * @return string The directory that contains the AsciiDoc pages.
298
     */
299
    public function getAsciiDocDir()
300
    {
301
        return $this->asciiDocDir;
302
    }
303
304
    /**
305
     * Sets the directory containing the AsciiDoc pages.
306
     *
307
     * @param string $dir The directory that contains the AsciiDoc pages.
308
     */
309 41
    public function setAsciiDocDir($dir)
310
    {
311 41
        Assert::directory($dir);
312
313 41
        $this->asciiDocDir = $dir;
314 41
    }
315
316
    /**
317
     * Returns the name of the file displayed when the application help is
318
     * shown with less/man.
319
     *
320
     * @return string The application page.
321
     */
322
    public function getApplicationPage()
323
    {
324
        return $this->applicationPage;
325
    }
326
327
    /**
328
     * Sets the name of the file displayed when the application help is shown
329
     * with less/man.
330
     *
331
     * @param string $page The application page.
332
     */
333 7 View Code Duplication
    public function setApplicationPage($page)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
334
    {
335 7
        if (null !== $page) {
336 7
            Assert::string($page, 'The application page must be a string or null. Got: %s');
337 7
            Assert::notEmpty($page, 'The application page must not be empty.');
338
        }
339
340 7
        $this->applicationPage = $page;
341 7
    }
342
343
    /**
344
     * Returns the prefix of the files displayed when a command help is shown
345
     * with less/man.
346
     *
347
     * @return string The page prefix.
348
     */
349
    public function getCommandPagePrefix()
350
    {
351
        return $this->commandPagePrefix;
352
    }
353
354
    /**
355
     * Sets the prefix of the files displayed when a command help is shown with
356
     * less/man.
357
     *
358
     * @param string $prefix The page prefix.
359
     */
360 5
    public function setCommandPagePrefix($prefix)
361
    {
362 5
        $this->commandPagePrefix = $prefix;
363 5
    }
364
365 17
    private function getAsciiDocPage(Application $application, Args $args)
366
    {
367 17
        return $this->asciiDocDir.'/'.$this->getPageName($application, $args).'.txt';
368
    }
369
370 22
    private function getManPage(Application $application, Args $args)
371
    {
372 22
        return $this->manDir.'/'.$this->getPageName($application, $args).'.1';
373
    }
374
375 30
    private function getPageName(Application $application, Args $args)
376
    {
377 30
        if ($args->isArgumentSet('command')) {
378 13
            $command = $application->getCommand($args->getArgument('command'));
379
380 13
            return $this->commandPagePrefix.$command->getName();
381
        }
382
383 17
        if ($this->applicationPage) {
384 7
            return $this->applicationPage;
385
        }
386
387 10
        return $application->getConfig()->getName();
388
    }
389
}
390