Skip to content

Commit

Permalink
Merge pull request #587 from paslandau/580_seventies
Browse files Browse the repository at this point in the history
 Provide option to run a single/list of tasks from the config
  • Loading branch information
Landerstraeten authored May 16, 2019
2 parents 252eba9 + 83327e1 commit 2d6d34c
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 9 deletions.
9 changes: 9 additions & 0 deletions doc/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@ php ./vendor/bin/grumphp run --testsuite=mytestsuite

This command can also be used for continious integration.
More information about the testsuites can be found in the [testsuites documentation](testsuites.md).

If you want to run only a subset of the configured tasks, you can run the command with the `--tasks` option:

```sh
php ./vendor/bin/grumphp run --tasks=task1,task2
```

The `--tasks` value has to be a comma-separated string of task names that match the keys in the `tasks` section
of the `grumphp.yml` file. See [#580](https://github.com/phpro/grumphp/issues/580) for a more exhaustive explanation.
40 changes: 40 additions & 0 deletions spec/Collection/TasksCollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,46 @@ function it_can_filter_by_empty_testsuite(TaskInterface $task1, TaskInterface $t
$tasks[1]->shouldBe($task2);
}

function it_can_filter_by_task_names(TaskInterface $task1, TaskInterface $task2)
{
$task1->getName()->willReturn('task1');
$task2->getName()->willReturn('task2');
$tasks = ['task1'];

$result = $this->filterByTaskNames($tasks);
$result->shouldBeAnInstanceOf(TasksCollection::class);
$result->count()->shouldBe(1);
$tasks = $result->toArray();
$tasks[0]->shouldBe($task1);
}

function it_can_filter_by_duplicate_task_names(TaskInterface $task1, TaskInterface $task2)
{
$task1->getName()->willReturn('task1');
$task2->getName()->willReturn('task2');
$tasks = ['task1', 'task1'];

$result = $this->filterByTaskNames($tasks);
$result->shouldBeAnInstanceOf(TasksCollection::class);
$result->count()->shouldBe(1);
$tasks = $result->toArray();
$tasks[0]->shouldBe($task1);
}

function it_can_filter_by_empty_task_names(TaskInterface $task1, TaskInterface $task2)
{
$task1->getName()->willReturn('task1');
$task2->getName()->willReturn('task2');
$tasks = [];

$result = $this->filterByTaskNames($tasks);
$result->shouldBeAnInstanceOf(TasksCollection::class);
$result->count()->shouldBe(2);
$tasks = $result->toArray();
$tasks[0]->shouldBe($task1);
$tasks[1]->shouldBe($task2);
}

function it_should_sort_on_priority(TaskInterface $task1, TaskInterface $task2, TaskInterface $task3, GrumPHP $grumPHP)
{
$this->beConstructedWith([$task1, $task2, $task3]);
Expand Down
14 changes: 14 additions & 0 deletions spec/Runner/TaskRunnerContextSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ function it_has_no_test_suite(ContextInterface $context)
$this->getTestSuite()->shouldBe(null);
}

function it_has_no_tasks()
{
$this->hasTasks()->shouldBe(false);
$this->getTasks()->shouldBe([]);
}

function it_has_tasks(ContextInterface $context, TestSuiteInterface $testSuite)
{
$tasks = ["task_1"];
$this->beConstructedWith($context, $testSuite, $tasks);
$this->hasTasks()->shouldBe(true);
$this->getTasks()->shouldBe($tasks);
}

function it_knows_to_skip_the_success_message()
{
$this->skipSuccessOutput()->shouldBe(false);
Expand Down
1 change: 1 addition & 0 deletions spec/Runner/TaskRunnerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function let(

$runnerContext->getTaskContext()->willReturn($taskContext);
$runnerContext->getTestSuite()->willReturn(null);
$runnerContext->getTasks()->willReturn([]);

$task1->getName()->willReturn('task1');
$task1->canRunInContext($taskContext)->willReturn(true);
Expand Down
24 changes: 24 additions & 0 deletions spec/Util/StrSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace spec\GrumPHP\Util;

use PhpSpec\ObjectBehavior;

class StrSpec extends ObjectBehavior
{
function it_should_find_a_part_of_a_string_by_one_of_the_provided_needles()
{
$this::containsOneOf('a;randomText-written by me', ['a', 'me'])->shouldBe(true);
$this::containsOneOf('a;randomText-written by me', ['Text'])->shouldBe(true);

$this::containsOneOf('a;randomText-written by me', ['this does not exist'])->shouldBe(false);
$this::containsOneOf('a;randomText-written by me', ['text'])->shouldBe(false);
}

function it_should_split_a_string_by_a_delimiter_and_result_in_a_unique_list()
{
$this::explodeWithCleanup(',', ' a random,list, of things ')->shouldBe([
'a random', 'list', 'of things'
]);
}
}
16 changes: 15 additions & 1 deletion src/Collection/TasksCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,28 @@ public function filterByContext(ContextInterface $context): self
public function filterByTestSuite(TestSuiteInterface $testSuite = null): self
{
if (null === $testSuite) {
return new self($this->toArray());
return $this;
}

return $this->filter(function (TaskInterface $task) use ($testSuite) {
return \in_array($task->getName(), $testSuite->getTaskNames(), true);
});
}

/**
* @param string[] $tasks
*/
public function filterByTaskNames(array $tasks): self
{
if (empty($tasks)) {
return $this;
}

return $this->filter(function (TaskInterface $task) use ($tasks) {
return \in_array($task->getName(), $tasks, true);
});
}

/**
* This method sorts the tasks by highest priority first.
*/
Expand Down
13 changes: 12 additions & 1 deletion src/Console/Command/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use GrumPHP\Locator\RegisteredFiles;
use GrumPHP\Runner\TaskRunnerContext;
use GrumPHP\Task\Context\RunContext;
use GrumPHP\Util\Str;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand Down Expand Up @@ -51,16 +52,26 @@ protected function configure()
'Specify which testsuite you want to run.',
null
);
$this->addOption(
'tasks',
null,
InputOption::VALUE_REQUIRED,
'Specify which tasks you want to run (comma separated). Example --tasks=task1,task2',
null
);
}

public function execute(InputInterface $input, OutputInterface $output)
{
$files = $this->getRegisteredFiles();
$testSuites = $this->grumPHP->getTestSuites();

$tasks = Str::explodeWithCleanup(',', $input->getOption("tasks") ?? '');

$context = new TaskRunnerContext(
new RunContext($files),
(bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null
(bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null,
$tasks
);

return $this->taskRunner()->run($output, $context);
Expand Down
1 change: 1 addition & 0 deletions src/Runner/TaskRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public function run(TaskRunnerContext $runnerContext): TaskResultCollection
$tasks = $this->tasks
->filterByContext($runnerContext->getTaskContext())
->filterByTestSuite($runnerContext->getTestSuite())
->filterByTaskNames($runnerContext->getTasks())
->sortByPriority($this->grumPHP);
$taskResults = new TaskResultCollection();

Expand Down
31 changes: 25 additions & 6 deletions src/Runner/TaskRunnerContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,21 @@ class TaskRunnerContext
/**
* @var null|TestSuiteInterface
*/
private $testSuite = null;
private $testSuite;

/**
* TaskRunnerContext constructor.
* @var string[]
*/
public function __construct(ContextInterface $taskContext, TestSuiteInterface $testSuite = null)
{
private $tasks;

public function __construct(
ContextInterface $taskContext,
TestSuiteInterface $testSuite = null,
array $tasks = []
) {
$this->taskContext = $taskContext;
$this->testSuite = $testSuite;
$this->tasks = $tasks;
}

public function getTaskContext(): ContextInterface
Expand All @@ -54,18 +60,31 @@ public function hasTestSuite(): bool
}

/**
* @return TestSuiteInterface|null
* @return null|TestSuiteInterface
*/
public function getTestSuite()
{
return $this->testSuite;
}

/**
* @param TestSuiteInterface|null $testSuite
* @param null|TestSuiteInterface $testSuite
*/
public function setTestSuite(TestSuiteInterface $testSuite)
{
$this->testSuite = $testSuite;
}

/**
* @return string[]
*/
public function getTasks(): array
{
return $this->tasks;
}

public function hasTasks(): bool
{
return !empty($this->tasks);
}
}
13 changes: 12 additions & 1 deletion src/Util/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace GrumPHP\Util;

class Str
final class Str
{
/**
* String contains one of the provided needles
Expand All @@ -17,4 +17,15 @@ public static function containsOneOf(string $haystack, array $needles): bool

return false;
}

/**
* Split $value on ",", trim the individual parts and
* de-deduplicate the remaining values
*/
public static function explodeWithCleanup(string $delimiter, string $value): array
{
return array_unique(array_map(function (string $value) {
return trim($value);
}, explode($delimiter, $value)));
}
}

0 comments on commit 2d6d34c

Please sign in to comment.