add Cli\Args\Help
[pharext/pharext] / src / pharext / Cli / Args / Help.php
1 <?php
2
3 namespace pharext\Cli\Args;
4
5 use pharext\Cli\Args;
6
7 class Help
8 {
9 private $args;
10
11 function __construct($prog, Args $args) {
12 $this->prog = $prog;
13 $this->args = $args;
14 }
15
16 function __toString() {
17 $usage = "Usage:\n\n \$ ";
18 $usage .= $this->prog;
19
20 list($flags, $required, $optional) = $this->listSpec();
21 if ($flags) {
22 $usage .= $this->dumpFlags($flags);
23 }
24 if ($required) {
25 $usage .= $this->dumpRequired($required);
26 }
27 if ($optional) {
28 $usage .= $this->dumpOptional($optional);
29 }
30
31 $help = $this->dumpHelp();
32
33 return $usage . "\n\n" . $help . "\n";
34 }
35
36 function listSpec() {
37 $flags = [];
38 $required = [];
39 $optional = [];
40 foreach ($this->args->getSpec() as $spec) {
41 if ($spec[3] & Args::REQARG) {
42 if ($spec[3] & Args::REQUIRED) {
43 $required[] = $spec;
44 } else {
45 $optional[] = $spec;
46 }
47 } else {
48 $flags[] = $spec;
49 }
50 }
51
52 return [$flags, $required, $optional] + compact("flags", "required", "optional");
53 }
54
55 function dumpFlags(array $flags) {
56 return sprintf(" [-%s]", implode("", array_column($flags, 0)));
57 }
58
59 function dumpRequired(array $required) {
60 $dump = "";
61 foreach ($required as $req) {
62 $dump .= sprintf(" -%s <%s>", $req[0], $req[1]);
63 }
64 return $dump;
65 }
66
67 function dumpOptional(array $optional) {
68 return sprintf(" [-%s <arg>]", implode("|-", array_column($optional, 0)));
69 }
70
71 function calcMaxLen() {
72 $spc = $this->args->getSpec();
73 $max = max(array_map("strlen", array_column($spc, 1)));
74 $max += $max % 8 + 2;
75 return $max;
76 }
77
78 function dumpHelp() {
79 $max = $this->calcMaxLen();
80 $dump = "";
81 foreach ($this->args->getSpec() as $spec) {
82 $dump .= " ";
83 if (isset($spec[0])) {
84 $dump .= sprintf("-%s|", $spec[0]);
85 }
86 $dump .= sprintf("--%s ", $spec[1]);
87 if ($spec[3] & Args::REQARG) {
88 $dump .= "<arg> ";
89 } elseif ($spec[3] & Args::OPTARG) {
90 $dump .= "[<arg>]";
91 } else {
92 $dump .= " ";
93 }
94
95 $dump .= str_repeat(" ", $max-strlen($spec[1])+3*!isset($spec[0]));
96 $dump .= $spec[2];
97
98 if ($spec[3] & Args::REQUIRED) {
99 $dump .= " (REQUIRED)";
100 }
101 if (isset($spec[4])) {
102 $dump .= sprintf(" [%s]", $spec[4]);
103 }
104 $dump .= "\n";
105 }
106 return $dump;
107 }
108 }