Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\Finder;
13
 
14
/**
15
 * Gitignore matches against text.
16
 *
17
 * @author Michael Voříšek <vorismi3@fel.cvut.cz>
18
 * @author Ahmed Abdou <mail@ahmd.io>
19
 */
20
class Gitignore
21
{
22
    /**
23
     * Returns a regexp which is the equivalent of the gitignore pattern.
24
     *
25
     * Format specification: https://git-scm.com/docs/gitignore#_pattern_format
26
     */
27
    public static function toRegex(string $gitignoreFileContent): string
28
    {
29
        return self::buildRegex($gitignoreFileContent, false);
30
    }
31
 
32
    public static function toRegexMatchingNegatedPatterns(string $gitignoreFileContent): string
33
    {
34
        return self::buildRegex($gitignoreFileContent, true);
35
    }
36
 
37
    private static function buildRegex(string $gitignoreFileContent, bool $inverted): string
38
    {
39
        $gitignoreFileContent = preg_replace('~(?<!\\\\)#[^\n\r]*~', '', $gitignoreFileContent);
40
        $gitignoreLines = preg_split('~\r\n?|\n~', $gitignoreFileContent);
41
 
42
        $res = self::lineToRegex('');
43
        foreach ($gitignoreLines as $line) {
44
            $line = preg_replace('~(?<!\\\\)[ \t]+$~', '', $line);
45
 
46
            if (str_starts_with($line, '!')) {
47
                $line = substr($line, 1);
48
                $isNegative = true;
49
            } else {
50
                $isNegative = false;
51
            }
52
 
53
            if ('' !== $line) {
54
                if ($isNegative xor $inverted) {
55
                    $res = '(?!'.self::lineToRegex($line).'$)'.$res;
56
                } else {
57
                    $res = '(?:'.$res.'|'.self::lineToRegex($line).')';
58
                }
59
            }
60
        }
61
 
62
        return '~^(?:'.$res.')~s';
63
    }
64
 
65
    private static function lineToRegex(string $gitignoreLine): string
66
    {
67
        if ('' === $gitignoreLine) {
68
            return '$f'; // always false
69
        }
70
 
71
        $slashPos = strpos($gitignoreLine, '/');
72
        if (false !== $slashPos && \strlen($gitignoreLine) - 1 !== $slashPos) {
73
            if (0 === $slashPos) {
74
                $gitignoreLine = substr($gitignoreLine, 1);
75
            }
76
            $isAbsolute = true;
77
        } else {
78
            $isAbsolute = false;
79
        }
80
 
81
        $regex = preg_quote(str_replace('\\', '', $gitignoreLine), '~');
82
        $regex = preg_replace_callback('~\\\\\[((?:\\\\!)?)([^\[\]]*)\\\\\]~', function (array $matches): string {
83
            return '['.('' !== $matches[1] ? '^' : '').str_replace('\\-', '-', $matches[2]).']';
84
        }, $regex);
85
        $regex = preg_replace('~(?:(?:\\\\\*){2,}(/?))+~', '(?:(?:(?!//).(?<!//))+$1)?', $regex);
86
        $regex = preg_replace('~\\\\\*~', '[^/]*', $regex);
87
        $regex = preg_replace('~\\\\\?~', '[^/]', $regex);
88
 
89
        return ($isAbsolute ? '' : '(?:[^/]+/)*')
90
            .$regex
91
            .(!str_ends_with($gitignoreLine, '/') ? '(?:$|/)' : '');
92
    }
93
}