From 6d771ed88f788c8b0302534185aa99e4ae5155be Mon Sep 17 00:00:00 2001
From: Dave Mc Nicoll <dave.mcnicoll@cslsj.qc.ca>
Date: Mon, 11 Nov 2024 20:20:51 +0000
Subject: [PATCH] - WIP on CLI works

---
 src/CliMiddleware.php      | 15 ++++++++-------
 src/CliRequest.php         |  2 --
 src/Command.php            |  1 -
 src/CommandStack.php       | 21 ++++++++++++++++-----
 src/Lib/AsciiFormatter.php |  2 +-
 src/Option.php             |  1 -
 6 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/src/CliMiddleware.php b/src/CliMiddleware.php
index b4a5f59..2ea7109 100644
--- a/src/CliMiddleware.php
+++ b/src/CliMiddleware.php
@@ -48,14 +48,15 @@ class CliMiddleware implements MiddlewareInterface
 
             $cliRequest = new CliRequest($request);
 
-            # $cliRequest->setOptions($commands->getOptions());
-
-            if ( $command = $this->commands->matchCommand($cliRequest->command, $cliRequest->options) ) {
+            if ( $command = $this->commands->matchCommand($cliRequest->command) ) {
                 if ($command->callback) {
                     if (is_string($command->callback)) {
                         list($class, $method) = explode('::', $command->callback);
 
-                        return $this->container->make($class)->{$method}($request->withAttribute('cli.command', $command)->withAttribute('cli.request', $cliRequest), []);
+                        $request = $request->withAttribute('cli.command', $command)
+                            ->withAttribute('cli.request', $cliRequest);
+                        
+                        return $this->container->make($class)->{$method}($request, []);
                     }
                 }
                 else {
@@ -80,11 +81,11 @@ class CliMiddleware implements MiddlewareInterface
     {
         $text = [
             $command->description, "",
-            "Usage:",
+            "#[color: rgb(145;130;195), format: bold]Usage:[#]",
             "  command [options] [arguments]", "",
-            "Options:",
+            "#[color: rgb(145;130;195), format: bold]Options:[#]",
             "  OPTIONS HERE", "",
-            "Available commands:",
+            "#[color: rgb(145;130;195), format: bold]Available commands:[#]",
             "  COMMANDS HERE", "",
         ];
 
diff --git a/src/CliRequest.php b/src/CliRequest.php
index 5528658..ef84475 100644
--- a/src/CliRequest.php
+++ b/src/CliRequest.php
@@ -47,8 +47,6 @@ class CliRequest
             $this->command[] = $cmd;
         }
 
-        dump($executionString);
-
         $this->command = $executionString;
     }
 
diff --git a/src/Command.php b/src/Command.php
index 2340a26..3f4905f 100644
--- a/src/Command.php
+++ b/src/Command.php
@@ -2,7 +2,6 @@
 
 namespace Mcnd\CLI;
 
-#[\Attribute]
 class Command
 {
     public function __construct(
diff --git a/src/CommandStack.php b/src/CommandStack.php
index 9f4d6a0..4bfb14b 100644
--- a/src/CommandStack.php
+++ b/src/CommandStack.php
@@ -19,14 +19,25 @@ class CommandStack
         $this->commands[] = $command;
     }
 
-    public function matchCommand(array $commands, array $options) : null|Command
+    /**
+     * Matches the closest command found from the stack
+     *
+     * @param array $commands
+     * @param array $options
+     * @return Command|null
+     */
+    public function matchCommand(array $commands) : null|Command
     {
-        $cmd = implode(' ', $commands);
+        while ($commands) {
+            $cmd = implode(' ', $commands);
 
-        foreach($this->commands as $command) {
-            if ($command->name === $cmd) {
-                return $command;
+            foreach ($this->commands as $command) {
+                if ($command->name === $cmd) {
+                    return $command;
+                }
             }
+
+            array_pop($commands);
         }
 
         return null;
diff --git a/src/Lib/AsciiFormatter.php b/src/Lib/AsciiFormatter.php
index 1a0d1f9..151c15a 100644
--- a/src/Lib/AsciiFormatter.php
+++ b/src/Lib/AsciiFormatter.php
@@ -53,7 +53,7 @@ class AsciiFormatter
                 );
             }
 
-            list($scope, $value) = explode(':', $formatting, 2);
+            list($scope, $value) = array_map('trim', explode(':', $formatting, 2));
 
             switch($scope) {
                 case 'color':
diff --git a/src/Option.php b/src/Option.php
index 7f8ce8c..7020b3d 100644
--- a/src/Option.php
+++ b/src/Option.php
@@ -2,7 +2,6 @@
 
 namespace Mcnd\CLI;
 
-#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS)]
 class Option
 {
     public const ARGUMENT_NONE = 0;