Spoova 2.6 Cli
Command line is a powerful tool that helps to run useful commands that make it easier to relate with project files. The spoova Cli was introduced into the framework to assist in setting up configurations and generating useful files. In the earlier version of the framework, extending to the Cli class is much more difficult and not organized. The main reason for this is that spoova does not render any form of management structure for commands. In version 2.6, a new template management structure has been added to help developer create and execute their own shell commands. This managment structure involves the setting of command line directory, command line options and controller methods. In this manner, spoova is able to validate options and make it easier to set up console descriptions, command syntaxes and command operators. The documentaion below provides a guide to this new feature.

Setting up Commands Directory
The default directory for running all spoova custom commands is the commands directory. This directory can be customized from the init configuration file by setting the argument CONSOLE_DIRECTORY to the name of the directory perferred. The init file will look as shown below:
  CONSOLE_DIRECTORY: my_directory
                                
While many directories are allowed, certain directories are reserved. These directories are the core, icore, windows, res and vendor directories. These are also the default directories that come with the framework. In this documentation, we are going to use the default directory name which is commands directory.

Setting up custom mi commands
The setting up of custom mi command is based on three main directives. These directives provide a meaning for command controller files and they determine what kind of response is needed and how best to display them. The custom root commands are cat::, cati::, catdx and catd:: directives. The following describes what each directive does within the console template management structure

cat:: This function is mostly used to call a method that is associated with a command or to execute commands
cati:: This function provides a descriptive information about the purpose of command
catx:: This function provides details only about the syntax of a command. These helps users to understand the structure of a command
catd:: This function provides a collective detail of both cati:: and catx:: as one single information. It is also designed to display options available for a command.

Each of the directives above are applied on a root command controller file required to process commands. The value that follows immediately after any of the directives is the controller class name. For example, assuming we have a class Version that exists within the commands directory, we can easily call this file by running the command below:
 php mi cat::version
                                
The command above will call the Version class and try to run any available commands. Similary, each directive can be used this way and they will try to excute the type of function they perform. The usage of these directives will be further explained later.

Setting up custom command file
The setting up of custom a command file requires certain key steps and configurations. The major configurations are based on number of arguments required, arguments required, argument options, argument descriptions and argument syntaxes. The spoova Cli system uses these basic determinants to set up a command-template structure that helps to manage options in terms of validating and processing command-line options. The sample command controller file will be used to further explain these structure

Simple Controller File
 <?php 

 namespace spoova\mi\commands;

 class Version {

    function __construct($args) {

        print_r($args);

    }

 }
                                
The sample controller file above is a simple controller file. This file has no basic extension to the root Consoler class. This structure is one which specifies that the entry point for all cat directives is the __construct() method where the arguments are parsed. Assuming we run the command below:
 php mi cat::version
                                
The command will call the __construct() method and instantiate the Version controller class. This format is only used when all arguments are expected to be managed by the developer. This method does not employ any template structure in any way or form.
Extended Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler {

    protected static $auto = false;

    function arguments($args) {

        print_r($args);

    }

 }
                                
The sample controller file above is an extened controller file. This file has a basic extension to the root Consoler class. This structure is one which specifies that the entry point for all cat directives is the arguments method. Assuming we run the command below:
 php mi cat::version
                                
By default, the arguments() method is the entry point through which all arguments are obtained. This method can be customized to use any desired method instead. This will be discussed later.
Extended Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{


 }
                                
The sample above is the standard way to allow the Consoler engine to render options and arguments supplied. Notice that the $auto property is not set as false. Once we have extended the controller class to the Consoler root engine, we can proceed set up a template structure for the command-line.

