44
55use Lkrms \Cli \Catalog \CliHelpSectionName ;
66use Lkrms \Cli \Catalog \CliHelpTarget ;
7- use Lkrms \Cli \Contract \ICliApplication ;
7+ use Lkrms \Cli \Contract \CliApplicationInterface ;
8+ use Lkrms \Cli \Contract \CliCommandInterface ;
89use Lkrms \Cli \Exception \CliInvalidArgumentsException ;
9- use Lkrms \Cli \Support \CliHelpStyle ;
1010use Lkrms \Console \Support \ConsoleManPageFormat ;
1111use Lkrms \Console \Support \ConsoleMarkdownFormat ;
1212use Lkrms \Console \ConsoleFormatter as Formatter ;
1313use Lkrms \Container \Application ;
14+ use Lkrms \Contract \HasJsonSchema ;
1415use Lkrms \Facade \Console ;
1516use Lkrms \Utility \Catalog \EnvFlag ;
1617use Lkrms \Utility \Arr ;
2627/**
2728 * A service container for CLI applications
2829 */
29- class CliApplication extends Application implements ICliApplication
30+ class CliApplication extends Application implements CliApplicationInterface
3031{
3132 private const COMMAND_REGEX = '/^[a-z][a-z0-9_-]*$/iD ' ;
3233
3334 /**
34- * @var array<string,class-string<CliCommand >|mixed[]>
35+ * @var array<string,class-string<CliCommandInterface >|mixed[]>
3536 */
3637 private $ CommandTree = [];
3738
38- private ?CliCommand $ RunningCommand = null ;
39+ private ?CliCommandInterface $ RunningCommand = null ;
3940
40- private ?CliCommand $ LastCommand = null ;
41+ private ?CliCommandInterface $ LastCommand = null ;
4142
4243 private int $ LastExitStatus = 0 ;
4344
@@ -69,15 +70,15 @@ public function __construct(
6970 /**
7071 * @inheritDoc
7172 */
72- public function getRunningCommand (): ?CliCommand
73+ public function getRunningCommand (): ?CliCommandInterface
7374 {
7475 return $ this ->RunningCommand ;
7576 }
7677
7778 /**
7879 * @inheritDoc
7980 */
80- public function getLastCommand (): ?CliCommand
81+ public function getLastCommand (): ?CliCommandInterface
8182 {
8283 return $ this ->LastCommand ;
8384 }
@@ -91,23 +92,26 @@ public function getLastExitStatus(): int
9192 }
9293
9394 /**
94- * Get a CliCommand instance from the given node in the command tree
95+ * Get a command instance from the given node in the command tree
9596 *
9697 * Returns `null` if no command is registered at the given node.
9798 *
98- * @internal
9999 * @param string $name The name of the node as a space-delimited list of
100100 * subcommands.
101- * @param array<string,class-string<CliCommand >|mixed[]>|class-string<CliCommand >|false|null $node The node as returned by {@see CliApplication::getNode()}.
101+ * @param array<string,class-string<CliCommandInterface >|mixed[]>|class-string<CliCommandInterface >|false|null $node The node as returned by {@see CliApplication::getNode()}.
102102 */
103- protected function getNodeCommand (string $ name , $ node ): ?CliCommand
103+ protected function getNodeCommand (string $ name , $ node ): ?CliCommandInterface
104104 {
105105 if (!is_string ($ node )) {
106106 return null ;
107107 }
108108
109- if (!(($ command = $ this ->get ($ node )) instanceof CliCommand)) {
110- throw new LogicException ("Not a subclass of CliCommand: $ node " );
109+ if (!(($ command = $ this ->get ($ node )) instanceof CliCommandInterface)) {
110+ throw new LogicException (sprintf (
111+ 'Does not implement %s: %s ' ,
112+ CliCommandInterface::class,
113+ $ node ,
114+ ));
111115 }
112116 $ command ->setName ($ name ? explode (' ' , $ name ) : []);
113117
@@ -119,18 +123,17 @@ protected function getNodeCommand(string $name, $node): ?CliCommand
119123 *
120124 * Returns one of the following:
121125 * - `null` if nothing has been added to the tree at `$name`
122- * - the name of the {@see CliCommand } class registered at `$name`
126+ * - the name of the {@see CliCommandInterface } class registered at `$name`
123127 * - an array that maps subcommands of `$name` to their respective nodes
124- * - `false` if a {@see CliCommand } has been registered above `$name`, e.g.
125- * if `$name` is `["sync", "canvas", "from-sis"]` and a command has been
126- * registered at `["sync", "canvas"]`
128+ * - `false` if a {@see CliCommandInterface } has been registered above
129+ * `$name`, e.g. if `$name` is `["sync", "canvas", "from-sis"]` and a
130+ * command has been registered at `["sync", "canvas"]`
127131 *
128132 * Nodes in the command tree are either subcommand arrays (branches) or
129- * {@see CliCommand } class names (leaves).
133+ * {@see CliCommandInterface } class names (leaves).
130134 *
131- * @internal
132135 * @param string[] $name
133- * @return array<string,class-string<CliCommand >|mixed[]>|class-string<CliCommand >|false|null
136+ * @return array<string,class-string<CliCommandInterface >|mixed[]>|class-string<CliCommandInterface >|false|null
134137 */
135138 protected function getNode (array $ name = [])
136139 {
@@ -199,11 +202,11 @@ public function command(array $name, string $id)
199202 /**
200203 * Get a help message for a command tree node
201204 *
202- * @param array<string,class-string<CliCommand >|mixed[]>|class-string<CliCommand > $node
205+ * @param array<string,class-string<CliCommandInterface >|mixed[]>|class-string<CliCommandInterface > $node
203206 */
204207 private function getHelp (string $ name , $ node , ?CliHelpStyle $ style = null ): ?string
205208 {
206- $ style ??= new CliHelpStyle (CliHelpTarget::TTY );
209+ $ style ??= new CliHelpStyle (CliHelpTarget::NORMAL );
207210
208211 $ command = $ this ->getNodeCommand ($ name , $ node );
209212 if ($ command ) {
@@ -236,7 +239,7 @@ private function getHelp(string $name, $node, ?CliHelpStyle $style = null): ?str
236239 /**
237240 * Get usage information for a command tree node
238241 *
239- * @param array<string,class-string<CliCommand >|mixed[]>|class-string<CliCommand > $node
242+ * @param array<string,class-string<CliCommandInterface >|mixed[]>|class-string<CliCommandInterface > $node
240243 */
241244 private function getUsage (string $ name , $ node ): ?string
242245 {
@@ -378,8 +381,11 @@ public function run()
378381
379382 if ($ args && $ args [0 ] === '_json_schema ' ) {
380383 array_shift ($ args );
381- $ schema = $ command ->getJsonSchema ($ args [0 ] ?? trim ($ this ->getProgramName () . " $ name " ) . ' options ' );
382- echo Json::prettyPrint ($ schema ) . \PHP_EOL ;
384+ $ schema = $ command ->getJsonSchema ();
385+ echo Json::prettyPrint ([
386+ '$schema ' => $ schema ['$schema ' ] ?? HasJsonSchema::DRAFT_04_SCHEMA_ID ,
387+ 'title ' => $ args [0 ] ?? $ schema ['title ' ] ?? trim ($ this ->getProgramName () . " $ name " ) . ' options ' ,
388+ ] + $ schema ) . \PHP_EOL ;
383389 return $ this ;
384390 }
385391
@@ -425,7 +431,7 @@ public function runAndExit()
425431 }
426432
427433 /**
428- * @param array<string,class-string<CliCommand >|mixed[]>|class-string<CliCommand > $node
434+ * @param array<string,class-string<CliCommandInterface >|mixed[]>|class-string<CliCommandInterface > $node
429435 * @param int&CliHelpTarget::* $target
430436 */
431437 private function generateHelp (string $ name , $ node , int $ target , string ...$ args ): void
0 commit comments