fix command help text output
[pharext/pharext] / src / pharext / Cli / Args / Help.php
index 19e8cd409910d5433d8e5283020632ee0a317241..907a40d9aeb6959bec53de071034a7a65e556c95 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace pharext\Cli\Args;
 
+use function array_column;
 use pharext\Cli\Args;
 
 class Help
@@ -17,7 +18,7 @@ class Help
                $usage = "Usage:\n\n  \$ ";
                $usage .= $this->prog;
 
-               list($flags, $required, $optional) = $this->listSpec();
+               list($flags, $required, $optional, $positional) = $this->listSpec();
                if ($flags) {
                        $usage .= $this->dumpFlags($flags);
                }
@@ -27,9 +28,12 @@ class Help
                if ($optional) {
                        $usage .= $this->dumpOptional($optional);
                }
+               if ($positional) {
+                       $usage .= $this->dumpPositional($positional);
+               }
+
+               $help = $this->dumpHelp($positional);
 
-               $help = $this->dumpHelp();
-               
                return $usage . "\n\n" . $help . "\n";
        }
 
@@ -37,19 +41,21 @@ class Help
                $flags = [];
                $required = [];
                $optional = [];
+               $positional = [];
                foreach ($this->args->getSpec() as $spec) {
-                       if ($spec[3] & Args::REQARG) {
-                               if ($spec[3] & Args::REQUIRED) {
-                                       $required[] = $spec;
-                               } else {
-                                       $optional[] = $spec;
-                               }
+                       if (is_numeric($spec[0])) {
+                               $positional[] = $spec;
+                       } elseif ($spec[3] & Args::REQUIRED) {
+                               $required[] = $spec;
+                       } elseif ($spec[3] & (Args::OPTARG|Args::REQARG)) {
+                               $optional[] = $spec;
                        } else {
                                $flags[] = $spec;
                        }
                }
 
-               return [$flags, $required, $optional] + compact("flags", "required", "optional");
+               return [$flags, $required, $optional, $positional]
+                       + compact("flags", "required", "optional", "positional");
        }
 
        function dumpFlags(array $flags) {
@@ -65,7 +71,77 @@ class Help
        }
 
        function dumpOptional(array $optional) {
-               return sprintf(" [-%s <arg>]", implode("|-", array_column($optional, 0)));
+               $req = array_filter($optional, function($a) {
+                       return $a[3] & Args::REQARG;
+               });
+               $opt = array_filter($optional, function($a) {
+                       return $a[3] & Args::OPTARG;
+               });
+
+               $dump = "";
+               if ($req) {
+                       $short = array_filter($req, function($a) {
+                               return is_string($a[0]);
+                       });
+                       if ($short) {
+                               $dump .= sprintf(" [-%s <arg>]", implode("|-", array_column($short, 0)));
+                       }
+                       $long = array_filter($req, function($a) {
+                               return !is_string($a[0]);
+                       });
+                       if ($long) {
+                               $dump .= sprintf(" [--%s <arg>]", implode("|--", array_column($long, 1)));
+                       }
+               }
+               if ($opt) {
+                       $short = array_filter($opt, function($a) {
+                               return is_string($a[0]);
+                       });
+                       if ($short) {
+                               $dump .= sprintf(" [-%s [<arg>]]", implode("|-", array_column($short, 0)));
+                       }
+                       $long = array_filter($opt, function($a) {
+                               return !is_string($a[0]);
+                       });
+                       if ($long) {
+                               $dump .= sprintf(" [--%s [<arg>]]", implode("|--", array_column($long, 1)));
+                       }
+               }
+               return $dump;
+       }
+
+       function dumpPositional(array $positional) {
+               $dump = " [--]";
+               $conv = [];
+               foreach ($positional as $pos) {
+                       $conv[$pos[0]][] = $pos;
+               }
+               $opts = [];
+               foreach ($conv as $positional) {
+                       $args = implode("|", array_column($positional, 1));
+                       if ($positional[0][3] & Args::REQUIRED) {
+                               $dump .= sprintf(" <%s>", $args);
+                       } else {
+                               $dump .= sprintf(" [<%s>]", $args);
+                       }
+                       if ($positional[0][3] & Args::MULTI) {
+                               $dump .= sprintf(" [<%s>]...", $args);
+                       }
+                       /*
+                       foreach ($positional as $pos) {
+                               if ($pos[3] & Args::REQUIRED) {
+                                       $dump .= sprintf(" <%s>", $pos[1]);
+                               } else {
+                                       $opts[] = $pos;
+                                       //$dump .= sprintf(" [<%s>]", $pos[1]);
+                               }
+                               if ($pos[3] & Args::MULTI) {
+                                       $dump .= sprintf(" [<%s>]...", $pos[1]);
+                               }
+                       }
+                        */
+               }
+               return $dump;
        }
 
        function calcMaxLen() {
@@ -80,10 +156,14 @@ class Help
                $dump = "";
                foreach ($this->args->getSpec() as $spec) {
                        $dump .= "    ";
-                       if (isset($spec[0])) {
+                       if (is_numeric($spec[0])) {
+                               $dump .= sprintf("  <%s>  ", $spec[1]);
+                       } elseif (isset($spec[0])) {
                                $dump .= sprintf("-%s|", $spec[0]);
                        }
-                       $dump .= sprintf("--%s ", $spec[1]);
+                       if (!is_numeric($spec[0])) {
+                               $dump .= sprintf("--%s ", $spec[1]);
+                       }
                        if ($spec[3] & Args::REQARG) {
                                $dump .= "<arg>  ";
                        } elseif ($spec[3] & Args::OPTARG) {
@@ -92,12 +172,16 @@ class Help
                                $dump .= "       ";
                        }
 
-                       $dump .= str_repeat(" ", $max-strlen($spec[1])+3*!isset($spec[0]));
-                       $dump .= $spec[2];
+                       $space = str_repeat(" ", $max-strlen($spec[1])+3*!isset($spec[0]));
+                       $dump .= $space;
+                       $dump .= str_replace("\n", "\n                        $space", $spec[2]);
 
                        if ($spec[3] & Args::REQUIRED) {
                                $dump .= " (REQUIRED)";
                        }
+                       if ($spec[3] & Args::MULTI) {
+                               $dump .= " (MULTIPLE)";
+                       }
                        if (isset($spec[4])) {
                                $dump .= sprintf(" [%s]", $spec[4]);
                        }