eftec / clione
A generator of command line (CLI) for Windows and Linux using PHP
Installs: 1 887
Dependents: 6
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
Requires (Dev)
- phpunit/phpunit: ^8.5
This package is auto-updated.
Last update: 2024-09-02 15:26:47 UTC
README
This library helps to create command line (CLI) operator for PHP in Windows, Mac and Linux
Features
✅ Windows, Linux and Mac Compatible.
✅ This library truly minimalist and simple, it only consists of 2 classes and nothing more and no external dependency.
✅ Arguments & user input
✅ This library was aimed to (optionally) fallback to user-input if the argument is missing.
✅ Colors available
✅ The design is mostly fluent (it adjusts to the width of the screen)
✅ Validation of values
✅ Support NO_COLOR environment variable. See https://no-color.org/
Getting started
Add the library using composer:
composer require eftec/clione
And create a new instance of the library
$cli=new CliOne(); // instance of the library
Usage
For example, let's say we need to create a CLI code to read an information and save into a file.
>php basic.php read -o result.json
We have two arguments, the first (read) is in the first position, and it doesn't have any "-". The second is "-o" that it is our flag with a value.
So we could create our arguments.
$cli=new CliOne(); $cli->createParam('read',[],'first')->add(); // a positional argument (the first one) value-less $cli->createParam('o',[],'flag')->add(); // a simple flag "-o"
And we could evaluate as
$cli->evalParam('read'); $cli->evalParam('o'); // So we could obtain our values as: var_dump($cli->getParameter('read')->value); var_dump($cli->getParameter('o')->value); // or as var_dump($cli->getValue('read')); var_dump($cli->getValue('o'));
It will return false if we don't set a value, and it will return the value it we set it.
>php basic.php read -o result.json string(4) "read" string(11) "result.json"
The parameters are created and evaluated separately because it allows to do more powerful operations with it.
For example, sometimes we want to show the help (the list of parameters available) without evaluating the parameters.
Ok, but now what if we want to create an alias of "-o"
var_dump($cli->getParameter('o',['output','outputresult'])->value);
So we could call using this line
php basic.php read --output result.json # or also php basic.php read --outputresult result.json # or also php basic.php read -o=result.json
If the parameter is a flag, then the alias is a longflag ("--"). If the parameter is a longflag then the alias is a flag.
But let's say we need to ask for a password, however we want to be entered interactively.
$cli->createParam('pwd',[],'flag') // we create the parameter ->setInput(true,'password') // and we ask (if the parameter is not entered as flag) //for user input of the type password (however the password is not hidden visually) ->add(); $cli->evalParam('pwd'); // and don't forget to evaluate the parameter
So it will look like:
> php .\basic.php read -o result.json Select the value of pwd [*****] :123
Now, let's say something more advanced, multiple options, we want to select the type of file: json, csv, html and xml
Our code
$cli->createParam('type',[],'flag') ->setInput(true,'option',['json','csv','xml','html']) ->add();
And the result:
PS > php .\basic.php read -o result.json Select the value of pwd [*****] :111 [1] json [2] csv [3] xml [4] html Select the value of type [] :2 #you could use TAB key for autocomplete, cool!
List of values are divided in two values, the visual value (simply called value), and the key-value.. In this example, "csv" is a value and its key-value is "2".
The list of values allows associative arrays and indexed arrays. Indexed arrays are renumbered to start in 1.
You could also enter
php .\basic.php read -o result.json -pwd 123 -type json
Now, you can show the parameters ("show the syntax help") as follows:
$cli->showParamSyntax2('parameters:');
But it will look plain.
It is because you can add a description, change the question and add more help information
$cli->createParam('type',[],'flag') ->setDescription('it is the type of output','what is the option?',['it is the help1','example: -option xml']) ->setInput(true,'option',['json','csv','xml','html']) ->add();
So it will look like: (in colors)
parameters: read The command [read] -o, --output, --outputresult The output file without extension [result.json] example: -o file -pwd It is the password [*****] -type it is the type of output [csv] it is the help1 example: -option xml
There are more operations available but the basic is there.
Table of contents
- CliOne
- Table of contents
Flow
- (optional) you can set the current value using the method setParam()
- If the type of parameter is not "onlyinput" and "none", then it reads the parameter
- Example: php program.php -param1 value --param2 -param3="hello world" parampositional
- If the parameter is found, then it is returned, end of the flow.
- If the parameter is not found then
- If setCurrentAsDefault() is set, and the current value is not null, then the default value is the current value.
- Otherwise, the default value is the value set using the method setDefault(). If none, then it uses null.
- if input is true setInput(true) then it asks to user-input the value
- if the user doesn't fill the information, then it returns the default value (if any), end of the flow
- if the user fills the information, but it is incorrect, then it asks again and again.
- if the user fills the right information, then it returns this value, end of the flow
- if input is true setInput(false) then
- Note: we were unable to read the values of the argument, and we don't want to read from user input.
- it returns the default value, and it could raise an error, end of the flow
Note:
- isRequired() if the value is missing, then it shows an error.
- setAllowEmpty() if the value is empty (not missing), then it allows to enter an empty value
Input as arguments
php mycli.php subcommandfirst subcommandsecond -flag valueflag --longflag valueflag2 subcommandlatest
The system allows reading multiple types of arguments
- first: this argument does not have value, and it is position (in the very first position), it must be not be prefixed with a "-", otherwise it would be considered a flag instead of a positional argument.
cliprogram.php first # the value obtained is "first".
- command: it is similar to first, but it does not compare the name of the argument.
cliprogram.php com -flag # first returns "com" if the argument is named first. command returns "com" regardless of its name.
- second: this argument is also positional (second position) and does not have any value
cliprogram.php first second -someflag # the value obtained is "second"
- last: this argument is also positional, and it is always at the latest argument
cliprogram.php first second last # the value obtained is "last"
- flag: the argument is prefixed with a single "-". This argument not need to be a single character.
cliprogram.php -flag hello # the value of the flag called "flag" is "hello"
- longflag: the argument is prefixed with a double "--"
cliprogram.php --flag hello # the value of the doubleflag called "flag" is "hello"
- onlyinput/none: the system never read it as argument, so it could be user-input.
- none means that the argument is only user-input, and it must not be stored.
cliprogram.php # "onlyinput/none" could not be obtained via command line
The argument could be created as:
// program.php -f hello // or // program.php -f=hello // or // program.php -f "hello world" $cli->createParam('f','flag')->add(); // add() is important otherwise the parameter will not be create.
And it could be read as:
$result=$cli->evalParam('name'); // $result->value will return "hello"
Now, what if you want to create multiples alias for the same parameter.
// program.php -h // or // program.php --help $cli->createParam('h','flag',['help'])->add(); // it adds an alias longflag called "help"
Input interactive
There are several configuration to set an input interactively.
By default, every parameter is read as argument. If the value is read as argument, then it is not asked interactively.
However, if the parameter is of the type "none" or "onlyinput", then they are only obtained by user input ( interactively).
Example:
$cli->$t->createParam('paramname',[],'none');
User input (interactive)
With the method setInput() we set that this parameter could also be read interactively.
$cli->$t->createParam('paramname',[],'none')->setInput();
Example, let's say the next example:
$cli=new CliOne(); $cli->createParam('p1',[],'none') ->setInput() ->add(); // we create the param $cli->evalParam('p1'); // and we evaluated the parameter
Now, this input accepts any kind of text. But there is many kind of user input.
Option returns a value and a value-key. Value is the content visible. And value-key, is the content selected by the user.
Example Option:
$cli=new CliOne(); $cli->createParam('p1',[],'none') ->setInput(true,'option2',['key1'=>'value1','key2'=>'value2','key3'=>'value3','key4'=>'value4']) ->add(); // we create the param $cli->evalParam('p1'); $cli->showLine("value :".$cli->getValue('p1')); $cli->showLine("valuekey :".$cli->getValueKey('p1'));
Example Multiple:
$cli=new CliOne(); $cli->createParam('p1',[],'none') ->setInput(true,'option2',['key1'=>'value1','key2'=>'value2','key3'=>'value3','key4'=>'value4']) ->add(); $cli->evalParam('p1'); // value returns an associative array with the values selected, example: ["value1","value3"]
Customize user input
It is possible to customize the input by changing the help description, changing the question, showing an example or showing a value to the argument
$cli=new CliOne(); $cli->createParam('p1',[],'none') ->setInput() ->setDescription('it is for help','what is the value of p1?',['help line1','help line 2'],'the argument is called p1') ->add(); $cli->evalParam('p1');
menu
You can create a menu using the next methods
addMenu()
It creates a new menu
addMenuItem()
It adds an option to a menu
addMenuItems()
It adds multiple options to a menu
evalMenu()
It executes a menu
clearMenu()
It clears a menu.
example
class ClassService { public function menuHeader(CliOne $cli) { /* todo: add header code */ } public function menuFooter(CliOne $cli) { /* todo: add footer code */ } public function menuOption1(CliOne $cli) { /* todo: add menu option 1 code */ } public function menuOption2(CliOne $cli) { /* todo: add menu option 2 code */ } } $obj=new ClassService(); $cli = new CliOne(); $cli->addMenu('menu1', 'header','footer'); $cli->addMenuItem('menu1','option1', 'option #1' ,function($cli) {$cli->showLine('calling action1');$this->assertTrue(true, true);}); $cli->addMenuItem('menu1','option2', 'option #2'); $cli->addMenuItem('menu1','option3', 'option #3','navigate:menu1.1'); $cli->addMenuItems('menu1',['option4'=>'option #4','option5'=> 'option #5']); // adding multiples options $cli->addMenu('menu1.1', 'header2','footer2'); $cli->addMenuItem('menu1.1','option1', 'option #1.1'); $cli->addMenuItem('menu1.1','option2', 'option #2.1'); $cli->addMenuItem('menu1.1','option3', 'option #3.1'); $cli->addMenuItem('menu1.1','option4', 'option #4.1'); $cli->addMenuItem('menu1.1','option5', 'option #5.1'); $cli->evalMenu('menu1',$obj); // runs the menu. $cli->showLine('exit ok'); $cli->clearMenu();
Examples
Example using arguments
And create the next code
// example1.php // don't forget to add autoloader, namespace, etc. $cli=new CliOne(); // instance of the library if($cli->isCli()) { // we validate if we are running a CLI or not. $cli->createParam('param1') // the name of the parameter ->setDescription('Some description','question?') // description and question ->setRequired(true) // if the field is required ->setDefault('param1') // the default value If the value is not found ->add(); // it adds a parameter to the cli $param1=$cli->evalParam('param1'); // then we evaluate the parameter. var_dump($param1->value); }
So you can run as:
Example using user input
You can ask for user input of the user.
$cli=new CliOne(); if($cli->isCli()) { $cli->createParam('param1') ->setDescription('This field is called param1 and it is required') ->setInput(true,'string') ->setRequired(true) ->setDefault('param1') ->add(); $param1 = $cli->evalParam('param1'); var_dump($param1->value); }
It will show the next result
Example with a game
Example colors
You can see the tags available in Types of colors
$cli->showLine("<bold>bold</bold>"); $cli->showLine("<dim>dim</dim>"); $cli->showLine("<bred>background red</bred>"); $cli->showLine("<bblue>background red</bblue>"); $cli->showLine("<bwhite><black>background white</black> </bwhite>"); $cli->showLine("<byellow><blue>background yellow</blue></byellow>"); $cli->showLine("<red>error</red> (color red)"); $cli->showLine("<yellow>warning</yellow> (color yellow)"); $cli->showLine("<blue>information</blue> (blue)"); $cli->showLine("<yellow>yellow</yellow> (yellow)"); $cli->showLine("<green>green</green> (color green)"); $cli->showLine("<italic>italic</italic>"); $cli->showLine("<bold>bold</bold>"); $cli->showLine("<bold><yellow>bold yellow</yellow></bold>"); $cli->showLine("<strikethrough>stike</strikethrough>"); $cli->showLine("<underline>underline</underline>"); $cli->showLine("<cyan>cyan</cyan> (color cyan)"); $cli->showLine("<magenta>magenta</magenta> (color magenta)"); $cli->showLine("<bold><cyan>bold cyan</cyan></bold> (color cyan)"); $cli->showLine("<bold><magenta>bold magenta</magenta></bold> (color magenta)"); $cli->showLine("<bblue><col0/> col0</bblue>"); $cli->showLine("<bblue><col1/> col1</bblue>"); $cli->showLine("<bblue><col2/> col2</bblue>"); $cli->showLine("<bblue><col3/> col3</bblue>"); $cli->showLine("<bblue><col4/> col4</bblue>"); $cli->showLine("<bblue><col1/> col1 <col3/> col3 <col5/> col5</bblue>"); $cli->showLine("The parameters of option are: <option/>",$cli->getParameter('test'));
Example tables
Types of user input
Types of colors
Definitions
You can find the definition of the classes, methods and fields at:
debug
To activate the debug mode, you must set the debug field as true:
$cli=new CliOne();
$cli->debug=true;
In debug mode, every user input is recored in the field $debugHistory
You can also see the history running the input ??history
And you can clear the history using the input ??clear
The goal is we could store a session and replace it using testUserInput()
You can also load and save the user input
- ??history it shows the history
- ??clear it clears the history
- ??load it load the user input and runs it.
- ??save it saves the user input in a file called _save.json
- ??load:file ??save:file you can also specify the filename where it will be saved
$cli = new CliOne(); CliOne::testUserInput([...]); // put your story here.
Compatibility
- It must support all moderns interface that are compatibles with Virtual Terminal.
- Since Windows TH2 (v1511, 2015), cmd.exe and powershell.exe has supports or VT, but it must be enabled.
- REG ADD HKCU\CONSOLE /f /v VirtualTerminalLevel /t REG_DWORD /d 1
- Since Windows 10 Anniversary Edition (v1607, 2016), cmd.exe and powershell.exe has default supports of VT (AFAIK)
- Windows 2019 (LTS, 2018) supports this library by default.
- Windows Terminal supports all features.
- The screen size width is -1 column less in older version of Windows. C'mon, Microsoft!
Changelog
-
1.33 (2024-08-02)
- json_encode does not throw an exception. Now it fails with empty or default value.
-
1.32.1 (2024-03-02)
- fixed some fields, default values and type hinting.
-
1.32 (2024-03-02)
- Updating dependency to PHP 7.4. The extended support of PHP 7.2 ended 3 years ago.
- Added more type hinting in the code.
-
1.31 (23-09-02)
- new methods:
- hideCursor()
- showCursor()
- modified method:
- setStyle() now allows two arguments.
- new methods:
-
1.30 (23-09-02)
- Best identification of the version of Windows. 10.1607 and higher is considered compatible.
- Fixed: scroll and wait cursor now work correctly.
- Preliminary Container.
-
1.29.1 (23-04-06)
- Fixed a bug with addMenuService()
-
1.29 (23-04-06)
- In the debug mode, you can ??load, ??save the operations.
-
1.28 (2023-04-05)
- the $debug field, so you can debug and store the user input history.
- PHP_FAKE_READLINE constant or global variable now is a static field $fakeReadLine
-
1.27 (2023-04-02)
- new method instance() so you can get or create a new singleton instance.
- new method hasInstance()
- new method hasMenu()
- new method addMenuService()
- fixed a bug with showHelp() and the help is an array or the help is missing.
-
1.26.1 (2023-03-21)
- cleaned some code.
-
1.26 (2023-03-21)
- addMenu() and addMenuItem() allow to use callable arguments.
-
1.25.1 (2023-03-20)
- Fixed a small bug with evalMenu()
- Added option to addMenu() ($size)
-
1.25 (2023-03-20)
- Added method clearMenu(),addMenu(),addMenuItem(),addMenuItems(),evalMenu()
- Added method setVariable(),getVariable() and addVariableCallBack(). $variable field is now private.
-
1.24 (2023-03-11)
- Added new method createOrReplaceParam(),setParamUsingArray(),getValueAsArray()
- setParam() has a new argument to create the parameter if it is not defined.
- Added variables that could be displayed when the text contains "{{namevar}}"
-
1.23 (2023-03-05)
- Added new methods readDataPHPFormat() and saveDataPHPFormat()
- readDate() and saveData() generate a file that includes the version and the date of generation. It does not impact older files.
-
1.22.3 (2023-03-04)
- fixed a small bug when some value is null. It could throw a warning in PHP
-
1.22.2 (2023-02-17)
- some cleanups
-
1.22.1 (2022-7-30)
- fix a small typo in the code.
-
1.22 (2022-07-30)
- setInput() added format wide to use 1 column (if the screen is equal or less than 80 columns) or two columns
- "option" ignore cases.
-
1.21 (2022-06-27)
- showMessageBox() now support colors and line carriage.
-
1.20 (2022-06-21)
- showMessageBox() added wrap lines
- updated the way to find if an array is associative or not.
-
1.19 (2022-06-18)
- Update the creation of table
-
1.18.1 (2022-06-17)
- Fixed a bug when we use setCurrentAsDefault() but the type of value is an option (we set the default the valuekey instead of the value)
-
1.18 (2022-06-11)
- Added the method addExtensionFile()
-
1.17 (2022-06-09)
- fixed many problems with Linux (number of rows, autocomplete, etc.)
-
1.16 (2022-03-25)
- setParam() allows to set the value or the value-key
-
1.15 (2022-03-15)
- showHelp() shows more information.
- colorText() now correct some missing tags.
-
1.14 (2022-03-04)
- method showTable() allows to show or hide the top, sides and bottom borders.
-
1.13 (2022-02-28)
- Changed silentError to errorType
-
1.12 (2022-02-26)
- CliOne:
- added a memory stream
- set the default stream
- set the current stream to use stdout,stderr or memory (stdin is not used for in)
- added a new parameter type "command" that it is equals than first, but it ignores the name and considers the position.
- added the method showHelp()
- added the method makeBigWords()
- added fontZnaki()
- added fontaatr()
- both fonts use a lot of space in code, but they are only an array of bits, so they use only 2KB.
- new method alignLinesVertically()
- new method maxWidth()
- renamed field cmdMode to noANSI
- method initialEndStyle()
- CliOneParam:
- Added a field related.
- CliOne:
-
1.11 (2022-02-22)
- Added supports for STDIN, STDOUT, and STDERR.
-
1.10 (2022-02-21)
- [new] support for the old command line (cmd.exe). It is activated automatically.
- It degraded the colors to b&w and changes the utf-8 characters to be compatible.
- Also, the scroll bar and the waiting cursor is not displayed in this mode.
- See compatibility for more information.
- [new] support for the old command line (cmd.exe). It is activated automatically.
-
1.9 (2022-02-20)
- [new] argumentIsValueKey and memory
- [changed] Changed the signature of createParam(), switched the second and third argument
-
1.8 (2022-02-20)
- [new] setParam() throw an exception if the parameter is not defined.
- [new] showParamSyntax2()
- [new] CliOneParam::$nameArg name of the argument (used in help)
-
1.7 (2022-02-18)
- [fix] added type hinting for most fields and methods.
- [new] new setValue() for CliOneParam.
-
1.6.1 (2022-02-18)
- [fix] fixed a small bug with the value is set manually, so it is still marked as missing.
-
1.6 (2022-02-18)
- [new] new method isParameterPresent()
-
1.5.5 (2022-02-18)
- getParameter() always returns a parameter, no matter if it does not exist.
- You can use the method isValid() to check its validity
- setSilentError() you can silent the error output.
- addhistory() renamed as setAddHistory()
- To add a new parameter add() validates if the key is already in use, if the key is an alias of other, or if the alias is in use.
- getParameter() always returns a parameter, no matter if it does not exist.
-
1.5.4 (2022-02-18)
- fixed a problem with the default value.
- added history (if available)
-
1.5.3 (2022-02-18)
- nothing, just a renumeration
-
1.5.2 (2022-02-18)
- [fix] some cleanups of the code.
-
1.5.1 (2022-02-18)
- [fix] fixed a problem when the type is "none", it returned null instead of false.
- [new] CliOneParam::evalParam() could return the value instead of the instance.
-
1.5 (2022-02-17)
- [fix] corrected the display and trim of some text when the text uses a color.
- [new] it allows multiples types of arguments (not only flags), including positional, flags, long-flags are none.
- [new] added stack. Some visual elements allows to stack values.
-
1.4.1 (2022-02-15)
- [fix] some fix for characters thare unicode. The system will use automatically MB_STRING if the library is available. Otherwise, it will use the default library
- [new] new styles and patterns for components.
-
1.4 (2022-02-15)
- [replaced] now all colors are express not abbreviated "" => "", etc.
- [new] added all basic colors, background and solved a problem with the underline.
- [new] added showFrame(),showTable(),showWaitCursor(),showProgressBar()
-
1.3 (2022-02-14)
- [new] added autocomplete (tab key)
- [new] added breadcrub
- [new] added showValuesColumn()
- [replaced] now keys (showing in options) are aligned at the center.
-
1.2.2 (2022-02-14)
- [fixed] fixed a problem where the question is truncated with an ellipsis (...)
-
1.2.1 (2022-02-13)
- [fixed] fixed some bugs
- [new] keys are padded, example /[ 1] /[ 2] /[ 3] ... [99], /[value 1] /[value 2] /[value ]
-
1.2 (2022-02-13)
- [replaced] "options" renamed as "multiple". Added "multiple2","multiple3","multiple4"
- [new] associative arrays are allowed.
- [new] added templates.
- [new] added valuekey.
-
1.1 (2022-02-12)
- [new] new methods savedata(),getArrayParams(),setArrayParam(),readData()
- [replaced] a new argument for the method replaceColor()
- [new] a new type called password
-
1.0.1 (2022-02-11)
- [Fixed] namespace.
- [Fixed] replaceColor() fixed a color
- [Added] CliOne::indVendorPath()
-
1.0 (2022-02-11)
- End of beta, first release.
-
0.7 (2022-02-11)
- Added option4.
- optionshorts allows to specify the first letter, only if the first letter is unique, examples: yes/no allows to use y/n
-
0.6 (2022-02-11)
- Added option2 and option3
- allowNulls() now doesn't work with default values.
-
0.5 (2022-02-03)
- [unittest] Better unit test.
- [CliOneParam] You can set if you allow empty values or not.
- [CliOne] You can set if you allow empty values or not.
-
0.4 (2022-01-27) Now test coverage is over the 75%
-
0.3 (2022-01-26) new corrections to the reading of values
-
0.2 some updates
-
0.1 first version