The CLI interface PSR brainstorm

376 views
Skip to first unread message

Dracony

unread,
Jun 27, 2016, 3:57:46 AM6/27/16
to PHP Framework Interoperability Group
A year or maybe two ago I proposed a PSR for "tasks", that would allow easier chaining of common things like e.g. migrating a database, minimizing CSS, etc. Back then it didn't really get much traction I believe because PHP world isn't really requiring as much build chains as say JS world (where gulp and Grunt plugins are abundant).

So instead I wanted to rephrase it now as a Command PSR, which is basically standardizing something akin to Symfony Command, which would be really really useful, since then you wouldn't need a special service provider to get Doctrine migrations in Silex, etc. A common interface would be very simple to achieve, but it requires standardizing the CLI interface first. So let's do that!

Ok, so to describe the CLI interface we need:

  • Input/Output streams for input, output and error
  • Methods to get options and arguments
  • Method to get current working directory
Getting this PSR done will open the way for the Command PSR too, and that will be just as useful to the CLI world and Middleware PSRs are for HTTP world.

What do you think? Did I catch your attention? If so, let's get cracking =)

Alexander Makarov

unread,
Jun 27, 2016, 5:40:14 AM6/27/16
to PHP Framework Interoperability Group
Sounds fine to me. We have a CLI wrapper in Yii so I can provide some input for questions raised.

Larry Garfield

unread,
Jun 27, 2016, 9:47:35 AM6/27/16
to php...@googlegroups.com
Standard questions:

1) Would it be possible to build such an interface skeleton that is sufficiently generic that it doesn't end up dictating an implementation?

2) Are current CLI tool projects on board with creating a standard?

3) What's the target audience, and how would it make life easier for the general PHP-developing public?

--Larry Garfield

Andreas Heigl

unread,
Jun 27, 2016, 1:29:01 PM6/27/16
to php...@googlegroups.com
Hi Dracony.

Thanks for stepping up. I had some similar ideas recently with
implementing a kind of Middleware for CLI-APplications.

Am 27.06.16 um 09:57 schrieb Dracony:
> A year or maybe two ago I proposed a PSR for "tasks", that would allow
> easier chaining of common things like e.g. migrating a database,
> minimizing CSS, etc. Back then it didn't really get much traction I
> believe because PHP world isn't really requiring as much build chains as
> say JS world (where gulp and Grunt plugins are abundant).
>
> So instead I wanted to rephrase it now as a Command PSR, which is
> basically standardizing something akin to Symfony Command, which would
> be really really useful, since then you wouldn't need a special service
> provider to get Doctrine migrations in Silex, etc. A common interface
> would be very simple to achieve, but it requires standardizing the CLI
> interface first. So let's do that!
>
> Ok, so to describe the CLI interface we need:
>
> * Input/Output streams for input, output and error
> * Methods to get options and arguments
> * Method to get current working directory

Personally I think setting up Input and Output-Streams for CLIs similar
to PSR7/Middleware will resolve the issue of getting options and
arguments. So I'd try to focus on that one. And there's already a
standardized way to get the current working directory:
http://php.net/getcwd - I don't think that a further one is needed.

So let's get going with "CLI-Message interfaces"

Cheers

Andreas

--
,,,
(o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:and...@heigl.org N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org http://hei.gl/wiFKy7 |
+---------------------------------------------------------------------+
| http://hei.gl/root-ca |
+---------------------------------------------------------------------+

Daniel Plainview

unread,
Jun 27, 2016, 2:52:37 PM6/27/16
to PHP Framework Interoperability Group
The problem is some things shouldn't be framework-agnostic, because they *are* framework.
They are what make us to choose one framework in favour of another.
Here is place for personal preferences.
I'd be careful with proposals like "because we can".

On Monday, June 27, 2016 at 10:57:46 AM UTC+3, Dracony wrote:

Dracony

unread,
Jun 28, 2016, 10:31:10 AM6/28/16
to PHP Framework Interoperability Group
> 1) Would it be possible to build such an interface skeleton that is sufficiently generic that it doesn't end up dictating an implementation?

