Completed
Push — master ( ea055a...aafc8c )
by Jitendra
17s
created

OutputHelper::label()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 8
nop 1
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Ahc\Cli\Helper;
4
5
use Ahc\Cli\Input\Argument;
6
use Ahc\Cli\Input\Command;
7
use Ahc\Cli\Input\Option;
8
use Ahc\Cli\Input\Parameter;
9
use Ahc\Cli\Output\Writer;
10
11
/**
12
 * This helper helps you by showing you help information :).
13
 *
14
 * @author  Jitendra Adhikari <[email protected]>
15
 * @license MIT
16
 *
17
 * @link    https://github.com/adhocore/cli
18
 */
19
class OutputHelper
20
{
21
    /** @var Writer */
22
    protected $writer;
23
24
    public function __construct(Writer $writer = null)
25
    {
26
        $this->writer = $writer ?? new Writer;
27
    }
28
29
    /**
30
     * @param Argument[] $arguments
31
     * @param string     $header
32
     * @param string     $footer
33
     *
34
     * @return self
35
     */
36
    public function showArgumentsHelp(array $arguments, string $header = '', string $footer = ''): self
37
    {
38
        $this->showHelp('Arguments', $arguments, $header, $footer);
39
40
        return $this;
41
    }
42
43
    /**
44
     * @param Option[] $options
45
     * @param string   $header
46
     * @param string   $footer
47
     *
48
     * @return self
49
     */
50
    public function showOptionsHelp(array $options, string $header = '', string $footer = ''): self
51
    {
52
        $this->showHelp('Options', $options, $header, $footer);
53
54
        return $this;
55
    }
56
57
    /**
58
     * @param Command[] $commands
59
     * @param string    $header
60
     * @param string    $footer
61
     *
62
     * @return self
63
     */
64
    public function showCommandsHelp(array $commands, string $header = '', string $footer = ''): self
65
    {
66
        $this->showHelp('Commands', $commands, $header, $footer);
67
68
        return $this;
69
    }
70
71
    /**
72
     * Show help with headers and footers.
73
     *
74
     * @param string $for
75
     * @param array  $items
76
     * @param string $header
77
     * @param string $footer
78
     *
79
     * @return void
80
     */
81
    protected function showHelp(string $for, array $items, string $header = '', string $footer = '')
82
    {
83
        if ($header) {
84
            $this->writer->bold($header, true);
85
        }
86
87
        $this->writer->eol()->boldGreen($for . ':', true);
88
89
        if (empty($items)) {
90
            $this->writer->bold('  (n/a)', true);
91
92
            return;
93
        }
94
95
        $space = 4;
96
        foreach ($this->sortItems($items, $padLen) as $item) {
97
            $name = $this->getName($item);
98
            $this->writer->bold('  ' . \str_pad($name, $padLen + $space));
99
            $this->writer->comment($item->desc(), true);
100
        }
101
102
        if ($footer) {
103
            $this->writer->eol()->yellow($footer, true);
104
        }
105
    }
106
107
    /**
108
     * Sort items by name. As a side effect sets max length of all names.
109
     *
110
     * @param Parameter[]|Command[] $items
111
     * @param int                   $max
112
     *
113
     * @return array
114
     */
115
    protected function sortItems(array $items, &$max = 0): array
116
    {
117
        $first = reset($items);
118
        $max   = \strlen($first->name());
119
120
        \uasort($items, function ($a, $b) use (&$max) {
121
            /** @var Parameter $b */
122
            /** @var Parameter $a */
123
            $max = \max(\strlen($this->getName($a)), \strlen($this->getName($b)), $max);
124
125
            return $a->name() <=> $b->name();
126
        });
127
128
        return $items;
129
    }
130
131
    /**
132
     * Prepare name for different items.
133
     *
134
     * @param Parameter|Command $item
135
     *
136
     * @return string
137
     */
138
    protected function getName($item): string
139
    {
140
        $name = $item->name();
141
142
        if ($item instanceof Command) {
143
            return \trim($item->alias() . '|' . $name, '|');
144
        }
145
146
        return $this->label($item);
147
    }
148
149
    /**
150
     * Get parameter label for humans.
151
     *
152
     * @param Parameter $item
153
     *
154
     * @return string
155
     */
156
    protected function label(Parameter $item)
157
    {
158
        $name = $item->name();
159
160
        if ($item instanceof Option) {
161
            $name = $item->short() . '|' . $item->long();
162
        }
163
164
        $variad = $item->variadic() ? '...' : '';
165
166
        if ($item->required()) {
167
            return "<$name$variad>";
168
        }
169
170
        return "[$name$variad]";
171
    }
172
}
173