6ad2c806b4a4ccabe3602f1b5ed8c836e5ca6423
[pharext/pharext] / src / pharext / Cli / Command.php
1 <?php
2
3 namespace pharext\Cli;
4
5 use pharext\Cli\Args as CliArgs;
6
7 use Phar;
8
9 if (!function_exists("array_column")) {
10 function array_column(array $array, $col, $idx = null) {
11 $result = [];
12 foreach ($array as $el) {
13 if (isset($idx)) {
14 $result[$el[$idx]] = $el[$col];
15 } else {
16 $result[] = $el[$col];
17 }
18 }
19 return $result;
20 }
21 }
22
23 trait Command
24 {
25 /**
26 * Command line arguments
27 * @var pharext\CliArgs
28 */
29 private $args;
30
31 /**
32 * @inheritdoc
33 * @see \pharext\Command::getArgs()
34 */
35 public function getArgs() {
36 return $this->args;
37 }
38
39 /**
40 * Retrieve metadata of the currently running phar
41 * @param string $key
42 * @return mixed
43 */
44 public function metadata($key = null) {
45 $running = new Phar(Phar::running(false));
46
47 if ($key === "signature") {
48 $sig = $running->getSignature();
49 return sprintf("%s signature of %s\n%s",
50 $sig["hash_type"],
51 $this->metadata("name"),
52 chunk_split($sig["hash"], 64, "\n"));
53 }
54
55 $metadata = $running->getMetadata();
56 if (isset($key)) {
57 return $metadata[$key];
58 }
59 return $metadata;
60 }
61
62 /**
63 * Output pharext vX.Y.Z header
64 */
65 public function header() {
66 if (!headers_sent()) {
67 /* only display header, if we didn't generate any output yet */
68 printf("%s\n\n", $this->metadata("header"));
69 }
70 }
71
72 /**
73 * @inheritdoc
74 * @see \pharext\Command::debug()
75 */
76 public function debug($fmt) {
77 if ($this->args->verbose) {
78 vprintf($fmt, array_slice(func_get_args(), 1));
79 }
80 }
81
82 /**
83 * @inheritdoc
84 * @see \pharext\Command::info()
85 */
86 public function info($fmt) {
87 if (!$this->args->quiet) {
88 vprintf($fmt, array_slice(func_get_args(), 1));
89 }
90 }
91
92 /**
93 * @inheritdoc
94 * @see \pharext\Command::warn()
95 */
96 public function warn($fmt) {
97 if (!$this->args->quiet) {
98 if (!isset($fmt)) {
99 $fmt = "%s\n";
100 $arg = error_get_last()["message"];
101 } else {
102 $arg = array_slice(func_get_args(), 1);
103 }
104 vfprintf(STDERR, "Warning: $fmt", $arg);
105 }
106 }
107
108 /**
109 * @inheritdoc
110 * @see \pharext\Command::error()
111 */
112 public function error($fmt) {
113 if (!isset($fmt)) {
114 $fmt = "%s\n";
115 $arg = error_get_last()["message"];
116 } else {
117 $arg = array_slice(func_get_args(), 1);
118 }
119 vfprintf(STDERR, "ERROR: $fmt", $arg);
120 }
121
122 /**
123 * Output command line help message
124 * @param string $prog
125 */
126 public function help($prog) {
127 printf("Usage:\n\n \$ %s", $prog);
128
129 $flags = [];
130 $required = [];
131 $optional = [];
132 foreach ($this->args->getSpec() as $spec) {
133 if ($spec[3] & CliArgs::REQARG) {
134 if ($spec[3] & CliArgs::REQUIRED) {
135 $required[] = $spec;
136 } else {
137 $optional[] = $spec;
138 }
139 } else {
140 $flags[] = $spec;
141 }
142 }
143
144 if ($flags) {
145 printf(" [-%s]", implode("", array_column($flags, 0)));
146 }
147 foreach ($required as $req) {
148 printf(" -%s <arg>", $req[0]);
149 }
150 if ($optional) {
151 printf(" [-%s <arg>]", implode("|-", array_column($optional, 0)));
152 }
153 printf("\n\n");
154 $spc = $this->args->getSpec();
155 $max = max(array_map("strlen", array_column($spc, 1)));
156 $max += $max % 8 + 2;
157 foreach ($spc as $spec) {
158 if (isset($spec[0])) {
159 printf(" -%s|", $spec[0]);
160 } else {
161 printf(" ");
162 }
163 printf("--%s ", $spec[1]);
164 if ($spec[3] & CliArgs::REQARG) {
165 printf("<arg> ");
166 } elseif ($spec[3] & CliArgs::OPTARG) {
167 printf("[<arg>]");
168 } else {
169 printf(" ");
170 }
171 printf("%s%s", str_repeat(" ", $max-strlen($spec[1])+3*!isset($spec[0])), $spec[2]);
172 if ($spec[3] & CliArgs::REQUIRED) {
173 printf(" (REQUIRED)");
174 }
175 if (isset($spec[4])) {
176 printf(" [%s]", $spec[4]);
177 }
178 printf("\n");
179 }
180 printf("\n");
181 }
182
183 /**
184 * Verbosity
185 * @return boolean
186 */
187 public function verbosity() {
188 if ($this->args->verbose) {
189 return true;
190 } elseif ($this->args->quiet) {
191 return false;
192 } else {
193 return null;
194 }
195 }
196 }