Factory::getCommandName()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 3
cts 3
cp 1
rs 9.7998
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 3
1
<?php
2
3
namespace SilverLeague\Console\Command;
4
5
use SilverLeague\Console\Command\Dev\Tasks\AbstractTaskCommand;
6
use SilverLeague\Console\Framework\ConsoleBase;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Dev\BuildTask;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Console\Style\SymfonyStyle;
13
14
/**
15
 * The Command Factory class is reponsible for converting a SilverStripe BuildTask into a Symfony Console Command
16
 *
17
 * @package silverstripe-console
18
 * @author  Robbie Averill <[email protected]>
19
 */
20
class Factory extends ConsoleBase
21
{
22
    /**
23
     * Given a BuildTask, convert it to a runnable Symfony Command
24
     *
25
     * @param  BuildTask $task
26
     * @return SilverStripeCommand|false
27
     */
28 2
    public function getCommandFromTask(BuildTask $task)
29
    {
30 2
        if (!is_callable([$task, 'run']) || !$task->isEnabled()) {
31
            return false;
32
        }
33
34 2
        $commandName = $this->getCommandName($task);
35 2
        if (empty($commandName)) {
36 2
            return false;
37 2
        }
38 2
39 2
        $command = new AbstractTaskCommand($commandName);
40
        $command->setApplication($this->getApplication());
41 2
        $command->setTask($task);
42
        $command->setDescription($task->getTitle());
43
        $command->setHelp($task->getDescription());
44
        $command->setCode($this->getTaskAsClosure($command));
45
46
        return $command;
47
    }
48
49 2
    /**
50
     * Get a Command name from the BuildTask segment
51 2
     *
52 2
     * @return string
53
     */
54 2
    public function getCommandName(BuildTask $task)
55 2
    {
56
        $taskSegment = Config::inst()->get(get_class($task), 'segment');
57 2
        if (empty($taskSegment)) {
58
            $taskSegment = get_class($task);
59
        }
60
61
        $segment = $this->getFriendlySegment($taskSegment);
62
        if (empty($segment)) {
63
            return '';
64
        }
65
66
        return sprintf('dev:tasks:%s', $segment);
67
    }
68 2
69
    /**
70
     * Convert the SilverStripe task names into a common, Symfony console style command with
71
     * dashes between capital letters, backslashes removed and all lowercase
72
     *
73
     * @param string $segment
74
     * @return string
75 2
     */
76
    public function getFriendlySegment($segment)
77
    {
78
        // Convert backslashes (from namespaced classes) to dashes
79
        $segment = str_replace('\\', '-', $segment);
80
81
        // Add dashes before any uppercase letter and return as lowercase
82
        $segment = strtolower(preg_replace('/(?<=[a-z])([A-Z]+)/', '-$1', $segment));
83
84
        // We don't really need "-task" on the end of every task.
85
        if (substr($segment, -5, 5) === '-task') {
86
            $segment = substr($segment, 0, strlen($segment) - 5);
87
        }
88
89
        return $segment;
90
    }
91
92
    /**
93
     * Get the BuildTask functionality as a closure
94
     *
95
     * @param  AbstractTaskCommand $command
96
     * @return callable
97
     */
98
    public function getTaskAsClosure(AbstractTaskCommand $command)
99
    {
100
        return function (InputInterface $input, OutputInterface $output) use ($command) {
101
            $io = new SymfonyStyle($input, $output);
102
103
            $io->title(sprintf('%s: %s', $command->getName(), $command->getDescription()));
104
            $io->section('Running...');
105
106
            $command->getTask()->run(new HTTPRequest('GET', '/'));
107
        };
108
    }
109
}
110