Passed
Pull Request — master (#39)
by
unknown
13:26
created

AbstractAction::error()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace App\Action;
4
5
use App\Action\ActionInterface;
6
use App\Action\Context;
7
use App\Facades\Log;
8
use App\Model\Deployment;
9
use App\Model\Finder\EventFinder;
10
use ReflectionClass;
11
use Ronanchilvers\Foundation\Config;
12
use Ronanchilvers\Foundation\Traits\Optionable;
13
use Ronanchilvers\Utility\Str;
14
use RuntimeException;
15
use Symfony\Component\Process\Process;
16
17
/**
18
 * Action to symlink the deployment in to the live location
19
 *
20
 * @author Ronan Chilvers <[email protected]>
21
 */
22
abstract class AbstractAction implements ActionInterface
23
{
24
    use Optionable;
25
26
    /**
27
     * @var \App\Model\Finder\EventFinder
28
     */
29
    protected $eventFinder = null;
30
31
    /**
32
     * @var boolean
33
     */
34
    protected $hookable = true;
35
36
    /**
37
     * @see \App\Action\ActionInterface::getKey()
38
     */
39 7
    public function getKey()
40
    {
41 7
        $reflection = new ReflectionClass($this);
42 7
        $name       = Str::snake(
43 7
            str_replace(
44 7
                'Action',
45 7
                '',
46 7
                $reflection->getShortName()
47
            )
48
        );
49
50 7
        return $name;
51
    }
52
53
    /**
54
     * @author Ronan Chilvers <[email protected]>
55
     */
56 6
    public function setEventFinder(EventFinder $eventFinder)
57
    {
58 6
        $this->eventFinder = $eventFinder;
59 6
    }
60
61
    /**
62
     * @author Ronan Chilvers <[email protected]>
63
     */
64 1
    public function isHookable()
65
    {
66 1
        return $this->hookable;
67
    }
68
69
    /**
70
     * @author Ronan Chilvers <[email protected]>
71
     */
72
    public function runHooks($hook, Config $configuration, Context $context)
73
    {
74
        $deployment = $context->getOrThrow(
75
            'deployment',
76
            'Invalid or missing deployment in hook runner'
77
        );
78
        $deploymentDir = $context->getOrThrow(
79
            'deployment_dir',
80
            'Invalid or missing deployment directory'
81
        );
82
        $hook = strtolower($hook);
83
        if (!in_array($hook, ['before', 'after'])) {
84
            return;
85
        }
86
        $key   = $this->getKey() . '.' . $hook;
87
        $hooks = $configuration->get($key);
88
        if (!is_array($hooks) || empty($hooks)) {
89
            Log::debug('No hooks defined', [
90
                'key' => $key
91
            ]);
92
            return;
93
        }
94
        foreach ($hooks as $command) {
95
            $this->info(
96
                $deployment,
97
                sprintf('Hook: %s hook running - %s', $key, $command)
98
            );
99
            $process = new Process($command, $deploymentDir);
100
            $process->run();
101
            if (!$process->isSuccessful()) {
102
                $this->error(
103
                    $deployment,
104
                    [
105
                        sprintf('Hook: %s hook failed to run : %s', $key, $command),
106
                        $process->getOutput(),
107
                        $process->getErrorOutput()
108
                    ]
109
                );
110
                throw new RuntimeException('Unable to run deployment hook');
111
            }
112
            $this->info(
113
                $deployment,
114
                [
115
                    sprintf('Hook: %s hook ran successfully', $key),
116
                    $process->getOutput(),
117
                ]
118
            );
119
        }
120
    }
121
122
    /**
123
     * @see \App\Action\ActionInterface::run()
124
     */
125
    abstract public function run(Config $configuration, Context $context);
126
127
    /**
128
     * Log an info event
129
     *
130
     * @param \App\Model\Deployment $deployment
131
     * @param string $header
132
     * @param mixed $detail
133
     * @return bool|\App\Model\Event
134
     * @author Ronan Chilvers <[email protected]>
135
     */
136 4
    protected function info(Deployment $deployment, $detail = '')
137
    {
138 4
        return $this->event(
139 4
            EventFinder::INFO,
140
            $deployment,
141
            $detail
142
        );
143
    }
144
145
    /**
146
     * Log an error event
147
     *
148
     * @param \App\Model\Deployment $deployment
149
     * @param string $header
150
     * @param mixed $detail
151
     * @return bool|\App\Model\Event
152
     * @author Ronan Chilvers <[email protected]>
153
     */
154 2
    protected function error(Deployment $deployment, $detail = '')
155
    {
156 2
        return $this->event(
157 2
            EventFinder::ERROR,
158
            $deployment,
159
            $detail
160
        );
161
    }
162
163
    /**
164
     * Log an event
165
     *
166
     * @param string $type
167
     * @param \App\Model\Deployment $deployment
168
     * @param string $header
169
     * @param mixed $detail
170
     * @return bool|\App\Model\Event
171
     * @author Ronan Chilvers <[email protected]>
172
     */
173 6
    protected function event(string $type, Deployment $deployment, $detail = '')
174
    {
175 6
        if (is_array($detail)) {
176 4
            $detail = implode("\n", $detail);
177
        }
178 6
        $header = ucwords(str_replace('_', ' ', $this->getKey()));
179 6
        return $this->eventFinder->event(
180 6
            $type,
181
            $deployment,
182
            $header,
183
            $detail
184
        );
185
    }
186
}
187