Of course, we already have stream interfaces defined for PSR-7. They are much more complex than what's needed for CLI though, since CLI streams are either readable OR writeable. So the Stream API can be "borrowed" from PSR-7 and simplified. Getting the current working directory is just a a method returning a string, so there is nothing to be dictating implementation there too. All in all the "interface dictating implementation" problem doesn't come up at all really

> 2) Are current CLI tool projects on board with creating a standard?

> 3) What's the target audience, and how would it make life easier for the general PHP-developing public?

This is rather easy. Having commands coded to a common interface would make packages like https://github.com/dbtlr/silex-doctrine-migrations obsolete.
Assets management, ORM generation, running tests, etc. All these tools can ship with a command adhering to the new interface and integrate into frameworks without the need for bridges like these

It'd be nice if we had Symfony representative pop up in this thread =) . Since the Symfony Console API is the de-facto standard atm

Dracony

unread,
Jul 7, 2016, 4:16:51 AM7/7/16
to PHP Framework Interoperability Group
Just wanted to bump this thread up, since everybody is residing in the Paul thread at the moment. Hopefully I can get some feedback from people working on CLI tools

Andrew Carter

unread,
Jul 7, 2016, 4:35:14 AM7/7/16
to PHP Framework Interoperability Group
I don't see this as an area where interoperability is better than innovation, but I could be persuaded. I think the FIG has to be careful not to standardise things for the sake of it - because it could be done - but rather because it would be beneficial to the ecosystem to do so.

Composer already has the option to provide vendor binaries. The only real benefit to a PSR for this that I can see is that you could add multiple commands from across packages to a single executable - and I ask - is that really a significant benefit?

If your desire is to not rely on concrete implementations, then out of the box PHP has the capability of doing everything that you mention (stdin, stdout, stderr, argc, argc, get_cwd(), etc...).

Could you provide an example scenario (or scenarios) where your suggested PSR would be beneficial to the ecosystem?

Regards,

Andrew

Roman Tsjupa

unread,
Jul 7, 2016, 4:56:27 AM7/7/16
to PHP FIG
Sure, actually I already did in this thread. Look at doctrine migrations provider for silex: https://github.com/kurlltd/silex-doctrine-migrations-provider
If the CLI is standardized as an interface the next step would be standardizing the Command interfaces, making such glue classes unneeded, and also it would be possible to use Doctrine migrations with frameworks that don't use Symfony Command.

Basically think of the CLI and Command proposals as analogs to the HTTP message and Middlware PSRs. I see no logical reason to not create a standard interface for them

--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/_vEmRLcw-gE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/6cc25422-7e4e-47a3-8c5a-0c3a97fa189a%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Andreas Heigl

unread,
Jul 7, 2016, 5:18:58 AM7/7/16
to php...@googlegroups.com
Am 07.07.16 um 10:35 schrieb Andrew Carter:
> I don't see this as an area where interoperability is better than
> innovation, but I could be persuaded. I think the FIG has to be careful
> not to standardise things for the sake of it - because it could be done
> - but rather because it would be beneficial to the ecosystem to do so.
>
> Composer already has the option to provide vendor binaries
> <https://getcomposer.org/doc/articles/vendor-binaries.md>. The only real
> benefit to a PSR for this that I can see is that you could add multiple
> commands from across packages to a single executable - and I ask - is
> that really a significant benefit?
>
> If your desire is to not rely on concrete implementations, then out of
> the box PHP has the capability of doing everything that you mention
> (stdin, stdout, stderr, argc, argc, get_cwd(), etc...).
>
> Could you provide an example scenario (or scenarios) where your
> suggested PSR would be beneficial to the ecosystem?

Having a standardized interface for - for example - the OutputInterface
would allow me to use a third-party library to format output in
different CLI-tools. Or I could use third-party libraries to filter and
validate input using a HTTP-like Middleware-approach.

