Passed
Push — master ( 1be62d...69b4a5 )
by Ronan
03:41
created

AbstractAction   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Test Coverage

Coverage 36.84%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 59
c 1
b 0
f 0
dl 0
loc 142
ccs 21
cts 57
cp 0.3684
rs 10

6 Methods

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