Passed
Push — master ( 62679a...2b0c72 )
by Gerard van
07:11
created

TextDescriptor::getColumnWidth()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 0
cts 5
cp 0
rs 9.6666
cc 3
eloc 5
nc 3
nop 1
crap 12
1
<?php
2
namespace Zicht\Tool\Command\Descriptor;
3
4
use Symfony\Component\Console\Application;
5
use Symfony\Component\Console\Command\Command;
6
use Symfony\Component\Console\Input\InputDefinition;
7
use Symfony\Component\Console\Input\InputOption;
8
use Symfony\Component\Console\Descriptor\TextDescriptor as BaseDescriptor;
9
use Symfony\Component\Console\Descriptor\ApplicationDescription;
10
11
/**
12
 */
13
class TextDescriptor extends BaseDescriptor
14
{
15
    /**
16
     * @param \Symfony\Component\Console\Input\InputOption $option
17
     * @return bool
18
     */
19 9
    public function isHiddenOption(InputOption $option)
20
    {
21 9
        return in_array(
22 9
            $option->getName(),
23 9
            array('help', 'version', 'verbose', 'quiet', 'explain', 'force', 'plugin', 'debug')
24 9
        );
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30 1
    protected function describeCommand(Command $command, array $options = array())
31
    {
32
        list($public, $internal) = $this->splitDefinition($command->getNativeDefinition());
33
34
        $synopsis = new Command($command->getName());
35
        $synopsis->setDefinition($public);
36
37
        $this->writeText('<comment>Usage:</comment>', $options);
38
        $this->writeText("\n");
39
        $this->writeText(' ' . $synopsis->getSynopsis(), $options);
40
        $this->writeText("\n");
41
42
        if (count($command->getAliases()) > 0) {
43
            $this->writeText("\n");
44
            $this->writeText('<comment>Aliases:</comment> <info>' . implode(', ', $command->getAliases()) . '</info>', $options);
45
        }
46
47
        $this->writeText("\n");
48 1
        $this->describeInputDefinition($public, $options);
49
        if (count($internal->getOptions())) {
50
            $this->writeText("\n\n" . '<comment>Global options:</comment>' . "\n");
51
            $this->writeText(' Following global options are available for all task commands:');
52
            $this->writeText(' ' . join(', ', array_map(function ($o) { return $o->getName(); }, $internal->getOptions())));
53
            $this->writeText(' Read the application help for more info' . "\n");
54
        }
55
        $this->writeText("\n");
56
57
        if ($help = $command->getProcessedHelp()) {
58
            $this->writeText('<comment>Help:</comment>', $options);
59
            $this->writeText("\n");
60
            $this->writeText(' ' . str_replace("\n", "\n ", $help), $options);
61
            $this->writeText("\n");
62
        }
63
64
        $this->writeText("\n");
65
    }
66
67
    /**
68
     * Splits the definition in an internal and public one, the latter representing whatever is shown to the user,
69
     * the former representing the options that are hidden.
70
     *
71
     * @param \Symfony\Component\Console\Input\InputDefinition $definition
72
     * @return InputDefinition[]
73
     */
74
    public function splitDefinition(InputDefinition $definition)
75
    {
76
        /** @var InputDefinition[] $ret */
77
        $ret = array(
78
            new InputDefinition(),
79
            new InputDefinition()
80
        );
81
82
        foreach ($definition->getArguments() as $arg) {
83
            $ret[0]->addArgument($arg);
84
            $ret[1]->addArgument($arg);
85
        }
86
        foreach ($definition->getOptions() as $opt) {
87
            $ret[$this->isHiddenOption($opt) ? 1 : 0]->addOption($opt);
88
        }
89
        return $ret;
90
    }
91
92
93
    /**
94
     * @param \Symfony\Component\Console\Application $application
95
     * @param array $options
96
     */
97
    protected function describeApplication(Application $application, array $options = array())
98
    {
99
        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
100
        $description = new ApplicationDescription($application, $describedNamespace);
101
102
        $width = $this->getColumnWidth($description->getCommands());
103
104
        $this->writeText($application->getHelp(), $options);
105
        $this->writeText("\n\n");
106
107
        if ($describedNamespace) {
108
            $this->writeText(sprintf("<comment>Available commands for the \"%s\" namespace:</comment>", $describedNamespace), $options);
109
        } else {
110
            $this->writeText('<comment>Available commands:</comment>', $options);
111
        }
112
113
        // add commands by namespace
114
        foreach ($description->getNamespaces() as $namespace) {
115
            if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
116
                $this->writeText("\n");
117
                $this->writeText('<comment>' . $namespace['id'] . '</comment>', $options);
118
            }
119
120
            foreach ($namespace['commands'] as $name) {
121
                $this->writeText("\n");
122
                $this->writeText(sprintf("  <info>%-${width}s</info> %s", $name, $description->getCommand($name)->getDescription()), $options);
123
            }
124
        }
125
126
        $this->writeText("\n");
127
    }
128
129
    /**
130
     * Because for some inapparent reason, the parent's implementation is private.
131
     *
132
     * @param string $content
133
     * @param array $options
134
     */
135
    private function writeText($content, array $options = array())
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
136
    {
137
        $this->write(
138
            isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
139
            isset($options['raw_output']) ? !$options['raw_output'] : true
140
        );
141
    }
142
143
    /**
144
     * Because for some inapparent reason, the parent's implementation is private.
145
     */
146
    private function getColumnWidth(array $commands)
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
147
    {
148
        $width = 0;
149
        foreach ($commands as $command) {
150
            $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
151
        }
152
153
        return $width + 2;
154
    }
155
}