Setting up template architecture
The setting up of custom template structure is done within a single array pattern. This array pattern defines arguments, options, syntaxes and option description which are later rendered on the console terminal. This option is usually defined by the setOps() method. The sample file below is a simple template structure for processing arguments.

Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{

    public static function setOps() : array {

        return [
            
            'show' => [
                'version' => 'appversion',
                'appname' => 'appname',
            ] 
            
        ];

    }

    function appversion($args) {
        print_r($args); //appversion
    }

    function appname($args) {
        print_r($args); //appname
    }

 }
                                
The options above follows a defined pattern. In the sample above, the first argument allowed is the show which has a list of options version and appname. With this strucuture, we can easily run a command below:
  php mi cat::version show
                                
This command will tell us that the argument show has a list of options which are version and appname We can proceed further to call any of the two options. A sample of this is shown below:
  php mi cat::version show version
                                
The sample command will automatically detect that version does not have an option. Once this is detected, it will go on to call the relative method assigned to the command which is appversion(). In a situation where a method is called in this format, the last option will be supplied as argument. Hence, the command line will print "appversion" as the argument supplied. The argument flow resembles the pattern below:
  Version => show => version => appversion() 
                                
Similarly, for the appname, the structure will resemble the format below
  Version => show => appname => appname() 
                                
From these structures, we would have easily guessed how the command syntax looks like. This provides a more meaningful relationship between console commands and their controller files. Similarly to the show command we can set up more arguments using similar pattern.

Setting up architectural description
Descriptions are mostly useful for explaining the purpose of a function to help users identify what such commands do. Descriptions can be defined for any of the arguments defined above using a closure function. Example of this is shown below:

Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{

    public static function setOps() : array {

        return [
            
            'show' => [
                
                'version' => 'appversion',
                'appname' => 'appname',

                fn() => [
                    'version' => 'shows app version',
                    'appname' => 'shows app name'
                    ]

                ] 
            
            ],

            fn() => [
                'show' => 'shows specific app details'
            ]

    }

    function appversion($args) {
        print_r($args); //appversion
    }

    function appname($args) {
        print_r($args); //appname
    }

 }
                                
In the sample above, notice that the closure function is defined in the same level along with the arguments. Once this is done, we can easily get the description of any argument by running either cati:: or catd:: command. The cati:: returns only the description while the catd:: gives a more detailed explanation of the command based on the level of information defined. From the above, we can easily get the description of any argument by running the command below:
  php mi cati::version show //Info: shows specific app details
                                
  php mi cati::version show appversion //Info: shows app version
                                
  php mi cati::version show appname //Info: shows app name
                                
As seen above, each argument will return its description defined. If no description was found, the response will be as shown below:
  Desc: no description found for this command
                                
In the situation where catd:: was run instead, the description returned will include syntaxes and argument options if they exist.

Setting up descriptive syntaxes
Syntaxes are helper descriptions that provide a short detail on how commands are applied making it easier to remember how to define each arguments of console. By default the closure function returns the description of any command. However, in cases where syntaxes are requires, rather than returning a string, we need to return an array. This array should have two keys which are optional. The key "i" refers to the main description. This is the key that anchors the previous default description. The second argument description "x" refers to the argument syntax. A sample format is shown below:

Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{

    public static function setOps() : array {

        return [

            'show' => [
                'version' => 'appversion',
                'appname' => 'appname',

                fn() => [
                    'version' => 'shows app version';
                    'appname' => 'shows app name'
                ]
            ],

            fn() => [
                'show' => 
                    [
                      'i'=> 'shows specific app details',
                      'x'=> 'show version {options}'
                    ],
            ]
        ];

    }

    function appversion($args) {
        print_r($args); //appversion
    }

    function appname($args) {
        print_r($args); //appname
    }

 }
                                
In the sample above, the array returned by the closure helps to provide more description fo the command. The "i" will now provide the argument's information when cati:: is executed while catx:: command will return the syntax of the command only if it exists. The sample below resembles the response obtained for catx::
  php mi catx::version show // show version {options}
                                
If the syntax is not provided, the command line will respond as shown below:
  syntax: no available syntax for these command.
                                