And such interfaces would also allow me to create one "Command"-Class
and accompanying business-logic that I can then use in different
Environments.

That surely can all be achieved using plain PHP-functionality, but
having a certain layer of abstraction would make it much easier for me
to write the main business-logic without always having to implement all
the addon stuff like validating input, howe to format the output, etc.

Just my 0.02€

Cheers

Andreas
> * Input/Output streams for input, output and error
> * Methods to get options and arguments
> * Method to get current working directory
>
> Getting this PSR done will open the way for the Command PSR
> too, and that will be just as useful to the CLI world and
> Middleware PSRs are for HTTP world.
>
> What do you think? Did I catch your attention? If so, let's
> get cracking =)
>
> --
> You received this message because you are subscribed to the Google
> Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to php-fig+u...@googlegroups.com
> <mailto:php-fig+u...@googlegroups.com>.
> To post to this group, send email to php...@googlegroups.com
> <mailto:php...@googlegroups.com>.
> <https://groups.google.com/d/msgid/php-fig/6cc25422-7e4e-47a3-8c5a-0c3a97fa189a%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


Andrew Carter

unread,
Jul 7, 2016, 5:20:30 AM7/7/16
to PHP Framework Interoperability Group
It is possible to use Doctrine migrations with frameworks that don't use Symfony Console? You just install Symfony Console like you would any other dependency of Doctrine Migrations.

Other than disk space, what's the problem with one dependency using one console helper and another dependency using another? Composer vendor binaries allow you to integrate commands from different vendors into applications just the same.

HTTP messages and CLI interfaces are different. HTTP messages are something you want to pass between different third party libraries and your application. The only benefit of doing this for CLI interfaces is that you could add multiple commands from different vendors to the same executable - and I don't think this is significant (not necessarily even desirable).

Roman Tsjupa

unread,
Jul 7, 2016, 5:27:22 AM7/7/16
to PHP FIG
Well of course it works if you also install Symfony Console. But what if the framework already has a different command line api stack?
There are also some nice added benefits for abstracting the CLI out, like say running a server on a socket that talks to multiple clients where each socket is represented as a CLI interface implementation

Andrew Carter

unread,
Jul 7, 2016, 5:47:57 AM7/7/16
to PHP Framework Interoperability Group
In general, my response to these comments are that you could make similar arguments for basically any PHP software component. If the FIG was to standardise every aspect of framework development, we would end up with a FIG framework that was no different from the others and actually worked against innovation in the community.

For this reason, the case for standardisation has to be strong - and I just don't see it here.

In the name of self throttling - this will be my last post on the topic.

@dracony


But what if the framework already has a different command line api stack?

That's a question for you to answer. I don't see it as a big problem - the first few letters of the command you type are different and it requires a little more space for dependencies.


There are also some nice added benefits for abstracting the CLI out, like say running a server on a socket that talks to multiple clients where each socket is represented as a CLI interface implementation

I think this is better handled by innovation rather than standardisation.

@andreas


Having a standardized interface for - for example - the OutputInterface
would allow me to use a third-party library to format output in
different CLI-tools.
 
I'm not sure this is a significant enough programming problem to warrant a PSR. I'm trying to think of times when I would ever have wanted to do this - but I can only speak for my own experience (which is limited).


Or I could use third-party libraries to filter and validate input using a HTTP-like Middleware-approach.

Interesting, but this isn't a console PSR - this is a separate filter/validate middleware PSR.

That surely can all be achieved using plain PHP-functionality, but having a certain layer of abstraction would make it much easier for me to write the main business-logic without always having to implement all the addon stuff like validating input, howe to format the output, etc.

Again, I'm not really convinced there is any down side here from coupling to say Symfony Console (or an alternative). Composer vendor binaries allow you to provide as many executable commands as you like from different dependencies.
 

Daniel Leech

