SharedAction::run()   F
last analyzed

Complexity

Conditions 33
Paths 271

Size

Total Lines 375
Code Lines 234

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 1122

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 234
c 1
b 0
f 0
dl 0
loc 375
ccs 0
cts 99
cp 0
rs 1.9566
cc 33
nc 271
nop 2
crap 1122

How to fix   Long Method    Complexity   

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\Action;
4
5
use App\Action\AbstractAction;
6
use App\Action\ActionInterface;
7
use App\Builder;
8
use App\Facades\Log;
9
use App\Facades\Settings;
10
use Ronanchilvers\Foundation\Config;
11
use Ronanchilvers\Utility\File;
12
use RuntimeException;
13
14
/**
15
 * Action to manage any shared locations for a project
16
 *
17
 * @author Ronan Chilvers <[email protected]>
18
 */
19
class SharedAction extends AbstractAction
20
{
21
    /**
22
     * @see \App\Action\ActionInterface::run()
23
     */
24
    public function run(Config $configuration, Context $context)
25
    {
26
        $deployment    = $context->getOrThrow('deployment', 'Invalid or missing deployment');
27
        $baseDir       = $context->getOrThrow('project_base_dir', 'Invalid or missing project base directory');
28
        $folderMode    = Settings::get('build.chmod.default_folder', Builder::MODE_DEFAULT);
29
        $fileMode      = Settings::get('build.chmod.default_file', Builder::MODE_DEFAULT_FILE);
30
        $sharedBaseDir = File::join($baseDir, 'shared');
31
        if (!is_dir($sharedBaseDir)) {
32
            $this->info($deployment, "Creating base shared directory: {$sharedBaseDir}");
33
            Log::debug('Creating shared base directory', [
34
                'dir' => $sharedBaseDir,
35
            ]);
36
            if (!mkdir($sharedBaseDir, $folderMode, true)) {
37
                $this->error(
38
                    $deployment,
39
                    [
40
                        'Failed creating base shared directory',
41
                        "Directory: {$sharedBaseDir}",
42
                        "Mode: {$folderMode}",
43
                    ]
44
                );
45
                throw new RuntimeException('Unable to create shared base directory');
46
            }
47
        }
48
        $deploymentDir = $context->getOrThrow('deployment_dir', 'Invalid or missing deployment directory');
49
        // Get the shared items from the configuration object
50
        $shared = $configuration->get('shared', []);
51
        if (0 == count($shared)) {
52
            $this->info(
53
                $deployment,
54
                'No shared files or folders set in deployment configuration'
55
            );
56
            return;
57
        }
58
        // Shared folders
59
        $sharedFolders = [];
60
        if (
61
            isset($shared['folders']) &&
62
            is_array($shared['folders']) &&
63
            0 < count($shared['folders'])
64
        ) {
65
            // $this->info(
66
            //     $deployment,
67
            //     [
68
            //         'Verifying shared folders',
69
            //         "Shared folders - " . implode(", ", $shared['folders']),
70
            //     ]
71
            // );
72
            foreach ($shared['folders'] as $folder) {
73
                $sharedDir = File::join($sharedBaseDir, $folder);
74
                $thisDeploymentDir = File::join($deploymentDir, $folder);
75
76
                $this->info($deployment, 'Folder: ' . $folder);
77
78
                // Create the shared directory if needed
79
                if (!is_dir($sharedDir)) {
80
                    if (is_dir($thisDeploymentDir)) {
81
                        $this->info(
82
                            $deployment,
83
                            [
84
                                'Copying shared folder from deployment',
85
                                "Deployment folder: {$thisDeploymentDir}",
86
                                "Shared folder: {$sharedDir}",
87
                            ]
88
                        );
89
                        if (!File::cp($thisDeploymentDir, $sharedDir)) {
90
                            $this->error(
91
                                $deployment,
92
                                [
93
                                    'Failed copying shared folder from deployment',
94
                                    "Deployment folder: {$thisDeploymentDir}",
95
                                    "Shared folder: {$sharedDir}",
96
                                ]
97
                            );
98
                            Log::debug('Unable to copy shared folder from deployment', [
99
                                'shared_dir'  => $sharedDir,
100
                                'deployment_dir' => $thisDeploymentDir,
101
                            ]);
102
                            throw new RuntimeException('Unable to move shared folder from deployment to shared');
103
                        }
104
                    } elseif (!mkdir($sharedDir, $folderMode, true)) {
105
                        $this->error(
106
                            $deployment,
107
                            [
108
                                'Unable to create shared folder',
109
                                "Shared folder: {$sharedDir}",
110
                                "Mode: {$folderMode}",
111
                            ]
112
                        );
113
                        Log::debug('Unable to create shared folder', [
114
                            'shared_dir'  => $sharedDir,
115
                            'deployment_dir' => $thisDeploymentDir,
116
                        ]);
117
                        throw new RuntimeException('Unable to create shared folders');
118
                    }
119
                }
120
121
                // Remove the shared folder from the deployment if it exists
122
                $this->info(
123
                    $deployment,
124
                    "Removing shared folder from deployment directory:  {$thisDeploymentDir}"
125
                );
126
                if (!File::rm($thisDeploymentDir)) {
127
                    $this->info(
128
                        $deployment,
129
                        "Shared folder not found in deployment directory: {$thisDeploymentDir}"
130
                    );
131
                    Log::debug('Shared folder not found in deployment directory', [
132
                        'shared_dir'     => $sharedDir,
133
                        'deployment_dir' => $thisDeploymentDir,
134
                    ]);
135
                }
136
137
                // Link the shared location into the deployment
138
                $parentDir = dirname($thisDeploymentDir);
139
                if (!is_dir($parentDir) && !mkdir($parentDir, $folderMode, true)) {
140
                    $this->error(
141
                        $deployment,
142
                        [
143
                            'Unable to create parent directory for symlinking',
144
                            "Parent shared folder: {$parentDir}",
145
                            "Mode: {$folderMode}",
146
                        ]
147
                    );
148
                    Log::debug('Unable to create parent directory for symlinking', [
149
                        'parent_dir'  => $parentDir,
150
                        'shared_dir'  => $sharedDir,
151
                        'deployment_dir' => $thisDeploymentDir,
152
                    ]);
153
                    throw new RuntimeException('Unable to create parent directory for symlinking');
154
                }
155
                if (!symlink($sharedDir, $thisDeploymentDir)) {
156
                    $this->error(
157
                        $deployment,
158
                        [
159
                            'Unable to symlink shared folder',
160
                            "Deployment link: {$thisDeploymentDir}",
161
                            "Shared folder: {$sharedDir}",
162
                        ]
163
                    );
164
                    Log::debug('Unable to symlink shared folder', [
165
                        'shared_dir'  => $sharedDir,
166
                        'deployment_dir' => $thisDeploymentDir,
167
                    ]);
168
                    throw new RuntimeException('Unable to symlink shared folder');
169
                }
170
                $sharedFolders[$sharedDir] = $sharedDir;
171
            }
172
        }
173
        // Shared files
174
        if (
175
            isset($shared['files']) &&
176
            is_array($shared['files']) &&
177
            0 < count($shared['files'])
178
        ) {
179
            // $this->info(
180
            //     $deployment,
181
            //     [
182
            //         'Verifying shared files',
183
            //         "Shared files - " . implode(", ", $shared['files']),
184
            //     ]
185
            // );
186
            foreach ($shared['files'] as $filename) {
187
                $sharedFilename     = File::join($sharedBaseDir, $filename);
188
                $sharedDir          = dirname($sharedFilename);
189
                $thisDeploymentFile = File::join($deploymentDir, $filename);
190
                $thisDeploymentDir  = dirname($thisDeploymentFile);
191
192
                $this->info($deployment, 'File: ' . $folder);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $folder does not seem to be defined for all execution paths leading up to this point.
Loading history...
193
194
                // Check that we're not sharing the parent directory already
195
                if (isset($sharedFolders[$sharedDir])) {
196
                    $this->error(
197
                        $deployment,
198
                        [
199
                            'Shared file parent folder is already shared',
200
                            "Shared file: {$sharedFilename}",
201
                            "Shared folder: {$sharedDir}",
202
                        ]
203
                    );
204
                    Log::error('Parent folder is already shared', [
205
                        'shared_dir' => $sharedDir,
206
                        'shared_file' => $sharedFilename,
207
                    ]);
208
                    throw new RuntimeException('Parent folder for shared file is already shared');
209
                }
210
211
                // Create the shared directory if needed
212
                if (!is_dir($sharedDir)) {
213
                    $this->info(
214
                        $deployment,
215
                        [
216
                            'Creating parent folder for shared file',
217
                            "Shared file: {$sharedFilename}",
218
                            "Shared folder: {$sharedDir}",
219
                        ]
220
                    );
221
                    if (!mkdir($sharedDir, $folderMode, true)) {
222
                        $this->error(
223
                            $deployment,
224
                            [
225
                                'Unable to create parent folder for shared file',
226
                                "Shared file: {$sharedFilename}",
227
                                "Shared folder: {$sharedDir}",
228
                            ]
229
                        );
230
                        Log::debug('Unable to create parent folder for shared file', [
231
                            'shared_dir'  => $sharedDir,
232
                            'shared_file' => $sharedFilename,
233
                        ]);
234
                        throw new RuntimeException('Unable to create parent folder for shared file');
235
                    }
236
                }
237
                // Copy over the file from the deployment if it exists
238
                if (file_exists($thisDeploymentFile)) {
239
                    $this->info(
240
                        $deployment,
241
                        [
242
                            'Copying shared file from deployment into shared folder',
243
                            "Deployment file: {$thisDeploymentFile}",
244
                            "Shared file: {$sharedFilename}",
245
                            "Shared folder: {$sharedDir}",
246
                        ]
247
                    );
248
                    Log::debug('Shared file exists in deployment', [
249
                        'shared_file'  => $sharedFilename,
250
                        'deployment_file' => $thisDeploymentFile,
251
                    ]);
252
                    if (!file_exists($sharedFilename) && !File::cp($thisDeploymentFile, $sharedFilename)) {
253
                        $this->error(
254
                            $deployment,
255
                            [
256
                                'Unable to copy shared file from deployment',
257
                                "Deployment file: {$thisDeploymentFile}",
258
                                "Shared file: {$sharedFilename}",
259
                                "Shared folder: {$sharedDir}",
260
                            ]
261
                        );
262
                        Log::debug('Unable to copy shared file from deployment', [
263
                            'shared_dir'   => $sharedDir,
264
                            'shared_file'  => $sharedFilename,
265
                            'deployment_file' => $thisDeploymentFile,
266
                        ]);
267
                        throw new RuntimeException('Unable to copy shared file from deployment');
268
                    }
269
                    $this->info(
270
                        $deployment,
271
                        [
272
                            'Removing shared file from deployment',
273
                            "Deployment file: {$thisDeploymentFile}",
274
                            "Shared file: {$sharedFilename}",
275
                            "Shared folder: {$sharedDir}",
276
                        ]
277
                    );
278
                    Log::debug('Removing shared file from deployment', [
279
                        'shared_file'  => $sharedFilename,
280
                        'deployment_file' => $thisDeploymentFile,
281
                    ]);
282
                    if (!File::rm($thisDeploymentFile)) {
283
                        $this->error(
284
                            $deployment,
285
                            [
286
                                'Unable to remove shared file from deployment',
287
                                "Deployment file: {$thisDeploymentFile}",
288
                                "Shared file: {$sharedFilename}",
289
                                "Shared folder: {$sharedDir}",
290
                            ]
291
                        );
292
                        Log::debug('Unable to remove shared file from deployment', [
293
                            'shared_dir'   => $sharedDir,
294
                            'shared_file'  => $sharedFilename,
295
                            'deployment_file' => $thisDeploymentFile,
296
                        ]);
297
                        throw new RuntimeException('Unable to remove shared file from deployment');
298
                    }
299
                }
300
301
                // Make sure the parent directory exists for the shared file
302
                if (!is_dir($thisDeploymentDir)) {
303
                    $this->info(
304
                        $deployment,
305
                        [
306
                            'Creating parent folder for deployment link',
307
                            "Deployment file: {$thisDeploymentFile}",
308
                            "Mode: {$folderMode}",
309
                        ]
310
                    );
311
                    if (!mkdir($thisDeploymentDir, $folderMode, true)) {
312
                        $this->info(
313
                            $deployment,
314
                            [
315
                                'Unable to create parent folder for shared file in deployment',
316
                                "Deployment file: {$thisDeploymentFile}",
317
                                "Mode: {$folderMode}",
318
                            ]
319
                        );
320
                        Log::debug('Unable to create parent directory for shared file in deployment', [
321
                            'shared_dir'   => $sharedDir,
322
                            'shared_file'  => $sharedFilename,
323
                            'deployment_file' => $thisDeploymentFile,
324
                            'deployment_dir'  => $thisDeploymentDir,
325
                        ]);
326
                        throw new RuntimeException('Unable to create parent directory for shared file in deployment');
327
                    }
328
                }
329
330
                // Touch the shared file
331
                if (!file_exists($sharedFilename)) {
332
                    $this->info(
333
                        $deployment,
334
                        [
335
                            'Creating empty shared file for symlinking',
336
                            "Shared file: {$sharedFilename}",
337
                        ]
338
                    );
339
                    if (!touch($sharedFilename)) {
340
                        $this->error(
341
                            $deployment,
342
                            [
343
                                'Unable to create shared file for symlinking',
344
                                "Shared file: {$sharedFilename}",
345
                            ]
346
                        );
347
                        Log::debug('Unable to touch shared file', [
348
                            'shared_dir'   => $sharedDir,
349
                            'shared_file'  => $sharedFilename,
350
                            'deployment_file' => $thisDeploymentFile,
351
                            'deployment_dir'  => $thisDeploymentDir,
352
                        ]);
353
                        throw new RuntimeException('Unable to touch shared file');
354
                    }
355
                    if (!chmod($sharedFilename, $fileMode)) {
356
                        $this->error(
357
                            $deployment,
358
                            [
359
                                'Unable to chmod shared file',
360
                                "Shared file: {$sharedFilename}",
361
                                "Mode: {$fileMode}",
362
                            ]
363
                        );
364
                        Log::debug('Unable to chmod shared file', [
365
                            'shared_dir'   => $sharedDir,
366
                            'shared_file'  => $sharedFilename,
367
                            'deployment_file' => $thisDeploymentFile,
368
                            'deployment_dir'  => $thisDeploymentDir,
369
                        ]);
370
                        throw new RuntimeException('Unable to chmod shared file');
371
                    }
372
                }
373
374
                // Symlink the shared file into place
375
376
                if (!symlink($sharedFilename, $thisDeploymentFile)) {
377
                    $this->error(
378
                        $deployment,
379
                        [
380
                            'Unable to symlink shared file',
381
                            "Shared file: {$sharedFilename}",
382
                            "Deployment link: {$thisDeploymentFile}",
383
                        ]
384
                    );
385
                    Log::debug('Unable to symlink shared file', [
386
                        'shared_dir'   => $sharedDir,
387
                        'shared_file'  => $sharedFilename,
388
                        'deployment_file' => $thisDeploymentFile,
389
                        'deployment_dir'  => $thisDeploymentDir,
390
                    ]);
391
                    throw new RuntimeException('Unable to symlink shared file');
392
                }
393
                $this->info(
394
                    $deployment,
395
                    [
396
                        'Symlinked shared file into deployment',
397
                        "Shared file: {$sharedFilename}",
398
                        "Deployment link: {$thisDeploymentFile}",
399
                    ]
400
                );
401
            }
402
        }
403
    }
404
}
405