Passed
Push — master ( 0e37d9...784814 )
by Pol
02:31
created

Config::getLocalConfigurationFilepath()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.8437

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 1
dl 0
loc 15
ccs 5
cts 8
cp 0.625
crap 4.8437
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace PhpTaskman\Core\Config;
6
7
use PhpTaskman\Core\Taskman;
8
use Symfony\Component\Finder\Finder;
9
10
final class Config
11
{
12
    /**
13
     * Find the files to include in the configuration.
14
     *
15
     * @param string $cwd
16
     *   The current working directory.
17
     *
18
     * @return string[]
19
     *   The list of all the YAML files to include.
20
     */
21 1
    public static function findFilesToIncludeInConfiguration($cwd)
22
    {
23
        // Get the vendor-bin property from the composer.json.
24 1
        $composer = Taskman::getComposerFromDirectory($cwd);
25 1
        $vendorDir = $composer->getConfig('vendor-dir') ?? $cwd . '/vendor';
26
27
        // Keep a reference of the default filename that we need to load from
28
        // each packages.
29
        $filesToLoad = [
30 1
            'taskman.yml.dist',
31
            'taskman.yml',
32
        ];
33
34
        // Load default paths.
35
        $filesystemPaths = [
36 1
            __DIR__ . '/../config/default.yml',
37
            __DIR__ . '/../default.yml',
38 1
            static::getLocalConfigurationFilepath(),
39
        ];
40
41
        // Find all the composer.json to parse.
42 1
        $finder = (new Finder())
43 1
            ->files()
44 1
            ->exclude('tests')
45 1
            ->in([\dirname(\realpath($vendorDir)), $cwd])
46 1
            ->name('composer.json');
47
48
        // Loop over each composer.json, deduct the package directory and probe for files to include.
49
        /** @var SplFileInfo $file */
50 1
        foreach ($finder as $file) {
51 1
            $composerPackageDirectory = \dirname($file->getPathname());
52
53 1
            foreach ($filesToLoad as $taskmanFile) {
54 1
                foreach ([$composerPackageDirectory, $cwd] as $directory) {
55 1
                    $candidateFile = $directory . '/' . $taskmanFile;
56 1
                    $filesystemPaths[$candidateFile] = $candidateFile;
57
                }
58
            }
59
60 1
            $composer = Taskman::getComposerFromDirectory(
61 1
                $composerPackageDirectory
62
            );
63
64 1
            $extra = $composer->getExtra();
65
66 1
            if (empty($extra)) {
67 1
                continue;
68
            }
69
70
            $extra += ['taskman' => []];
71
            $extra['taskman'] += ['files' => []];
72
73
            foreach ($extra['taskman']['files'] as $commandFile) {
74
                $filesystemPaths[$commandFile] = $commandFile;
75
                $commandFile = $composerPackageDirectory . '/' . $commandFile;
76
                $filesystemPaths[$commandFile] = $commandFile;
77
            }
78
        }
79
80 1
        $files = static::resolveImports(...\array_values($filesystemPaths));
81
82 1
        return \array_filter($files, 'file_exists');
83
    }
84
85
    /**
86
     * Get the local configuration filepath.
87
     *
88
     * @param string $configuration_file
89
     *   The default filepath.
90
     *
91
     * @return null|string
92
     *   The local configuration file path, or null if it doesn't exist.
93
     */
94 1
    public static function getLocalConfigurationFilepath($configuration_file = 'phptaskman/taskman.yml')
95
    {
96 1
        if ($config = \getenv('PHPTASKMAN_CONFIG')) {
97
            return $config;
98
        }
99
100 1
        if ($config = \getenv('XDG_CONFIG_HOME')) {
101
            return $config . '/' . $configuration_file;
102
        }
103
104 1
        if ($home = \getenv('HOME')) {
0 ignored issues
show
Unused Code introduced by
The assignment to $home is dead and can be removed.
Loading history...
105 1
            return \getenv('HOME') . '/.config/' . $configuration_file;
106
        }
107
108
        return null;
109
    }
110
111
    /**
112
     * Resolve YAML configurations files containing imports.
113
     *
114
     * Handles circular dependencies by ignoring them.
115
     *
116
     * @param string[] ...$filepaths
117
     *   A list of YML filepath to parse.
118
     *
119
     * @return string[]
120
     *   The list of all the YAML files to include.
121
     */
122 1
    public static function resolveImports(...$filepaths)
123
    {
124 1
        return (new YamlRecursivePathsFinder($filepaths))
125 1
            ->getAllPaths();
126
    }
127
}
128