• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eliashaeussler / gitattributes / 11745881131

08 Nov 2024 04:31PM UTC coverage: 86.061% (+49.6%) from 36.424%
11745881131

push

github

eliashaeussler
Initial commit

142 of 165 new or added lines in 10 files covered. (86.06%)

142 of 165 relevant lines covered (86.06%)

4.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/src/Rule/Pattern/FilePattern.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer package "eliashaeussler/gitattributes".
7
 *
8
 * Copyright (C) 2024 Elias Häußler <elias@haeussler.dev>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace EliasHaeussler\Gitattributes\Rule\Pattern;
25

26
use Stringable;
27
use Symfony\Component\Finder;
28

29
use function addcslashes;
30
use function preg_match;
31
use function preg_replace;
32
use function str_contains;
33
use function str_ends_with;
34
use function str_starts_with;
35
use function strlen;
36
use function strpos;
37
use function trim;
38

39
/**
40
 * FilePattern.
41
 *
42
 * @author Elias Häußler <elias@haeussler.dev>
43
 * @license GPL-3.0-or-later
44
 */
45
final class FilePattern implements Stringable
46
{
47
    public function __construct(
23✔
48
        private readonly string $pattern,
49
    ) {}
23✔
50

NEW
51
    public function pattern(): string
×
52
    {
NEW
53
        return $this->pattern;
×
54
    }
55

56
    /**
57
     * @see https://git-scm.com/docs/gitattributes#_description
58
     * @see https://git-scm.com/docs/gitignore#_pattern_format
59
     */
60
    public function matches(Finder\SplFileInfo $file): bool
22✔
61
    {
62
        $patterns = [];
22✔
63
        $relativePathname = $file->getRelativePathname();
22✔
64

65
        if (str_contains($this->pattern, '/')
22✔
66
            && (str_starts_with($this->pattern, '/') || (strpos($this->pattern, '/') < strlen($this->pattern) - 1))
22✔
67
        ) {
68
            // Pattern is relative to .gitattributes file
69
            $normalizedPattern = trim($this->pattern, DIRECTORY_SEPARATOR);
17✔
70

71
            $patterns[] = $normalizedPattern;
17✔
72
            $patterns[] = $normalizedPattern.'/**';
17✔
73
        } else {
74
            // Pattern is global (may match at any level)
75
            $patterns[] = $this->pattern;
5✔
76
            $patterns[] = '**/'.$this->pattern;
5✔
77

78
            if (!str_ends_with($this->pattern, '/')) {
5✔
79
                $patterns[] = $this->pattern.'/**';
4✔
80
                $patterns[] = '**/'.$this->pattern.'/**';
4✔
81
            }
82
        }
83

84
        $regex = $this->convertPatternsToRegularExpression($patterns);
22✔
85

86
        return 1 === preg_match($regex, $relativePathname);
22✔
87
    }
88

89
    public function toString(): string
1✔
90
    {
91
        return $this->pattern;
1✔
92
    }
93

94
    public function __toString(): string
1✔
95
    {
96
        return $this->toString();
1✔
97
    }
98

99
    /**
100
     * @param list<string> $patterns
101
     */
102
    private function convertPatternsToRegularExpression(array $patterns): string
22✔
103
    {
104
        $groups = [];
22✔
105

106
        foreach ($patterns as $pattern) {
22✔
107
            $groups[] = preg_replace(
22✔
108
                ['/(?<!\*)\*(?!\*)/', '/\*\*/', '/\?/'],
22✔
109
                ['[^/]*', '.*', '[^/]'],
22✔
110
                addcslashes($pattern, '#'),
22✔
111
            );
22✔
112
        }
113

114
        return '#^('.implode('|', $groups).')$#';
22✔
115
    }
116
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc