Skip to content

Commit d5adba5

Browse files
author
Mike Fisher
committed
Refactor group commands in GroupCommand object
1 parent 0d3072b commit d5adba5

File tree

7 files changed

+175
-51
lines changed

7 files changed

+175
-51
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"task/phpspec": "~0.1",
2222
"mikey179/vfsStream": "~1.2",
2323
"henrikbjorn/phpspec-code-coverage" : "1.0.*@dev",
24+
"bossa/phpspec2-expect": "~1.0",
2425
"satooshi/php-coveralls": "~0.6"
2526
},
2627
"autoload": {

spec/Task/Console/Command/CommandSpec.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
use Symfony\Component\Console\Input\Input;
99
use Task\Plugin\Console\Output\Output;
10+
use Task\Console\Command\Command;
11+
use Symfony\Component\Console\Application;
12+
use Symfony\Component\Console\Helper\HelperSet;
13+
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Output\OutputInterface;
1015

1116
class CommandSpec extends ObjectBehavior
1217
{
@@ -61,4 +66,16 @@ function it_should_throw_on_no_property(Input $input)
6166
$input->getOption('property')->willReturn([]);
6267
$this->shouldThrow('InvalidArgumentException')->duringGetProperty('foo', null, $input);
6368
}
69+
70+
function it_should_run_a_task_on_demand(Application $app, HelperSet $helperSet, Command $command, InputInterface $input, OutputInterface $output)
71+
{
72+
$app->getHelperSet()->willReturn($helperSet);
73+
$app->get('test')->willReturn($command);
74+
$this->setApplication($app);
75+
76+
$command->run($input, $output)->willReturn(123);
77+
78+
$this->runTask('test', $output, $input)->shouldReturn(123);
79+
}
80+
6481
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace spec\Task\Console\Command;
4+
5+
use PhpSpec\ObjectBehavior;
6+
use Prophecy\Argument;
7+
8+
use Task\Project;
9+
use Task\Console\Command\Command;
10+
use Symfony\Component\Console\Input\InputInterface;
11+
use Symfony\Component\Console\Output\OutputInterface;
12+
13+
class GroupCommandSpec extends ObjectBehavior
14+
{
15+
private $project;
16+
17+
function let()
18+
{
19+
$this->project = new Project('test');
20+
$this->beConstructedWith('test', $this->project, ['foo', 'bar']);
21+
}
22+
23+
function it_is_initializable()
24+
{
25+
$this->shouldHaveType('Task\Console\Command\GroupCommand');
26+
}
27+
28+
function it_should_resolve_dependencies()
29+
{
30+
$foo = $this->project->addTask('foo', function () {});
31+
$bar = $this->project->addTask('bar', ['baz'], function () {});
32+
$baz = $this->project->addTask('baz', function () {});
33+
34+
$this->getCommands()->shouldReturn([$foo, $baz, $bar]);
35+
}
36+
37+
function it_should_filter_dependencies()
38+
{
39+
$this->beConstructedWith('test', $this->project, ['baz', 'foo', 'bar']);
40+
41+
$foo = $this->project->addTask('foo', function () {});
42+
$bar = $this->project->addTask('bar', ['baz'], function () {});
43+
$baz = $this->project->addTask('baz', function () {});
44+
45+
$this->getCommands()->shouldReturn([$baz, $foo, $bar]);
46+
}
47+
48+
function it_should_run_commands(Project $project, Command $foo, Command $bar, InputInterface $input, OutputInterface $output)
49+
{
50+
$foo->getName()->willReturn('foo');
51+
$bar->getName()->willReturn('bar');
52+
53+
$project->resolveDependencies(Argument::any())->willReturn([]);
54+
$project->get('foo')->willReturn($foo);
55+
$project->get('bar')->willReturn($bar);
56+
57+
$this->beConstructedWith('test', $project, ['foo', 'bar']);
58+
59+
$foo->run($input, $output)->shouldBeCalled();
60+
$bar->run($input, $output)->shouldBeCalled();
61+
62+
$this->execute($input, $output);
63+
}
64+
}

spec/Task/ProjectSpec.php

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Prophecy\Argument;
88

99
use Symfony\Component\Console\Input\ArrayInput;
10-
use Task\Plugin\Console\Output\Output;
10+
use Symfony\Component\Console\Output\OutputInterface;
1111
use Symfony\Component\Console\Command\Command as BaseCommand;
1212
use Task\Console\Command\Command;
1313

@@ -35,15 +35,7 @@ function it_should_inject_a_container()
3535
})->shouldReturn($this->getContainer());
3636
}
3737

