GitAttributesManager   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Test Coverage

Coverage 57.45%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 42
dl 0
loc 106
ccs 27
cts 47
cp 0.5745
rs 10
c 1
b 0
f 0
wmc 20

7 Methods

Rating   Name   Duplication   Size   Complexity  
A writeGitAttributes() 0 3 1
A generatePatterns() 0 13 3
A appendPatternsToContent() 0 14 4
A cleanPatterns() 0 34 6
A formatPattern() 0 3 1
A appendPatterns() 0 11 2
A readGitAttributes() 0 7 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\DistSizeOptimizer\GitAttributesManager;
6
7
use function sprintf;
8
9
final class GitAttributesManager
10
{
11
    private const GITATTRIBUTES_FILE = '.gitattributes';
12
    private const EXPORT_IGNORE_PATTERN = 'export-ignore';
13
14 2
    public function appendPatterns(array $violatingFilesAndDirs): void
15
    {
16 2
        $patterns = $this->generatePatterns(violatingFilesAndDirs: $violatingFilesAndDirs);
17
18 2
        if (empty($patterns)) {
19
            return;
20
        }
21
22 2
        $content = $this->readGitAttributes();
23 2
        $newContent = $this->appendPatternsToContent(content: $content, patterns: $patterns);
24 2
        $this->writeGitAttributes(content: $newContent);
25
    }
26
27
    /**
28
     * Удаляет из .gitattributes все записанные паттерны export-ignore,
29
     * которые больше не соответствуют реальным файлам/папкам.
30
     */
31
    public function cleanPatterns(): void
32
    {
33
        $content = $this->readGitAttributes();
34
        if ($content === '') {
35
            // файл не существует или пуст — нечего чистить
36
            return;
37
        }
38
39
        $lines = preg_split(pattern: '/\r?\n/', subject: $content);
40
        $kept = [];
41
42
        foreach ($lines as $line) {
43
            $line = trim(string: $line);
44
            if ($line === '' || !str_contains(haystack: $line, needle: self::EXPORT_IGNORE_PATTERN)) {
45
                // оставляем пустые и “не-export-ignore” строки
46
                $kept[] = $line;
47
48
                continue;
49
            }
50
51
            // ожидаем формат "<путь> export-ignore"
52
            [$path] = preg_split(pattern: '/\s+/', subject: $line, limit: 2);
53
            // убираем возможные кавычки и ведущий слэш
54
            $path = ltrim(string: $path, characters: '/');
55
56
            // проверяем существование относительного пути
57
            if (file_exists(filename: $path)) {
58
                $kept[] = $line;
59
            }
60
        }
61
62
        // собираем обратно, не забывая про переводы строк
63
        $newContent = implode(separator: "\n", array: array_filter(array: $kept, callback: static fn($l) => $l !== '')) . "\n";
64
        $this->writeGitAttributes(content: $newContent);
65
    }
66
67 2
    private function generatePatterns(array $violatingFilesAndDirs): array
68
    {
69 2
        $patterns = [];
70
71 2
        foreach ($violatingFilesAndDirs['files'] as $file) {
72 1
            $patterns[] = $this->formatPattern(path: $file);
73
        }
74
75 2
        foreach ($violatingFilesAndDirs['directories'] as $directory) {
76 1
            $patterns[] = $this->formatPattern(path: rtrim(string: (string) $directory, characters: '/') . '/');
77
        }
78
79 2
        return array_unique(array: $patterns);
80
    }
81
82 2
    private function formatPattern(string $path): string
83
    {
84 2
        return sprintf('%s %s', $path, self::EXPORT_IGNORE_PATTERN);
85
    }
86
87 2
    private function readGitAttributes(): string
88
    {
89 2
        if (!file_exists(filename: self::GITATTRIBUTES_FILE)) {
90 1
            return '';
91
        }
92
93 1
        return file_get_contents(filename: self::GITATTRIBUTES_FILE) ?: '';
94
    }
95
96 2
    private function appendPatternsToContent(string $content, array $patterns): string
97
    {
98 2
        $existingPatterns = array_filter(array: explode(separator: "\n", string: $content));
99 2
        $newPatterns = array_diff($patterns, $existingPatterns);
100
101 2
        if (empty($newPatterns)) {
102
            return $content;
103
        }
104
105 2
        if (!empty($content) && !str_ends_with(haystack: $content, needle: "\n")) {
106
            $content .= "\n";
107
        }
108
109 2
        return $content . implode(separator: "\n", array: $newPatterns) . "\n";
110
    }
111
112 2
    private function writeGitAttributes(string $content): void
113
    {
114 2
        file_put_contents(filename: self::GITATTRIBUTES_FILE, data: $content);
115
    }
116
}
117