Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
ExistenceChecker
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
6 / 6
6
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
 exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 filterExisting
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isDirectory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 absolutePath
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of fast-forward/dev-tools.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @copyright Copyright (c) 2026 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
12 * @license   https://opensource.org/licenses/MIT MIT License
13 *
14 * @see       https://github.com/php-fast-forward/dev-tools
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\DevTools\GitAttributes;
20
21use Symfony\Component\Filesystem\Filesystem;
22
23/**
24 * Checks the existence of files and directories in a given base path.
25 *
26 * This class determines which candidate paths from the canonical list
27 * actually exist in the target repository, enabling selective export-ignore rules.
28 */
29  class ExistenceChecker implements ExistenceCheckerInterface
30{
31    /**
32     * @param Filesystem $filesystem
33     */
34    public function __construct(
35        private Filesystem $filesystem = new Filesystem()
36    ) {}
37
38    /**
39     * Checks if a path exists as a file or directory.
40     *
41     * @param string $basePath the repository base path used to resolve the candidate
42     * @param string $path The path to check (e.g., "/.github/" or "/.editorconfig")
43     *
44     * @return bool True if the path exists as a file or directory
45     */
46    public function exists(string $basePath, string $path): bool
47    {
48        return $this->filesystem->exists($this->absolutePath($basePath, $path));
49    }
50
51    /**
52     * Filters a list of paths to only those that exist.
53     *
54     * @param string $basePath the repository base path used to resolve the candidates
55     * @param list<string> $paths The paths to filter
56     *
57     * @return list<string> Only the paths that exist
58     */
59    public function filterExisting(string $basePath, array $paths): array
60    {
61        return array_values(array_filter($paths, fn(string $path): bool => $this->exists($basePath, $path)));
62    }
63
64    /**
65     * Checks if a path is a directory.
66     *
67     * @param string $basePath the repository base path used to resolve the candidate
68     * @param string $path The path to check (e.g., "/.github/")
69     *
70     * @return bool True if the path exists and is a directory
71     */
72    public function isDirectory(string $basePath, string $path): bool
73    {
74        return is_dir($this->absolutePath($basePath, $path));
75    }
76
77    /**
78     * Checks if a path is a file.
79     *
80     * @param string $basePath the repository base path used to resolve the candidate
81     * @param string $path The path to check (e.g., "/.editorconfig")
82     *
83     * @return bool True if the path exists and is a file
84     */
85    public function isFile(string $basePath, string $path): bool
86    {
87        return is_file($this->absolutePath($basePath, $path));
88    }
89
90    /**
91     * Resolves a candidate path against the repository base path.
92     *
93     * @param string $basePath the repository base path
94     * @param string $path the candidate path in canonical form
95     *
96     * @return string the absolute path used for filesystem checks
97     */
98    private function absolutePath(string $basePath, string $path): string
99    {
100        return rtrim($basePath, '/\\') . $path;
101    }
102}