Passed
Push — master ( f2e14b...2db21b )
by Robbie
04:12
created

Factory::getFriendlySegment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
ccs 1
cts 1
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 2
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
    public function getFriendlySegment($segment)
70
    {
71
        // Convert backslashes (from namespaced classes) to dashes
72
        $segment = str_replace('\\', '-', $segment);
73
74
        // Add dashes before any uppercase letter and return as lowercase
75 2
        $segment = strtolower(preg_replace('/(?<=[a-z])([A-Z]+)/', '-$1', $segment));
76
77
        // We don't really need "-task" on the end of every task.
78
        if (substr($segment, -5, 5) === '-task') {
79
            $segment = substr($segment, 0, strlen($segment) - 5);
80
        }
81
82
        return $segment;
83
    }
84
85
    /**
86
     * Get the BuildTask functionality as a closure
87
     *
88
     * @param  AbstractTaskCommand $command
89
     * @return callable
90
     */
91
    public function getTaskAsClosure(AbstractTaskCommand $command)
92
    {
93
        return function (InputInterface $input, OutputInterface $output) use ($command) {
94
            $io = new SymfonyStyle($input, $output);
95
96
            $io->title(sprintf('%s: %s', $command->getName(), $command->getDescription()));
97
            $io->section('Running...');
98
99
            $command->getTask()->run(new HTTPRequest('GET', '/'));
100
        };
101
    }
102
}
103