In this manner, the Consoler class makes it easier to set up arguments using structures that are easily maintainable. In order to remove visual noise, it may be better to defined the setOps() method at the foot of the class.

Obtaining arguments
In the previous headings, we have seen how to set up, control and manage argument's flow within the terminal. There are however, situations where we need to obtain arguments rather than calling a method probably for cases where those arguments may be further used to set up configurations or perform some other functionalities. The Consoler supports the obtaining of arguments by defining an ellipses ... rather than a method. This will tell the Consoler engine that the argument only allows input options. The ellipses is a continuity sign and it is sometimes used to denote arguments. The sample below is how to set up arguments that allows inputs.

Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{

    public static function setOps() : array {

        return [
            
            'show' => [
                
                'version' => 'appversion',
                'appname' => '...',

                fn() => [
                    'version' => 'shows app version',
                    'appname' => 'shows app name'
                ] 
            
            ],

            fn() => [
                'show' => 'shows specific app details'
            ]
        ];

    }

    function appversion($args) {
        print_r($args); //appversion
    }

    function appname($args) {
        print_r($args); //['some','more,'arguments']
    }

 }
                                
In the sample above assuming the command below is executed:
  php mi cat::version show appname some more arguments
                                
In the above command, the some more arguments will not execute as a code. Rather, they will be parsed as array arguments to the appname() method. This is because of the effect of the ellipses ... directive. The response obtained will resemble the format below:
  ['some','more','arguments']
                                

Setting arguments limit
Usually, in certain cases, we may require to set up a maximum or minimum number of arguments that a particular command can contain. This is usually done at the top level of the controller file by setting the $args_max or $args_min property. This will enforce the Controller file to set a maximum or minimum number of arguments allowed. Once the arguments supplied that does not pass this limitation, the controller file will throw a shutdown error. In general, all custom commands are allocated a maximum of 50 commands and a minimum of Zero(0) commands. However, this can be further streamlined using the predefined property. The sample below shows is an example of how to set the the maximum and minimum number of arguments.

Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{

    public static $args_min = 1; //set a minimum of 1 arguments
    
    public static $args_max = 5; //set a maximum of 5 arguments
    
    function appversion($args) {
        print_r($args); //appversion
    }

    function appname($args) {
        print_r($args); //appname
    }

    public static function setOps() : array {

        return [
            
            'show' => [
                'version' => 'appversion',
                'appname' => 'appname',

                fn() => [
                    'version' => 'shows app version';
                    'appname' => 'shows app name'
                    ]
                ] 
            
            ],

            fn() => [
                'show' => 
                    [
                      'i'=>'shows specific app details',
                      'x'=> 'show version {options}'
                    ],
            ]
        ];

    }

 }
                                

Helper properties and methods
There exist some few helper properties and methods within the Consoler class. These helpers are discussed below:

Consoler::getCats() This method helps to return the current array which contains the method called by each "cat" directive. This is equivalent to Consoler::$cats property.

Consoler::isAuto() This property returns true when the Consoler::$auto is set as true. This property deterimines the responsiveness of the Consoler controller template files.

Controller File
 <?php 

 namespace spoova\mi\commands;

 use spoova\mi\core\commands\Consoler\Consoler;

 class Version extends Consoler{

    public static $arg_max = 5; //set a limit of 5 arguments

    function appversion($args) {
        print_r($args); //appversion
    }

    function appname($args) {
        print_r($args); //appname
    }

    public static function setOps() : array {

        return [
            
            'show' => [
                'version' => 'appversion',
                'appname' => 'appname',

                fn() => [
                    'version' => 'shows app version';
                    'appname' => 'shows app name'
                    ]
                ] 
            
            ],

            fn() => [
                'show' => 
                    [
                      'i'=>'shows specific app details',
                      'x'=> 'show version {options}'
                    ],
            ]
        ];

    }

 }