RunCommand   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 10

Importance

Changes 0
Metric Value
wmc 23
cbo 10
dl 0
loc 170
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 18 1
B doExecute() 0 39 6
A formatBlock() 0 7 1
B fetchJobs() 0 16 7
B buildJobs() 0 29 6
A getProfile() 0 15 2
1
<?php
2
3
/**
4
 * This file is part of Bldr.io
5
 *
6
 * (c) Aaron Scherer <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE
10
 */
11
12
namespace Bldr\Block\Core\Command;
13
14
use Bldr\Application;
15
use Bldr\Block\Core\Service\Builder;
16
use Bldr\Command\AbstractCommand;
17
use Bldr\Definition\JobDefinition;
18
use Bldr\Definition\TaskDefinition;
19
use Bldr\Exception\BldrException;
20
use Bldr\Registry\JobRegistry;
21
use Symfony\Component\Console\Helper\FormatterHelper;
22
use Symfony\Component\Console\Input\InputArgument;
23
24
/**
25
 * @author Aaron Scherer <[email protected]>
26
 */
27
class RunCommand extends AbstractCommand
28
{
29
    /**
30
     * @var Builder $builder
31
     */
32
    private $builder;
33
34
    /**
35
     * @var JobRegistry $registry
36
     */
37
    private $registry;
38
39
    /**
40
     * {@inheritDoc}
41
     */
42
    protected function configure()
43
    {
44
        $this->setName('run')
45
            ->setDescription("Runs the project for the directory you are in. Must contain a config file.")
46
            ->addArgument('profile', InputArgument::OPTIONAL, 'Profile to run')
47
            ->setHelp(
48
                <<<EOF
49
50
The <info>%command.name%</info> builds the current project, using the config file in the root directory.
51
52
To use:
53
54
    <info>$ bldr %command.name% <profile_name></info>
55
56
EOF
57
            )
58
        ;
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64
    protected function doExecute()
65
    {
66
        $this->registry = $this->container->get('bldr.registry.job');
67
        $this->builder  = $this->container->get('bldr.builder');
68
        $profileName    = $this->input->getArgument('profile') ?: 'default';
69
70
        $this->output->writeln(["\n", Application::$logo, "\n"]);
71
72
        $profile = $this->getProfile($profileName);
73
74
        $projectFormat = [];
75
76
        if ($this->container->getParameter('name') !== '') {
77
            $projectFormat[] = sprintf("Building the '%s' project", $this->container->getParameter('name'));
78
        }
79
        if ($this->container->getParameter('description') !== '') {
80
            $projectFormat[] = sprintf(" - %s - ", $this->container->getParameter('description'));
81
        }
82
83
        $profileFormat = [sprintf("Using the '%s' profile", $profileName)];
84
        if (!empty($profile['description'])) {
85
            $profileFormat[] = sprintf(" - %s - ", $profile['description']);
86
        }
87
88
        $this->output->writeln(
89
            [
90
                "",
91
                $projectFormat === [] ? '' : $this->formatBlock($projectFormat, 'blue', 'black'),
92
                "",
93
                $this->formatBlock($profileFormat, 'blue', 'black'),
94
                ""
95
            ]
96
        );
97
98
        $this->fetchJobs($profile);
99
        $this->builder->runJobs($this->registry);
100
101
        $this->output->writeln(['', $this->formatBlock('Build Success!', 'green', 'white', true), '']);
102
    }
103
104
    /**
105
     * @param string|array $output
106
     * @param string       $background
107
     * @param string       $foreground
108
     *
109
     * @return string
110
     */
111
    private function formatBlock($output, $background, $foreground, $large = false)
112
    {
113
        /** @var FormatterHelper $formatter */
114
        $formatter = $this->getApplication()->getHelperSet()->get('formatter');
115
116
        return $formatter->formatBlock($output, "bg={$background};fg={$foreground}", $large);
117
    }
118
119
    /**
120
     * @param array $profile
121
     */
122
    private function fetchJobs(array $profile)
123
    {
124
        if (!empty($profile['uses']) && !empty($profile['uses']['before'])) {
125
            foreach ($profile['uses']['before'] as $name) {
126
                $this->fetchJobs($this->getProfile($name));
127
            }
128
        }
129
130
        $this->buildJobs($profile['jobs']);
131
132
        if (!empty($profile['uses']) && !empty($profile['uses']['after'])) {
133
            foreach ($profile['uses']['after'] as $name) {
134
                $this->fetchJobs($this->getProfile($name));
135
            }
136
        }
137
    }
138
139
    /**
140
     * @param string[] $names
141
     *
142
     * @throws \Exception
143
     * @return array
144
     */
145
    private function buildJobs(array $names)
146
    {
147
        $jobs = $this->container->getParameter('jobs');
148
        foreach ($names as $name) {
149
            if (!array_key_exists($name, $jobs)) {
150
                throw new BldrException(
151
                    sprintf(
152
                        "Job `%s` does not exist. Found: %s",
153
                        $name,
154
                        implode(', ', array_keys($jobs))
155
                    )
156
                );
157
            }
158
159
            $jobInfo     = $jobs[$name];
160
            $description = isset($jobInfo['description']) ? $jobInfo['description'] : "";
161
            $job         = new JobDefinition($name, $description);
162
163
            foreach ($jobInfo['tasks'] as $taskInfo) {
164
                $task = new TaskDefinition($taskInfo['type']);
165
                $task->setContinueOnError(isset($taskInfo['continueOnError']) ? $taskInfo['continueOnError'] : false);
166
                unset($taskInfo['type'], $taskInfo['continueOnError']);
167
                $task->setParameters($taskInfo);
168
                $job->addTask($task);
169
            }
170
171
            $this->registry->addJob($job);
172
        }
173
    }
174
175
    /**
176
     * @param $name
177
     *
178
     * @return mixed
179
     * @throws \Exception
180
     */
181
    private function getProfile($name)
182
    {
183
        $profiles = $this->container->getParameter('profiles');
184
        if (!array_key_exists($name, $profiles)) {
185
            throw new \Exception(
186
                sprintf(
187
                    'There is no profile with the name \'%s\', expecting: (%s)',
188
                    $name,
189
                    implode(', ', array_keys($profiles))
190
                )
191
            );
192
        }
193
194
        return $profiles[$name];
195
    }
196
}
197