Passed
Pull Request — master (#20)
by Ronan
03:42
created

DeployJob::execute()   C

Complexity

Conditions 7
Paths 338

Size

Total Lines 97
Code Lines 78

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 0 Features 0
Metric Value
eloc 78
dl 0
loc 97
rs 5.5
c 8
b 0
f 0
cc 7
nc 338
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Queue;
4
5
use App\Action\ActivateAction;
6
use App\Action\CheckoutAction;
7
use App\Action\CleanupAction;
8
use App\Action\ClearPathsAction;
9
use App\Action\ComposerAction;
10
use App\Action\Context;
11
use App\Action\CreateWorkspaceAction;
12
use App\Action\FinaliseAction;
13
use App\Action\ScanConfigurationAction;
14
use App\Action\SharedAction;
15
use App\Action\WritablesAction;
16
use App\Builder;
17
use App\Facades\Log;
18
use App\Facades\Notifier;
19
use App\Facades\Provider;
20
use App\Facades\Settings;
21
use App\Model\Deployment;
22
use App\Model\Project;
23
use Exception;
24
use Ronanchilvers\Foundation\Config;
25
use Ronanchilvers\Foundation\Queue\Exception\FatalException;
26
use Ronanchilvers\Foundation\Queue\Job\Job;
27
use Ronanchilvers\Orm\Orm;
28
use Ronanchilvers\Utility\File;
29
use RuntimeException;
30
use Symfony\Component\Yaml\Yaml;
31
32
/**
33
 * Deploy a project
34
 *
35
 * @author Ronan Chilvers <[email protected]>
36
 */
37
class DeployJob extends Job
38
{
39
    /**
40
     * @var string
41
     */
42
    protected $queue = 'deploy';
43
44
    /**
45
     * @var \App\Model\deployment
46
     */
47
    protected $deployment;
48
49
    /**
50
     * Class constructor
51
     *
52
     * @param \App\Model\Deployment $project
53
     * @author Ronan Chilvers <[email protected]>
54
     */
55
    public function __construct(Deployment $deployment)
56
    {
57
        $this->deployment = $deployment;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     *
63
     * @author Ronan Chilvers <[email protected]>
64
     */
65
    public function execute()
66
    {
67
        $project       = $this->deployment->project;
68
        $data          = Yaml::parseFile(__DIR__ . '/../../config/defaults.yaml');
69
        $configuration = new Config($data);
70
        $builder       = new Builder(
71
            $project,
72
            $this->deployment
73
        );
74
        $baseDir    = Settings::get('build.base_dir');
75
        $key        = $project->key;
76
        $projectDir = File::join(
77
            $baseDir,
78
            $key
79
        );
80
        $deploymentBaseDir = File::join(
81
            $projectDir,
82
            'deployments'
83
        );
84
        $deploymentDir = File::join(
85
            $deploymentBaseDir,
86
            $this->deployment->number
87
        );
88
        try {
89
            $context = new Context;
90
            $context->set('project_base_dir', $projectDir);
91
            $context->set('deployment_base_dir', $deploymentBaseDir);
92
            $context->set('deployment_dir', $deploymentDir);
93
            $provider = Provider::forProject($project);
94
            $builder->addAction(new ScanConfigurationAction($provider));
95
            $builder->addAction(new CreateWorkspaceAction);
96
            $builder->addAction(new CheckoutAction($provider));
97
            $builder->addAction(new ComposerAction);
98
            $builder->addAction(new SharedAction);
99
            $builder->addAction(new WritablesAction);
100
            $builder->addAction(new ClearPathsAction);
101
            $builder->addAction(new ActivateAction);
102
            $builder->addAction(new FinaliseAction);
103
            $builder->addAction(new CleanupAction);
104
            if (!$this->deployment->start()) {
105
                throw new RuntimeException('Unable to mark the deployment as started');
106
            }
107
            $builder->run(
108
                $configuration,
109
                $context,
110
                function($data) use ($project) {
111
                    Log::debug($data, [
112
                        'project' => $project->toArray(),
113
                    ]);
114
                }
115
            );
116
            if (!$this->deployment->finish()) {
117
                throw new RuntimeException('Unable to mark the deployment as finished');
118
            }
119
            Notifier::send(
120
                sprintf(
121
                    "Deployment completed for <%s|%s>\nSHA: <%s|%s>\nAuthor: %s",
122
                    $provider->getRepositoryLink($project->repository),
123
                    $project->repository,
124
                    $provider->getShaLink($project->repository, $this->deployment->sha),
125
                    $this->deployment->sha,
126
                    $this->deployment->author
127
                ),
128
                $configuration->get('notify', [])
129
            );
130
        } catch (Exception $ex) {
131
            Log::critical($ex->getMessage(), [
132
                'project'   => $project->toArray(),
133
                'deployment'   => $this->deployment->toArray(),
134
                'exception' => $ex,
135
            ]);
136
            if (!$this->deployment->fail()) {
137
                throw new RuntimeException('Unable to mark the deployment as failed');
138
            }
139
            $project->last_status = $this->deployment->status;
140
            if (!$project->save()) {
141
                throw new RuntimeException('Unable to project as failed');
142
            }
143
            Notifier::send(
144
                sprintf(
145
                    "Deployment failed for <%s|%s>\nSHA: <%s|%s>\nAuthor: %s",
146
                    $provider->getRepositoryLink($project->repository),
147
                    $project->repository,
148
                    $provider->getShaLink($project->repository, $this->deployment->sha),
149
                    $this->deployment->sha,
150
                    $this->deployment->author
151
                ),
152
                $configuration->get('notify', [])
153
            );
154
            throw new FatalException(
155
                $ex->getMessage(),
156
                $ex->getCode(),
157
                $ex
158
            );
159
        } finally {
160
            if (!$project->markActive()) {
161
                throw new RuntimeException('Unable to mark project as deploying');
162
            }
163
        }
164
    }
165
}
166