38-
function it_should_run_a_task_on_demand()
39-
{
40-
$this->addTask('test', function () {
41-
return 123;
42-
});
43-
$this->runTask('test')->shouldReturn(123);
44-
}
45-
46-
function it_should_run_plain_commands()
38+
function it_should_run_plain_commands(OutputInterface $output)
4739
{
4840
$command = new BaseCommand('test');
4941
$command->setCode(function () {
@@ -53,17 +45,17 @@ function it_should_run_plain_commands()
5345
$input = new ArrayInput(['command' => 'test']);
5446

5547
$this->add($command);
56-
$this->run($input)->shouldReturn(123);
48+
$this->run($input, $output)->shouldReturn(123);
5749
}
5850

59-
function it_should_run_a_task()
51+
function it_should_run_a_task(OutputInterface $output)
6052
{
6153
$this->addTask('test', function () {
6254
return 123;
6355
});
6456

6557
$input = new ArrayInput(['command' => 'test']);
66-
$this->run($input)->shouldReturn(123);
58+
$this->run($input, $output)->shouldReturn(123);
6759
}
6860

6961
function it_should_throw_on_no_args_to_parse()
@@ -139,52 +131,45 @@ function it_should_add_a_command()
139131
$this->run(new ArrayInput(['command' => 'test']))->shouldReturn(123);
140132
}
141133

142-
function it_should_alias_a_command()
134+
function it_should_alias_a_command(OutputInterface $output)
143135
{
144136
$command = new BaseCommand('test');
145137
$command->setCode(function () {
146138
return 123;
147139
});
148140

149141
$this->addTask('foo', $command);
150-
$this->run(new ArrayInput(['command' => 'foo']))->shouldReturn(123);
142+
$this->run(new ArrayInput(['command' => 'foo']), $output)->shouldReturn(123);
151143
}
152144

153-
function it_should_add_a_closure()
145+
function it_should_add_a_closure(OutputInterface $output)
154146
{
155147
$this->addTask('test', function () {
156148
return 123;
157149
});
158150

159-
$this->run(new ArrayInput(['command' => 'test']))->shouldReturn(123);
151+
$this->run(new ArrayInput(['command' => 'test']), $output)->shouldReturn(123);
160152
}
161153

162-
function it_should_inject_a_closure()
154+
function it_should_inject_a_closure(OutputInterface $output)
163155
{
164156
$this->getContainer()['foo'] = $foo = 123;
165157
$this->addTask('test', ['foo', function ($foo) {
166158
return $foo;
167159
}]);
168160

169-
$this->run(new ArrayInput(['command' => 'test']))->shouldReturn(123);
161+
$this->run(new ArrayInput(['command' => 'test']), $output)->shouldReturn(123);
170162
}
171163

172-
function it_should_add_a_group(Output $output)
164+
function it_should_add_a_group(OutputInterface $output)
173165
{
174-
$this->getContainer()['output'] = $output;
175-
$this->addTask('foo', ['output', function ($output) {
176-
$output->writeln('foo');
177-
return null;
178-
}]);
179-
180-
$this->addTask('bar', function () {
181-
return 123;
182-
});
166+
$this->addTask('foo', function () {});
167+
$this->addTask('bar', function () {});
168+
$group = $this->addTask('test', ['foo', 'bar']);
183169

184-
$this->addTask('test', ['foo', 'bar']);
185-
186-
$output->writeln('foo')->shouldBeCalled();
187-
$this->run(new ArrayInput(['command' => 'test']), $output)->shouldReturn(123);
170+
$group->shouldHaveType('Task\Console\Command\GroupCommand');
171+
$group->getProject()->shouldReturn($this);
172+
$group->getTasks()->shouldReturn(['foo', 'bar']);
188173
}
189174

190175
function it_should_throw_on_bad_work()
@@ -227,7 +212,7 @@ function it_should_normalize_dependencies()
227212
$test = $this->addTask('test', ['foo', 'bar'], function () {});
228213
$foo = $this->addTask('foo', ['bar'], function () {});
229214
$bar = $this->addTask('bar', function () {});
230-
$this->resolveDependencies($test)->shouldEqual([$foo, $bar]);
215+
$this->resolveDependencies($test)->shouldEqual([$bar, $foo]);
231216
}
232217

233218
function it_should_normalize_complex_dependencies()

