Skip to content

Commit

Permalink
Merge pull request #48 from veewee/feature-progressbar
Browse files Browse the repository at this point in the history
Introducing Events, Progress and a run command.
Fixes #46, #33, #20, #42.
  • Loading branch information
veewee committed Oct 26, 2015
2 parents 18d83ee + 091ae9c commit 8457213
Show file tree
Hide file tree
Showing 39 changed files with 933 additions and 31 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,4 @@ install:
- composer update --prefer-dist --no-scripts --no-interaction

script:
- ./vendor/bin/phpcs --standard=PSR2 src
- ./vendor/bin/phpspec run

- ./bin/grumphp run
80 changes: 76 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ You will see following message in the composer logs:

To make GrumPHP even more awesome, it will suggest installing some extra packages:

- squizlabs/php_codesniffer : ~2.3
- behat/behat : ~3.0
- fabpot/php-cs-fixer: ~1.10
- phpspec/phpspec : ~2.1
- phpunit/phpunit : ~4.5
- roave/security-advisories : dev-master@dev
- squizlabs/php_codesniffer : ~2.3

GrumPHP will never push you into using a specific task. You can choose the tasks that fit your needs, and activate or
deactivate any task in no time!
Expand Down Expand Up @@ -70,6 +72,29 @@ The only downfall is that you will have to initialize the git hook manually:
php ./vendor/bin/grumphp git:init --config=path/to/grumphp.yml
```

### Global installation

It is possible to install or update GrumPHP on your system with following commands:

```sh
composer global require phpro/grumphp
composer global update phpro/grumphp
```

This will install the `grumphp` executable in the `~/.composer/vendor/bin` folder.
Make sure to add this folder to your system `$PATH` variable:

```
# .zshrc or .bashrc
export PATH="$HOME/.composer/vendor/bin:$PATH"
```

That's all! The `grumphp` command will be available on your CLI and will be used by default.

**Note:** that you might want to re-initialize your project git hooks to make sure the system-wide executable is being used. Run the `grumphp git:init` command in the project directory.

**Note:** When you globally installed 3rd party tools like e.g. `phpunit`, those will also be used instead of the composer executables.

## Build your own conventions checker

You can see [example](https://github.com/linkorb/conventions-checker)
Expand Down Expand Up @@ -345,6 +370,7 @@ composer require --dev leaphub/phpcs-symfony2-standard
Following this, you can add the path to your phpcs task.

```yml
# grumphp.yml
parameters:
tasks:
phpcs:
Expand Down Expand Up @@ -410,7 +436,7 @@ You just have to create a class that implements the `GrumPHP\Task\TaskInterface`
Next register it to the service manager and add your task configuration:

