composer/composer — pull request #1186 by johnkary (2012-10-06 04:50:00+00:00)
Title: Add ability to invoke CLI commands on Composer scripts

This new functionality allows command-line tasks to be executed when any Composer event is fired. It currently preserves backwards compatibility with the ability to intermix PHP callbacks and CLI commands in the same array of event script commands. It also includes some expansion of the scripts documentation and has also been updated to explain the new feature.

This ability to execute CLI commands with events exists in `npm`, and while this feature addition does not fully replicate it, it provides the basic ability to start doing so.

Jordi and I discussed this feature at the hack day during SymfonyLive 2012 in San Francisco and I implemented it there with some feedback from him.

### Basic Usage

{
"scripts": {
"post-install-cmd": [
"phpunit -c path/to/phpunit.xml"
]
}
}

## Use Cases

### Test suite execution

My initial use case for my own needs was to run my project's functional and unit tests after pulling in new versions of my dependencies to make sure all tests still pass.

### Integrate with other package managers

Some projects offload package management for Chef cookbooks (e.g. [librarian-chef](https://github.com/applicationsonline/librarian)), while many others also require frontend web assets.

There are currently [several frontend package managers](https://github.com/wilmoore/frontend-packagers) vying for a top spot, but I don't think any one has taken hold as a standard. Jordi has [written on this in the past](http://nelm.io/blog/2012/05/an-appeal-to-all-package-managers/) and it would be great if someday we could manage our frontend assets more natively through Composer. But for now each frontend package manager operates in mostly its own ecosystem.

The functionality in this PR allows Composer to delegate to your project's chosen frontend package manager, and to pull in all of your frontend assets as part of updating your PHP dependencies. This allows our reliance on frontend package management to evolve independently from Composer.

### Delegate to other command-execution tools

Many projects leverage additional command-line tasks from tools like Phing, Capifony, Rake, custom shell scripts, etc. You could go wild and integrate deployment as part of running Composer if that fits your project and team's mindset.

### Lay groundwork for other command-line integrations

Feature request #1055 asks for a reliable way to execute a project's test suite. A command like `composer test` could executes a project's test suite. So a developer could jump into any project that uses Composer and instantly know how to run the test suite. With PHPUnit 3.7.3 now ([properly](http://twitter.com/s_bergmann/status/254296949950386177)) available via Composer, now seems like the right time to add `composer test` functionality to Composer:

{
// NOT IMPLEMENTED IN THIS PR, EXAMPLE ONLY
"tests": [
"phpunit -c path/to/phpunit.xml"
],
}

## Further Improvements

### Separate lists for PHP and CLI commands

I think the mixing of PHP callbacks and CLI commands in the same JSON array is a bit error-prone. Right now the code simply checks if the string contains `::` and tries to execute it as a PHP callback, else tries to execute it as a CLI command. Theoretically a valid CLI command could contain `::` somewhere in the command causing the wrong execution path.

Splitting a script's events into two members would make for not only a cleaner approach in the code (no `if` statement required) but also easier to predict results:

{
"scripts": {
"post-install-cmd": {
"php": [
"MyVendor\\MyClass::someMethodName"
],
"commands": [
"phpunit -c path/to/phpunit.xml"
]
}
}
}

### Better support for executing CLI commands

NPM supports [much more in the way of CLI command execution](https://npmjs.org/doc/scripts.html), some of which our users may require.

Right now this functionality passes CLI commands to the [Symfony Process](http://symfony.com/doc/master/components/process.html) component. Hopefully this component provides good compatibility for CLI execution on multiple platforms (e.g. Windows). **I haven't tested any of this code against a Windows platform.**

Any limitations in the CLI functionality in Composer will probably be traced back to the Process component.

### Tests for CLI output

This PR includes a test for the "happy path" of executing a CLI command, but I could not figure out how best to write a test to verify the console output was correctly passed to the IO stream. I have pushed my work in progress for writing this test to a branch in my fork. Your help in writing a test for this, or making changes to make it more testable, would be appreciated: