AbstractAction::error()   A
last analyzed

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
            $command = preg_replace('#[\s]{2,}#',' ', $command);
100
            $command = explode(" ", $command, 2);
101
            // @TODO Remove var_dump
102
            // var_dump($command); exit();
103
            $process = new Process($command, $deploymentDir);
104
            $process->run();
105
            if (!$process->isSuccessful()) {
106
                $this->error(
107
                    $deployment,
108
                    [
109
                        sprintf('Hook: %s hook failed to run : %s', $key, implode(' ', $command)),
110
                        $process->getOutput(),
111
                        $process->getErrorOutput()
112
                    ]
113
                );
114
                throw new RuntimeException('Unable to run deployment hook');
115
            }
116
            $this->info(
117
                $deployment,
118
                [
119
                    sprintf('Hook: %s hook ran successfully', $key),
120
                    $process->getOutput(),
121
                ]
122
            );
123
        }
124
    }
125
126
    /**
127
     * @see \App\Action\ActionInterface::run()
128
     */
129
    abstract public function run(Config $configuration, Context $context);
130
131
    /**
132
     * Log an info event
133
     *
134
     * @param \App\Model\Deployment $deployment
135
     * @param string $header
136
     * @param mixed $detail
137
     * @return bool|\App\Model\Event
138
     * @author Ronan Chilvers <[email protected]>
139
     */
140 4
    protected function info(Deployment $deployment, $detail = '')
141
    {
142 4
        return $this->event(
143 4
            EventFinder::INFO,
144
            $deployment,
145
            $detail
146
        );
147
    }
148
149
    /**
150
     * Log an error event
151
     *
152
     * @param \App\Model\Deployment $deployment
153
     * @param string $header
154
     * @param mixed $detail
155
     * @return bool|\App\Model\Event
156
     * @author Ronan Chilvers <[email protected]>
157
     */
158 2
    protected function error(Deployment $deployment, $detail = '')
159
    {
160 2
        return $this->event(
161 2
            EventFinder::ERROR,
162
            $deployment,
163
            $detail
164
        );
165
    }
166
167
    /**
168
     * Log an event
169
     *
170
     * @param string $type
171
     * @param \App\Model\Deployment $deployment
172
     * @param string $header
173
     * @param mixed $detail
174
     * @return bool|\App\Model\Event
175
     * @author Ronan Chilvers <[email protected]>
176
     */
177 6
    protected function event(string $type, Deployment $deployment, $detail = '')
178
    {
179 6
        if (is_array($detail)) {
180 4
            $detail = implode("\n", $detail);
181
        }
182 6
        $header = ucwords(str_replace('_', ' ', $this->getKey()));
183 6
        return $this->eventFinder->event(
184 6
            $type,
185
            $deployment,
186
            $header,
187
            $detail
188
        );
189
    }
190
}
191