```yaml
# resources/config/services.yml
# grumphp.yml
parameters:
tasks:
myConfigKey:
Expand All @@ -431,17 +457,58 @@ You're welcome!

You just registered your custom task in no time! Pretty cool right?!

## Events

It is possible to hook in to GrumPHP with events.
Internally the Symfony event dispatcher is being used.
This means it can be configured just like you would in Symfony:

```yml
# grumphp.yml
services:
listener.some_listener:
class: MyNamespace\EventListener\MyListener
tags:
- { name: grumphp.event_listener, event: grumphp.runner.run }
- { name: grumphp.event_listener, event: grumphp.runner.run, method: customMethod, priority: 10 }
listener.some_subscriber:
class: MyNamespace\EventSubscriber\MySubscriber
tags:
- { name: grumphp.event_subscriber }
```

Following events are triggered during execution:

| Event name | Event class | Triggered
| ----------------------- | ----------------- | ----------
| grumphp.task.run | TaskEvent | before a task is executed
| grumphp.task.failed | TaskFailedEvent | when a task fails
| grumphp.task.complete | TaskEvent | when a task succeeds
| grumphp.runner.run | RunnerEvent | before the tasks are executed
| grumphp.runner.failed | RunnerFailedEvent | when one task failed
| grumphp.runner.complete | RunnerEvent | when all tasks succeed


## Roadmap

Following tasks are still on the roadmap:

- composer.json and composer.lock need to be committed at the same time
- composer validate command
- phpmd
- phpcpd
- phpdcd
- twig lint
- json lint
- yaml lint
- xml lint / dtd validation
- grunt tests
- gulp tests
- npm test tests
- ...

In a future version, it will also be possible to use GrumPHP as a Continious Integration tool.
New features or bugfixes can be logged at the [https://github.com/phpro/grumphp/issues](issues list).
Want to help out? Feel free to contact us!


# Execution

Expand All @@ -450,8 +517,13 @@ GrumPHP will be triggered with GIT hooks. However, you can execute the trigger a

```sh
php ./vendor/bin/grumphp git:pre-commit
php ./vendor/bin/grumphp git:commit-msg
```

If you want to run the tests on the full codebase, you can run the command:
```sh
php ./vendor/bin/grumphp run
```

# Compatibility

Expand Down
12 changes: 7 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"composer-plugin-api": "~1.0",
"symfony/console": "^2.4",
"symfony/expression-language": "^2.4",
"symfony/event-dispatcher": "^2.4",
"symfony/process": "^2.4",
"symfony/filesystem": "^2.4",
"symfony/finder": "^2.4",
Expand All @@ -25,11 +26,12 @@
"fabpot/php-cs-fixer": "~1.0"
},
"suggest": {
"roave/security-advisories": "Lets GrumPHP be sure that there are no known security issues.",
"squizlabs/php_codesniffer": "Lets GrumPHP sniff on your code.",
"phpspec/phpspec": "Lets GrumPHP spec your code.",
"phpunit/phpunit": "Lets GrumPHP run your unit tests.",
"fabpot/php-cs-fixer": "Lets GrumPHP automatically fix your codestyle."
"behat/behat": "Lets GrumPHP validate your project features.",
"fabpot/php-cs-fixer": "Lets GrumPHP automatically fix your codestyle.",
"phpspec/phpspec": "Lets GrumPHP spec your code.",
"phpunit/phpunit": "Lets GrumPHP run your unit tests.",
"squizlabs/php_codesniffer": "Lets GrumPHP sniff on your code.",
"roave/security-advisories": "Lets GrumPHP be sure that there are no known security issues."
},
"authors": [
{
Expand Down
9 changes: 9 additions & 0 deletions resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ services:
class: GrumPHP\Configuration\GrumPHP
arguments: [@service_container]

event_dispatcher:
class: Symfony\Component\EventDispatcher\EventDispatcher

filesystem:
class: Symfony\Component\Filesystem\Filesystem

Expand All @@ -29,6 +32,8 @@ services:

task_runner:
class: GrumPHP\Runner\TaskRunner
arguments:
- @event_dispatcher

locator.external_command:
class: GrumPHP\Locator\ExternalCommand
Expand All @@ -38,6 +43,10 @@ services:
class: GrumPHP\Locator\ChangedFiles
arguments: [@git.repository]

locator.registered_files:
class: GrumPHP\Locator\RegisteredFiles
arguments: [@git.repository]

task.phpcs:
class: GrumPHP\Task\Phpcs
arguments:
Expand Down
16 changes: 14 additions & 2 deletions spec/GrumPHP/Console/Helper/TaskRunnerHelperSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
use GrumPHP\Task\Context\ContextInterface;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Filesystem\Filesystem;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class TaskRunnerHelperSpec extends ObjectBehavior
{
function let(TaskRunner $taskRunner, HelperSet $helperSet, PathsHelper $pathsHelper)
function let(TaskRunner $taskRunner, EventDispatcherInterface $eventDispatcher, HelperSet $helperSet, PathsHelper $pathsHelper)
{
$this->beConstructedWith($taskRunner);
$this->beConstructedWith($taskRunner, $eventDispatcher);

$helperSet->get(PathsHelper::HELPER_NAME)->willreturn($pathsHelper);
$this->setHelperSet($helperSet);
Expand All @@ -35,4 +36,15 @@ function it_should_return_success_code_during_exceptions(OutputInterface $output
$taskRunner->run($context)->shouldBeCalled();
$this->run($output, $context)->shouldReturn(TaskRunnerHelper::CODE_SUCCESS);
}

function it_should_add_a_progress_listener_during_run(
OutputInterface $output,
TaskRunner $taskRunner,
ContextInterface $context,
EventDispatcherInterface $eventDispatcher
) {
$taskRunner->run($context)->shouldBeCalled();
$eventDispatcher->addSubscriber(Argument::type('GrumPHP\Event\Subscriber\ProgressSubscriber'))->shouldBeCalled();
$this->run($output, $context)->shouldReturn(TaskRunnerHelper::CODE_SUCCESS);
}
}
30 changes: 30 additions & 0 deletions spec/GrumPHP/Event/RunnerEventSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace spec\GrumPHP\Event;

use GrumPHP\Collection\TasksCollection;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class RunnerEventSpec extends ObjectBehavior
{
function let(TasksCollection $tasks)
{
$this->beConstructedWith($tasks);
}

function it_is_initializable()
{
$this->shouldHaveType('GrumPHP\Event\RunnerEvent');
}

function it_is_an_event()
{
$this->shouldHaveType('Symfony\Component\EventDispatcher\Event');
}

function it_has_tasks(TasksCollection $tasks)
{
$this->getTasks()->shouldBe($tasks);
}
}
35 changes: 35 additions & 0 deletions spec/GrumPHP/Event/RunnerFailedEventSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace spec\GrumPHP\Event;

use GrumPHP\Collection\TasksCollection;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class RunnerFailedEventSpec extends ObjectBehavior
{
function let(TasksCollection $tasks)
{
$this->beConstructedWith($tasks, array());
}

function it_is_initializable()
{
$this->shouldHaveType('GrumPHP\Event\RunnerFailedEvent');
}

function it_is_a_runner_event()
{
$this->shouldHaveType('GrumPHP\Event\RunnerEvent');
}

function it_has_tasks(TasksCollection $tasks)
{
$this->getTasks()->shouldBe($tasks);
}

function it_should_contain_the_error_messages()
{
$this->getMessages()->shouldBe(array());
}
}
69 changes: 69 additions & 0 deletions spec/GrumPHP/Event/Subscriber/ProgressSubscriberSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace spec\GrumPHP\Event\Subscriber;

use GrumPHP\Collection\TasksCollection;
use GrumPHP\Event\RunnerEvent;
use GrumPHP\Event\TaskEvent;
use GrumPHP\Task\TaskInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\OutputInterface;

class ProgressSubscriberSpec extends ObjectBehavior
{
function let(OutputInterface $output, ProgressBar $progressBar)
{
$this->beConstructedWith($output, $progressBar);
}

function it_is_initializable()
{
$this->shouldHaveType('GrumPHP\Event\Subscriber\ProgressSubscriber');
}

function it_is_an_event_subscriber()
{
$this->shouldImplement('Symfony\Component\EventDispatcher\EventSubscriberInterface');
}

function it_should_subscribe_to_events()
{
$this->getSubscribedEvents()->shouldBeArray();
}

function it_starts_progress(ProgressBar $progressBar, RunnerEvent $event, TasksCollection $tasks)
{
$tasks->count()->willReturn(2);
$event->getTasks()->willReturn($tasks);

$progressBar->setFormat(Argument::type('string'))->shouldBeCalled();
$progressBar->setOverwrite(false)->shouldBeCalled();
$progressBar->setMessage(Argument::type('string'))->shouldBeCalled();
$progressBar->start(2)->shouldBeCalled();

$this->startProgress($event);
}

function it_should_advance_progress(ProgressBar $progressBar, TaskEvent $event, TaskInterface $task)
{
$event->getTask()->willReturn($task);

$progressBar->setFormat(Argument::type('string'))->shouldBeCalled();
$progressBar->setOverwrite(false)->shouldBeCalled();
$progressBar->setMessage(Argument::type('string'))->shouldBeCalled();
$progressBar->advance()->shouldBeCalled();

$this->advanceProgress($event);
}

function it_finishes_progress(OutputInterface $output, ProgressBar $progressBar, RunnerEvent $event)
{
$progressBar->setOverwrite(false)->shouldBeCalled();
$progressBar->finish()->shouldBeCalled();
$output->writeln('')->shouldBeCalled();

$this->finishProgress($event);
}
}
Loading

0 comments on commit 8457213

Please sign in to comment.