Patcher::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 3
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
    /**
44
     * @var array
45
     */
46
    private $patches = array();
47
48
    public function __construct(
49
        Config $config,
50
        LoggerInterface $logger,
51
        Dispatcher $dispatcher
52
    ) {
53
        $this->config = $config;
54
        $this->logger = $logger;
55
        $this->dispatcher = $dispatcher;
56
    }
57
58
    public function run(): void
59
    {
60
        $this->registerPatch();
61
        $dispatcher = $this->dispatcher;
62
        $patchEvent = new PatchEvent($this->patches);
63
64
        // begin to writting patch
65
        $this->debug('dispatching '.Constant::EVENT_PRE_PATCH);
66
        $dispatcher->dispatch(Constant::EVENT_PRE_PATCH, $patchEvent);
67
        $patches = $patchEvent->getPatches();
68
        $this->applyPatch($patches);
69
        $this->debug('dispatching '.Constant::EVENT_POST_PATCH);
70
        $dispatcher->dispatch(Constant::EVENT_POST_PATCH, $patchEvent);
71
    }
72
73
    /**
74
     * Processing all registered patch.
75
     *
76
     * @param array $patches
77
     */
78
    private function applyPatch($patches): void
79
    {
80
        $this->debug('start applying patch');
81
        $homeDir = $this->config->get('dotfiles.home_dir');
82
        $fs = new Filesystem();
83
        foreach ($patches as $relPath => $patch) {
84
            $contents = implode(PHP_EOL, $patch);
85
            $target = $homeDir.DIRECTORY_SEPARATOR.$relPath;
86
            $fs->patch($target, $contents);
87
            $this->debug('+patch '.$target);
88
        }
89
    }
90
91
    private function debug($message, array $context = array()): void
92
    {
93
        $this->logger->info($message, $context);
94
    }
95
96
    private function registerPatch(): void
97
    {
98
        $backupDir = $this->config->get('dotfiles.backup_dir').'/src';
99
100
        $finder = Finder::create()
101
            ->ignoreVCS(true)
102
            ->ignoreDotFiles(false)
103
            ->in($backupDir)
104
            ->path('patch')
105
        ;
106
107
        $this->debug('registering all available patches');
108
109
        /* @var SplFileInfo $file */
110
        foreach ($finder->files() as $file) {
111
            $relPath = str_replace($file->getRelativePath().'/', '', $file->getRelativePathname());
112
            $relPath = Toolkit::ensureDotPath($relPath);
113
            $patch = file_get_contents($file->getRealPath());
114
            if (!isset($this->patches[$relPath])) {
115
                $this->patches[$relPath] = array();
116
            }
117
            $this->patches[$relPath][] = $patch;
118
            $this->debug('+patch '.$relPath);
119
        }
120
    }
121
}
122