unread,
Jul 7, 2016, 5:57:52 AM7/7/16
to php...@googlegroups.com
Just to add a concrete example, you can integrate the f.e. Doctrine
commands into your existing console stack. You do not need to bootstrap
the Symfony console, add or add proxy commands to your CLI.

Example:

$ php myconsoleapp
My CLI Appilcation:

Commands:

init:database : Initialize the dataabase
run : etc.
benchmark : etc.
send-emails : etc.

When I want to use Doctine DBAL in my application I need to reimplement
the Symfony Console command. This PR would seem to lead the way to being
able to reuse the (f.e.) stock DBAL command.

$myApplication->addComand(new \Acme\MyCommand));
$myApplication->addComand(new \Doctrine\DBAL\Console\SchemaUpdate(...));

So for what its worth I think it is a great idea.

On Thu, Jul 07, 2016 at 02:20:30AM -0700, Andrew Carter wrote:
> It is possible to use Doctrine migrations with frameworks that don't use
> Symfony Console? You just install Symfony Console like you would any other
> dependency of Doctrine Migrations.
>
> Other than disk space, what's the problem with one dependency using one
> console helper and another dependency using another? Composer vendor
> binaries allow you to integrate commands from different vendors into
> applications just the same.
>
> HTTP messages and CLI interfaces are different. HTTP messages are
> something you want to pass between different third party libraries and
> your application. The only benefit of doing this for CLI interfaces is
> that you could add multiple commands from different vendors to the same
> executable - and I don't think this is significant (not necessarily even
> desirable).
>
> On Thursday, July 7, 2016 at 9:56:27 AM UTC+1, Dracony wrote:
>
> Sure, actually I already did in this thread. Look at doctrine migrations
> provider for
> silex: [1]https://github.com/kurlltd/silex-doctrine-migrations-provider
> If the CLI is standardized as an interface the next step would be
> standardizing the Command interfaces, making such glue classes unneeded,
> and also it would be possible to use Doctrine migrations with frameworks
> that don't use Symfony Command.
> Basically think of the CLI and Command proposals as analogs to the HTTP
> message and Middlware PSRs. I see no logical reason to not create a
> standard interface for them
> On Thu, Jul 7, 2016 at 10:35 AM, Andrew Carter
> <[2]andrewca...@gmail.com> wrote:
>
> I don't see this as an area where interoperability is better than
> innovation, but I could be persuaded. I think the FIG has to be
> careful not to standardise things for the sake of it - because it
> could be done - but rather because it would be beneficial to the
> ecosystem to do so.
>
> Composer already has the option to provide [3]vendor binaries. The
> like [4]https://github.com/dbtlr/silex-doctrine-migrations
> obsolete.
> Assets management, ORM generation, running tests, etc. All these
> tools can ship with a command adhering to the new interface and
> integrate into frameworks without the need for bridges like these
> It'd be nice if we had Symfony representative pop up in this
> thread =) . Since the Symfony Console API is the de-facto standard
> atm
>
> On Monday, June 27, 2016 at 9:57:46 AM UTC+2, Dracony wrote:
>
> A year or maybe two ago I proposed a PSR for "tasks", that would
> allow easier chaining of common things like e.g. migrating a
> database, minimizing CSS, etc. Back then it didn't really get
> much traction I believe because PHP world isn't really requiring
> as much build chains as say JS world (where gulp and Grunt
> plugins are abundant).
> So instead I wanted to rephrase it now as a Command PSR, which
> is basically standardizing something akin to Symfony Command,
> which would be really really useful, since then you wouldn't
> need a special service provider to get Doctrine migrations in
> Silex, etc. A common interface would be very simple to achieve,
> but it requires standardizing the CLI interface first. So let's
> do that!
> Ok, so to describe the CLI interface we need:
>
> * Input/Output streams for input, output and error
> * Methods to get options and arguments
> * Method to get current working directory
>
> Getting this PSR done will open the way for the Command PSR too,
> and that will be just as useful to the CLI world and Middleware
> PSRs are for HTTP world.
> What do you think? Did I catch your attention? If so, let's get
> cracking =)
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this topic, visit
> [5]https://groups.google.com/d/topic/php-fig/_vEmRLcw-gE/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [6]php-fig+u...@googlegroups.com.
> To post to this group, send email to [7]php...@googlegroups.com.
> To view this discussion on the web visit
> [8]https://groups.google.com/d/msgid/php-fig/6cc25422-7e4e-47a3-8c5a-0c3a97fa189a%40googlegroups.com.
> For more options, visit [9]https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [10]php-fig+u...@googlegroups.com.
> To post to this group, send email to [11]php...@googlegroups.com.
> To view this discussion on the web visit
> [12]https://groups.google.com/d/msgid/php-fig/40b460ed-fb4e-4460-b416-2607076a99b5%40googlegroups.com.
> For more options, visit [13]https://groups.google.com/d/optout.
>
> References
>
> Visible links
> 1. https://github.com/kurlltd/silex-doctrine-migrations-provider
> 2. javascript:
> 3. https://getcomposer.org/doc/articles/vendor-binaries.md
> 4. https://github.com/dbtlr/silex-doctrine-migrations
> 5. https://groups.google.com/d/topic/php-fig/_vEmRLcw-gE/unsubscribe
> 6. javascript:
> 7. javascript:
> 8. https://groups.google.com/d/msgid/php-fig/6cc25422-7e4e-47a3-8c5a-0c3a97fa189a%40googlegroups.com?utm_medium=email&utm_source=footer
> 9. https://groups.google.com/d/optout
> 10. mailto:php-fig+u...@googlegroups.com
> 11. mailto:php...@googlegroups.com
> 12. https://groups.google.com/d/msgid/php-fig/40b460ed-fb4e-4460-b416-2607076a99b5%40googlegroups.com?utm_medium=email&utm_source=footer
> 13. https://groups.google.com/d/optout

