Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
GitIgnore
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
5 / 5
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 path
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 entries
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIterator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromFile
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Fast Forward Development Tools for PHP projects.
7 *
8 * This file is part of fast-forward/dev-tools project.
9 *
10 * @author   Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
11 * @license  https://opensource.org/licenses/MIT MIT License
12 *
13 * @see      https://github.com/php-fast-forward/
14 * @see      https://github.com/php-fast-forward/dev-tools
15 * @see      https://github.com/php-fast-forward/dev-tools/issues
16 * @see      https://php-fast-forward.github.io/dev-tools/
17 * @see      https://datatracker.ietf.org/doc/html/rfc2119
18 */
19
20namespace FastForward\DevTools\GitIgnore;
21
22use ArrayIterator;
23use SplFileObject;
24
25/**
26 * Represents a .gitignore file with its path and entries.
27 *
28 * This class implements IteratorAggregate to allow iteration over entries
29 * and provides a factory method to load .gitignore content from the file system.
30 *
31 * @implements GitIgnoreInterface
32 */
33  class GitIgnore implements GitIgnoreInterface
34{
35    /**
36     * Initializes a GitIgnore instance with the given path and entries.
37     *
38     * @param string $path the file system path to the .gitignore file
39     * @param list<string> $entries the .gitignore entries
40     */
41    public function __construct(
42        public string $path,
43        public array $entries
44    ) {}
45
46    /**
47     * Returns the file system path to the .gitignore file.
48     *
49     * @return string the absolute path to the .gitignore file
50     */
51    public function path(): string
52    {
53        return $this->path;
54    }
55
56    /**
57     * Returns the list of entries from the .gitignore file.
58     *
59     * @return list<string> the non-empty .gitignore entries
60     */
61    public function entries(): array
62    {
63        return $this->entries;
64    }
65
66    /**
67     * Returns an iterator over the .gitignore entries.
68     *
69     * This method implements the IteratorAggregate interface.
70     *
71     * @return ArrayIterator<int, string> an iterator over the entries
72     */
73    public function getIterator(): ArrayIterator
74    {
75        return new ArrayIterator($this->entries);
76    }
77
78    /**
79     * Creates a GitIgnore instance from a file path.
80     *
81     * If the file does not exist, returns an empty GitIgnore with the given path.
82     * Empty lines and whitespace-only lines are filtered from the entries.
83     *
84     * @param string $gitignorePath the file system path to the .gitignore file
85     *
86     * @return static a new GitIgnore instance
87     */
88    public static function fromFile(string $gitignorePath): self
89    {
90        if (! file_exists($gitignorePath)) {
91            return new self($gitignorePath, []);
92        }
93
94        $file = new SplFileObject($gitignorePath, 'r');
95        $file->setFlags(SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
96
97        $entries = [];
98        foreach ($file as $line) {
99            $trimmed = trim($line ?: '');
100
101            if ('' !== $trimmed) {
102                $entries[] = $trimmed;
103            }
104        }
105
106        return new self($gitignorePath, array_values($entries));
107    }
108}