Passed
Pull Request — master (#6)
by ANTHONIUS
02:55
created

Patcher   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
dl 0
loc 92
c 0
b 0
f 0
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 13 1
A __construct() 0 8 1
A registerPatch() 0 23 3
A debug() 0 3 1
A applyPatch() 0 10 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the dotfiles project.
7
 *
8
 *     (c) Anthonius Munthi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Dotfiles\Core\Processor;
15
16
use Dotfiles\Core\Config\Config;
17
use Dotfiles\Core\Constant;
18
use Dotfiles\Core\Event\Dispatcher;
19
use Dotfiles\Core\Event\PatchEvent;
20
use Dotfiles\Core\Util\Filesystem;
21
use Dotfiles\Core\Util\Toolkit;
22
use Psr\Log\LoggerInterface;
23
use Symfony\Component\Finder\Finder;
24
use Symfony\Component\Finder\SplFileInfo;
25
26
class Patcher
27
{
28
    /**
29
     * @var Config
30
     */
31
    private $config;
32
33
    /**
34
     * @var Dispatcher
35
     */
36
    private $dispatcher;
37
38
    /**
39
     * @var LoggerInterface
40
     */
41
    private $logger;
42
    /**
43
     * @var array
44
     */
45
    private $patches = array();
46
47
    public function __construct(
48
        Config $config,
49
        LoggerInterface $logger,
50
        Dispatcher $dispatcher
51
    ) {
52
        $this->config = $config;
53
        $this->logger = $logger;
54
        $this->dispatcher = $dispatcher;
55
    }
56
57
    public function run(): void
58
    {
59
        $this->registerPatch();
60
        $dispatcher = $this->dispatcher;
61
        $patchEvent = new PatchEvent($this->patches);
62
63
        // begin to writting patch
64
        $this->debug('dispatching '.Constant::EVENT_PRE_PATCH);
65
        $dispatcher->dispatch(Constant::EVENT_PRE_PATCH, $patchEvent);
66
        $patches = $patchEvent->getPatches();
67
        $this->applyPatch($patches);
68
        $this->debug('dispatching '.Constant::EVENT_POST_PATCH);
69
        $dispatcher->dispatch(Constant::EVENT_POST_PATCH, $patchEvent);
70
    }
71
72
    /**
73
     * Processing all registered patch.
74
     *
75
     * @param array $patches
76
     */
77
    private function applyPatch($patches): void
78
    {
79
        $this->debug('start applying patch');
80
        $homeDir = $this->config->get('dotfiles.home_dir');
81
        $fs = new Filesystem();
82
        foreach ($patches as $relPath => $patch) {
83
            $contents = implode(PHP_EOL, $patch);
84
            $target = $homeDir.DIRECTORY_SEPARATOR.$relPath;
85
            $fs->patch($target, $contents);
86
            $this->debug('+patch '.$target);
87
        }
88
    }
89
90
    private function debug($message, array $context = array()): void
91
    {
92
        $this->logger->info($message, $context);
93
    }
94
95
    private function registerPatch(): void
96
    {
97
        $backupDir = $this->config->get('dotfiles.backup_dir').'/src';
98
99
        $finder = Finder::create()
100
            ->ignoreVCS(true)
101
            ->ignoreDotFiles(false)
102
            ->in($backupDir)
103
            ->path('patch')
104
        ;
105
106
        $this->debug('registering all available patches');
107
108
        /* @var SplFileInfo $file */
109
        foreach ($finder->files() as $file) {
110
            $relPath = str_replace($file->getRelativePath().'/', '', $file->getRelativePathname());
111
            $relPath = Toolkit::ensureDotPath($relPath);
112
            $patch = file_get_contents($file->getRealPath());
113
            if (!isset($this->patches[$relPath])) {
114
                $this->patches[$relPath] = array();
115
            }
116
            $this->patches[$relPath][] = $patch;
117
            $this->debug('+patch '.$relPath);
118
        }
119
    }
120
}
121