Andreas Heigl

unread,
Jul 7, 2016, 6:06:14 AM7/7/16
to php...@googlegroups.com
Hi Andrew.

Am 07.07.16 um 11:47 schrieb Andrew Carter:
>
> @andreas
>
> Having a standardized interface for - for example - the OutputInterface
> would allow me to use a third-party library to format output in
> different CLI-tools.
>
>
> I'm not sure this is a significant enough programming problem to warrant
> a PSR. I'm trying to think of times when I would ever have wanted to do
> this - but I can only speak for my own experience (which is limited).
Having done several CLI-tools in the last time I was looking for a way
to do exactly that. But also, that's my personal idea but I believe it
would be a good idea to have a standardized interface to be able to use
third-party tools.
>
> Or I could use third-party libraries to filter and validate input
> using a HTTP-like Middleware-approach.
>
>
> Interesting, but this isn't a console PSR - this is a separate
> filter/validate middleware PSR.
A PSR for a CLI-Interface in my eyes should includ interfaces for input
and output handling similar to PSR-7. And with such a standardized
interface it would be possible to implement validation/filtering using
middlewares. It would be even more interesting to have ONE interface for
CLI AND HTTP-Middleware, but that's far to complicated in my eyes and
wouldn't justify the effort.

>
> That surely can all be achieved using plain PHP-functionality, but
> having a certain layer of abstraction would make it much easier for
> me to write the main business-logic without always having to
> implement all the addon stuff like validating input, howe to format
> the output, etc.
>
>
> Again, I'm not really convinced there is any down side here from
> coupling to say Symfony Console (or an alternative). Composer vendor
> binaries allow you to provide as many executable commands as you like
> from different dependencies.
I was more talking about me implementing a business-logic that others
can implement. And then it would be much easier to have one set of
interfaces to be implemented instead of enabling the busines-logic for
different CLI-providers. Or the user using the logic will have to create
the command by himself and handle invocation of the logic herself.