src/Console/Command/Command.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Symfony\Component\Console\Command\Command as BaseCommand;
66
use Symfony\Component\Console\Input\InputInterface;
77
use Symfony\Component\Console\Input\InputOption;
8+
use Symfony\Component\Console\Input\ArrayInput;
89
use Symfony\Component\Console\Output\OutputInterface;
910

1011
class Command extends BaseCommand
@@ -68,4 +69,12 @@ public function setProperty($name, $value)
6869
$this->properties[$name] = $value;
6970
return $this;
7071
}
72+
73+
public function runTask($name, OutputInterface $output = null, InputInterface $input = null)
74+
{
75+
$input = $input ?: new ArrayInput(['command' => $name]);
76+
$output = $output ?: new Output;
77+
return $this->getApplication()->get($name)->run($input, $output);
78+
}
79+
7180
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Task\Console\Command;
4+
5+
use Task\Project;
6+
use Symfony\Component\Console\Input\InputInterface;
7+
use Symfony\Component\Console\Output\OutputInterface;
8+
9+
class GroupCommand extends Command
10+
{
11+
protected $project;
12+
protected $tasks;
13+
14+
public function __construct($name, Project $project, array $tasks)
15+
{
16+
parent::__construct($name);
17+
$this->project = $project;
18+
$this->tasks = $tasks;
19+
}
20+
21+
public function getProject()
22+
{
23+
return $this->project;
24+
}
25+
26+
public function getTasks()
27+
{
28+
return $this->tasks;
29+
}
30+
31+
public function getCommands()
32+
{
33+
$project = $this->getProject();
34+
35+
$commands = [];
36+
foreach ($this->getTasks() as $taskName) {
37+
$task = $project->get($taskName);
38+
$commands = array_values(array_unique(
39+
array_merge(
40+
$commands,
41+
$project->resolveDependencies($task),
42+
[$task]
43+
),
44+
SORT_REGULAR
45+
));
46+
}
47+
48+
return $commands;
49+
}
50+
51+
public function execute(InputInterface $input, OutputInterface $output)
52+
{
53+
$exitCode = 0;
54+
foreach ($this->getCommands() as $task) {
55+
$output->writeln("Running {$task->getName()}...");
56+
$task->run($input, $output);
57+
}
58+
59+
return $exitCode;
60+
}
61+
}

src/Project.php

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
use Symfony\Component\Console\Application;
66
use Symfony\Component\Console\Input\InputInterface;
7-
use Symfony\Component\Console\Input\ArrayInput;
87
use Symfony\Component\Console\Output\OutputInterface;
98
use Task\Plugin\Console\Output\Output;
109
use Symfony\Component\Console\Command\Command as BaseCommand;
1110
use Task\Console\Command\ShellCommand;
1211
use Task\Console\Command\Command;
12+
use Task\Console\Command\GroupCommand;
1313
use Task\Injector;
1414

1515
class Project extends Application
@@ -51,13 +51,6 @@ public function run(InputInterface $input = null, OutputInterface $output = null
5151
return parent::run($input, $output ?: new Output);
5252
}
5353

54-
public function runTask($name, OutputInterface $output = null)
55-
{
56-
$input = new ArrayInput(['command' => $name]);
57-
$output = $output ?: new Output;
58-
return $this->doRun($input, $output);
59-
}
60-
6154
protected function doRunCommand(BaseCommand $command, InputInterface $input, OutputInterface $output)
6255
{
6356
if (!($command instanceof Command)) {
@@ -70,6 +63,7 @@ protected function doRunCommand(BaseCommand $command, InputInterface $input, Out
7063
);
7164

7265
foreach ($run as $command) {
66+
$output->writeln("Running {$command->getName()}...");
7367
$exitCode = parent::doRunCommand($command, $input, $output);
7468
}
7569

@@ -164,14 +158,7 @@ public function addTask()
164158
} else {
165159
# Group
166160
#
167-
$project = $this;
168-
$task->setCode(function () use ($work, $project) {
169-
foreach ($work as $name) {
170-
$exitCode = $project->runTask($name);
171-
}
172-
173-
return $exitCode;
174-
});
161+
$task = new GroupCommand($name, $this, $work);
175162
}
176163

177164
break;
@@ -216,6 +203,6 @@ public function resolveDependencies(Command $task, $nested = false)
216203
);
217204
}
218205

219-
return $nested ? $run : array_reverse(array_unique($run, SORT_REGULAR));
206+
return $nested ? $run : array_unique(array_reverse($run), SORT_REGULAR);
220207
}
221208
}

0 commit comments

Comments
 (0)