Skip to content

Commit 9de98ad

Browse files
committed
CliTool initial commit.
Main features: - more transparent and convenient config builder; - tools/cli-toolkit/generate-autocompletion-scripts.php (eases autocompletion init); - src/TerminalFormatter.php (helps format the improved generated help pages); - src/Question/Question.php (helps implement interactive scripts); - PHPUnit for autotests plus more autotests.
1 parent 88859e0 commit 9de98ad

File tree

155 files changed

+8855
-3811
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+8855
-3811
lines changed

.gitignore

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,2 @@
1-
.DS_Store
2-
/.idea
3-
/tests/*.diff
4-
/tests/*.exp
5-
/tests/*.log
6-
/tests/*.out
7-
/tests/*.php
1+
/local/
82
/vendor

LICENSE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
MIT License
22

3-
Copyright (c) 2011-2021 Aleksandr Galkin
3+
CliToolkit Copyright (c) 2024-today Kirill Ulanovskii
4+
Cliff Copyright (c) 2011-2021 Aleksandr Galkin
45

56
Permission is hereby granted, free of charge, to any person obtaining a copy
67
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 82 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -1,219 +1,120 @@
1-
# Cliff — a CLI framework for PHP
1+
# CliToolkit
22

3-
Cliff allows you to write CLI scripts in PHP with comfort.
4-
The main features are:
3+
**CliToolkit** is a framework for PHP CLI scripts.
54

6-
* Arguments/options parser
7-
* Terse chained-call configuration syntax
8-
* No-config mode
9-
* Usage and help generation
10-
* Automatic bash completion
5+
Key features (why would you want to use it):
6+
- configure named (options) and positioned (arguments) parameters with ease using a builder;
7+
- define required options, optional arguments, lists of possible values, flags, array-like parameters and subcommands;
8+
- call your scripts from any paths by generated aliases
9+
(see [tools/cli-toolkit/generate-autocompletion-scripts.php](tools/cli-toolkit/generate-autocompletion-scripts.php));
10+
- enjoy autocompleting options' names and parameters' possible values (when calling scripts via special aliases);
11+
- get a generated help page (using the built-in `--help` option) based on your parameters configuration.
1112

12-
The basic idea of Cliff is to allow you to work with CLI arguments exactly the same way
13-
you work with http request variables: by using `$_REQUEST`. All you need is to describe
14-
options and parameters of your script, and then everything just works. In no-config mode,
15-
you don't even have to describe anything.
13+
## Contents
1614

17-
## VERSION
15+
- [Installation](#installation)
16+
- [How to](#how-to)
17+
- [Examples](#examples)
18+
- [Inspiration and authors](#inspiration-and-authors)
19+
- [More info](#more-info)
1820

19-
Current Cliff version is 1.0. It is incompatible with the previous version (0.2) because
20-
of the new code style, which moved everything to camelCase, breaking the API.
21+
## Installation
2122

22-
## DISCLAIMER
23+
The only requirement is PHP >= 8.1
2324

24-
What Cliff is not: it is not a getopt library. It may be overkill to use Cliff for
25-
simplistic cron jobs. What Cliff is for is large tools which you are using a lot, like
26-
CLI versions of extensive projects, data mining tools, etc. If you crave for smart bash
27-
completion, Cliff is the right tool for you.
25+
Just clone / download this repository.
2826

29-
## HOWTO
27+
The composer-based installation will become available a bit later.
3028

31-
You may want to look at scripts in `examples` directory, or even simply grab one of those
32-
and modify to your needs.
29+
## How to
3330

34-
A short example:
31+
Just create a php-file and start configuring:
32+
```php
33+
use MagicPush\CliToolkit\Parametizer\Parametizer;
3534

36-
<?php
37-
require_once 'cliff/lib/Cliff/Cliff.php';
38-
use \Cliff\Cliff;
35+
// Configure your script parameters
36+
$request = Parametizer::newConfig()
37+
->newArgument('chunk-size') // A positioned parameter.
38+
->newFlag('--dry-run') // A named boolean parameter.
39+
->run();
3940

40-
Cliff::run(Cliff::config()->manyParams('lines'));
41+
// Read parameters
42+
$chunkSize = (int) $request->getParam('chunk-size');
4143

42-
foreach ($_REQUEST['lines'] as $arg) {
43-
echo "$arg\n";
44-
}
44+
// Process...
4545

46-
This little script will take arbitrary number of arguments and output each of them
47-
on a separate line. Now, if you want to add an option to uppercase the arguments
48-
before outputting them, it can be done quite easily:
46+
if (!$request->getParam('dry-run')) {
47+
// Make data changes.
48+
}
49+
```
4950

50-
<?php
51-
require_once 'cliff/lib/Cliff/Cliff.php';
52-
use \Cliff\Cliff;
51+
If you want to read your script's documentation, then just call your script with the `--help` option:
52+
```
53+
$ path/to/my-cool-script.php --help
5354
54-
Cliff::run(
55-
Cliff::config()
56-
->flag('--uppercase -u') // adds --uppercase and -u as its alias
57-
->manyParams('lines')
58-
);
55+
USAGE
5956
60-
foreach ($_REQUEST['lines'] as $arg) {
61-
if ($_REQUEST['uppercase']) { // this will be FALSE if the flag is not set,
62-
$arg = strtoupper($arg); // so you don't have to worry about notices
63-
}
57+
my-cool-script.php [--dry-run] <chunk-size>
6458
65-
echo "$arg\n";
66-
}
59+
OPTIONS
6760
68-
Now our script may be called as `php script.php -u abc def`. If called without arguments
69-
or with incorrect ones, the script will show a short description of available options and
70-
parameters. 'Parameter' in Cliff means any non-option argument.
61+
--dry-run
7162
72-
Read phpdoc comments in `lib/Cliff/Config.php` for all configuration possibilities.
63+
--help Show full help page.
7364
74-
### Examples
65+
ARGUMENTS
7566
76-
* [params.php](https://github.com/johnnywoo/cliff/blob/master/examples/params.php): the simplest script that shows how to accept multiple params
77-
* [options.php](https://github.com/johnnywoo/cliff/blob/master/examples/options.php): how to use flags and options
78-
* [callbacks.php](https://github.com/johnnywoo/cliff/blob/master/examples/callbacks.php): how to use callbacks and validators
79-
* [commands.php](https://github.com/johnnywoo/cliff/blob/master/examples/commands.php): how to define subcommands a-la `git checkout`
80-
* [pear-completion.php](https://github.com/johnnywoo/cliff/blob/master/examples/pear-completion.php): a sample config (+ bash completion) for pear executable
81-
* [phpunit-completion.php](https://github.com/johnnywoo/cliff/blob/master/examples/phpunit-completion.php): a sample config (+ bash completion) for phpunit executable
67+
<chunk-size>
68+
(required)
69+
```
8270

83-
## NO-CONFIG MODE
71+
Config and parameter builders will guide you with available options you can set up. If you set something odd, then
72+
built-in validators will show you corresponding errors:
8473

85-
No-config mode allows you to have your cake and eat it too: you get `$_REQUEST` filled,
86-
but don't have to configure anything.
74+
```php
75+
use MagicPush\CliToolkit\Parametizer\Parametizer;
8776

88-
<?php
89-
require_once 'cliff/lib/Cliff/Cliff.php';
90-
\Cliff\Cliff::run();
77+
$request = Parametizer::newConfig()
78+
->newArgument('chunk-size')
79+
->default(100)
80+
->required()
81+
->run();
82+
```
9183

92-
// work with $_REQUEST as you like:
93-
// -x will become $_REQUEST['x'] == true
94-
// --option will become $_REQUEST['option'] == true
95-
// --option=a will become $_REQUEST['option'] == 'a'
96-
// non-options will be accumulated in $_REQUEST['args'] array
84+
```
85+
$ my-cool-script.php
86+
'chunk-size' >>> Config error: a parameter can't be required and have a default simultaneously.
87+
```
9788

98-
You can always add configuration later, to enable proper help, validation and bash completion.
89+
For more cool stuff to know see [Features Manual](docs/features-manual.md).
9990

100-
## BASH COMPLETION
91+
## Examples
10192

102-
The completion is available for configured options (the options/flags themselves
103-
and long option values) and param values. It may work incorrectly with weird characters,
104-
but simple cases should behave properly.
93+
Here are [useful scripts](tools/cli-toolkit) that also utilize some Parametizer features (so may be studied as examples).
10594

106-
To enable the completion, put the following into your ~/.profile
107-
(or ~/.bash_profile, whatever the name is on your system).
95+
- [generate-autocompletion-scripts.php](tools/cli-toolkit/generate-autocompletion-scripts.php)
96+
You should start with this script, as it enables the autocompletion for all Parametizer-powered scripts.
97+
- Launch the script and show the details: `php tools/cli-toolkit/generate-autocompletion-scripts.php --verbose`
98+
- Read it's manual for further customization: `php tools/cli-toolkit/generate-autocompletion-scripts.php --help`
99+
- [terminal-formatter-showcase.php](tools/cli-toolkit/terminal-formatter-showcase.php)
100+
This script shows examples and codes for a terminal coloring and formatting by utilizing
101+
the [TerminalFormatter](src/TerminalFormatter.php) class included in the project.
108102

109-
eval "$(/usr/bin/php /path/to/your/awesometool.php --cliff-bash-profile=atool)"
103+
You can also read the [Tests](tests/Tests)`/*/scripts/` directories as artificial examples.
110104

111-
In this example:
105+
## Inspiration and authors
112106

113-
* `/usr/bin/php` is your php 5.3 cli binary
114-
* `/path/to/your/awesometool.php` is your cliff script
115-
* `atool` is the alias you will use to execute the awesome tool
107+
**CliToolkit** was inspired by and based on [Cliff](https://github.com/johnnywoo/cliff) project, so the first author is
108+
[Aleksandr Galkin](https://github.com/johnnywoo).
116109

117-
After editing the profile, `source` it (or simply log off and on), and `atool <tab>` should
118-
start working.
110+
A part of ideas and code for **CliToolkit v1.0** was brought by [Anton Kotik](https://github.com/anton-kotik).
119111

120-
Of course, instead of eval, you can execute the command by hand, alter its output, etc.
121-
Eval is just a convenient way to get things working.
112+
The [Question](src/Question/Question.php) class was developed by [Vasiliy Borodin](https://github.com/borodin-vasiliy).
122113

123-
### Bash completion for third-party programs
114+
The rest is done by Kirill "Magic Push" Ulanovskii.
124115

125-
You can use Cliff to add bash completion to any other program. Simply create a cliff script
126-
with nothing but config and completion callbacks, and set the actual program name
127-
when installing the completion into bash profile.
116+
## More info
128117

129-
To do that:
130-
131-
1. Write a script with desired config, like the one in `examples/phpunit-completion.php`
132-
2. Put this in your profile:
133-
134-
eval "$(/usr/bin/php /path/to/your/phpunit-completion.php --cliff-bash-profile=phpunit | sed 1d)"
135-
136-
The `sed` part will remove alias command, so when you type "phpunit", it will still mean the phpunit
137-
you can work with (not the helper script); but completion will use the helper script.
138-
139-
## NOTES
140-
141-
To signal an error in your script, simply throw an exception. It will be caught by Cliff,
142-
its message will be displayed into stderr, and the script will exit with non-zero status
143-
(useful for shell scripting).
144-
145-
To change error exit code, you need to change `Cliff::$errorExitCode`. Default error exit code is 1.
146-
147-
## REQUIREMENTS
148-
149-
The only thing Cliff requires is PHP 5.3.
150-
151-
## TODO
152-
153-
If you don't mind, I'll leave this todo list here.
154-
155-
* [+] Modifying option values and params via validator callbacks
156-
* [+] Special class for argument-related exceptions, so we can show usage only for those
157-
* [+] Specifying default error exit code somewhere (for grep-like exit codes)
158-
* [+] Separate options and flags
159-
* [+] A way to specify required options and options that require a value but provide default one
160-
* [+] Ability to allow unconfigured options
161-
* [+] Non-config mode: aggregate all provided options and store all params into $_REQUEST['args'],
162-
no validation or anything; could be useful for tmp scripts (hack a tool together with no design
163-
planning and then, when it matures, configure it for usage and completion)
164-
* [+] A way to specify optional parameters (e.g. vmig db [table])
165-
* [+] Non-validation parse time callbacks (to prevent --help from breaking completion)
166-
* Bash completion for options and params
167-
* [+] Completion for options
168-
* [+] A nice way to install completion handlers into the profile
169-
* [+] Completion for option values
170-
* [+] Completion for params
171-
* Completion of params and validation
172-
* Completion standard modes (filenames, etc) mixed with custom options
173-
* Smart completion for mentioned options (not array = do not complete it twice)
174-
* Completion for single-letter option values
175-
* Completion of weird chars and escaping
176-
* Aliases when installing completion into bash profile (like g='script' x='script -a -b')
177-
* Look into trollop for potential insight
178-
* Ability to specify default values for single-letter options
179-
* [+] Allow a string instead of $props array
180-
* Helper for colors
181-
* Helper for reading (char, string, password, stdin)
182-
* Helper for writing (out, err, interface = skipped if not tty, table)
183-
* Ability to store STDIN in a variable (is it possible to iterate over it instead?)
184-
* [+] Ability to design complex subcommand structures via branches and subcommands
185-
* [+] Aliases for command names
186-
* Usage/help for command name aliases
187-
* Defining branches without params (like `x --list whatever`)
188-
(to distinguish branches we can just forbid two consequent branches with no params)
189-
* Adopting external commands as subcommands
190-
* Adopting external Cliff scripts as subcommands with usage/completion import
191-
* Load config from Cliff XML (not sure if PEAR::Console_CommandLine format is enough)
192-
* Generate config in Cliff XML
193-
* Load config from PEAR::Console_CommandLine XML
194-
* Need some way to include code samples in descriptions (formatting breaks those)
195-
* Refactoring and benchmarking
196-
* An interface/base class for lazy configs (scripts with lots of commands)
197-
198-
## KNOWN BUGS
199-
200-
### Completion makes incorrect/extra chars after sudo
201-
202-
When you try to use sudo with your script, completion results may look like
203-
`sudo pear list-upgrades\ ` (with incorrect escaped space at the end).
204-
This is actually a bug in bash-completion suite (or other script you're using
205-
to enable sudo completion), which does not work correctly with `-o nospace`.
206-
Try completing `sudo git checkout`, it will have weird double space at the end too.
207-
If it doesn't and Cliff completion still glitches, please write me a letter.
208-
209-
## CONTACTS
210-
211-
The Cliff framework was created by Aleksandr "Johnny Woo" Galkin in 2011.
212-
213-
E-mail: agalkin@agalkin.ru
214-
215-
Github page: https://github.com/johnnywoo/cliff
216-
217-
Cliff is released under MIT license. This means you can do pretty much whatever you want with it.
218-
219-
Copyright 2011 Aleksandr Galkin.
118+
- [Features Manual](docs/features-manual.md) - the "[How to](#how-to)" continuation.
119+
- [TODO](docs/todo.md) - the list of things I think would be cool to implement here.
120+
- [Changelog](docs/changelog.md)

composer.json

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
11
{
2-
"name": "johnnywoo/cliff",
3-
"description": "CLI framework",
2+
"name": "magic-push/cli-toolkit",
3+
"description": "CLI framework for PHP",
4+
"type": "project",
5+
"license": "MIT",
46
"require": {
5-
"php": ">=5.3.0"
7+
"php": ">=8.1",
8+
"ext-mbstring": "*",
9+
"ext-posix": "*",
10+
"ext-ctype": "*"
611
},
7-
"license": "MIT",
8-
"authors": [{
9-
"name": "Aleksandr Galkin",
10-
"email": "agalkin@agalkin.ru"
11-
}],
1212
"autoload": {
13-
"psr-0": {
14-
"Cliff": "lib"
13+
"files": [
14+
"src/Polyfill.php"
15+
],
16+
"psr-4": {
17+
"MagicPush\\CliToolkit\\": "src/"
18+
}
19+
},
20+
"autoload-dev": {
21+
"psr-4": {
22+
"MagicPush\\CliToolkit\\Tests\\": "tests/"
23+
}
24+
},
25+
"authors": [
26+
{
27+
"name": "Kirill Ulanovskii",
28+
"email": "xerxes.home@gmail.com",
29+
"homepage": "https://github.com/MagicPush"
1530
}
31+
],
32+
"require-dev": {
33+
"phpunit/phpunit": "^10"
1634
}
1735
}

0 commit comments

Comments
 (0)