Personally I'm absolutely in favour of creating a certain
standardization for CLI-tools but there seems to be need to further
define WHAT should be standardized and what not.

I'll try to create a set of interfaces to have something more
substantial to talk about.

Cheers

Andreas

Stefano Torresi

unread,
Jul 7, 2016, 8:58:40 AM7/7/16
to php...@googlegroups.com
I think starting with just a Command interface would be best, and possibly leaving the executor to a different PSR (or even multiple PSRs, like a generic CommandBus rather than a CLI specific one).

The main use case is that there are already plenty of vendor specific implementations and adapters in the wild.

I don't agree with Andrew's point about limiting innovation. I reckon commands are much simpler to model than HTTP messages; the API would be minimal, so it shouldn't impose relevant limitations to implementors.

I'm not even sure what is left to innovate in CLI applications, as they've always been pretty much the same since the dawn of shells: invoke by name, may accept input (arguments and/or stream), may provide output, will provide an exit code.
Am I missing anything?

Furthermore, at end of the day its always a Recommendation; nothing prevents anyone from doing their own thing.

For example, Python has a comprehensive standard library for everything Andrew mentioned (stdin, stdout, stderr, argc, argc, cwd), with multiple builtin modules around the same details (e.g. getopts and argparse). Has that prevented any innovation in Python CLI applications? Nope, I'm sure there some exotic packages to parse CLI arguments in PyPI.

And we're not even proposing implementations here.

Daniel Plainview

unread,
Jul 9, 2016, 8:43:47 AM7/9/16
to PHP Framework Interoperability Group
> like a generic CommandBus rather than a CLI specific one
Please, don't mix up things. CommandBus has nothing to do with CLI Command. 

CLI Command is just UI detail exactly like HTTP controllers.
They are not place for business logic.
This problem is already known as https://en.wikipedia.org/wiki/Magic_pushbutton anti-pattern.
Thus, it's better to ask sane API (decoupled from UI) from mentioned vendors (Doctrine and others) in order to make things
instead of asking abstract CLI commands.

Stefano Torresi

unread,
Jul 9, 2016, 9:23:42 AM7/9/16
to php...@googlegroups.com
Il giorno sab 9 lug 2016 alle ore 14:43 Daniel Plainview <daniel...@gmail.com> ha scritto:
> like a generic CommandBus rather than a CLI specific one
Please, don't mix up things. CommandBus has nothing to do with CLI Command. 

I am very aware of the difference, in fact I was talking about different proposals, while starting from a baseline abstraction.
 
CLI Command is just UI detail exactly like HTTP controllers.
They are not place for business logic.
This problem is already known as https://en.wikipedia.org/wiki/Magic_pushbutton anti-pattern.

This has nothing to do with my suggestion. Again, I was suggesting to start with a simple interface.
I never suggested conflating commands with business logic, where did you get that from?
 
Thus, it's better to ask sane API (decoupled from UI) from mentioned vendors (Doctrine and others) in order to make things
instead of asking abstract CLI commands.

I'm not sure I understand.
All there is to a PSR is a specification document and a set of interfaces. This *is* about abstractions.

Daniel Plainview

unread,
Jul 9, 2016, 6:18:22 PM7/9/16
to PHP Framework Interoperability Group
> I am very aware of the difference, in fact I was talking about different proposals, while starting from a baseline abstraction.

Well, still, I'm not sure how these two different concepts may have the same "baseline abstraction".
Even if interfaces for command message and for CLI command would accidentally look identically, they are not related.
They are very different domains and trying to find "baseline abstraction" for non-related domains is weird idea for me.

"The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise".
And generic CommandInterface w/o context (CLI, Command message pattern, GoF Command pattern, ...) is vague interface, hence wrong abstraction.

> I never suggested conflating commands with business logic, where did you get that from?
Sorry for this confusion, second part of my message was directed to participants above.
Reply all
Reply to author
Forward
0 new messages