Completed
Push — master ( c1a557...09df77 )
by Pol
03:01
created

Config::getLocalConfigurationFilepath()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 15
ccs 0
cts 12
cp 0
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 20
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
    public static function findFilesToIncludeInConfiguration($cwd)
22
    {
23
        // Get the vendor-bin property from the composer.json.
24
        $composer = Taskman::getComposerFromDirectory($cwd);
25
        $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
            'taskman.yml.dist',
31
            'taskman.yml',
32
        ];
33
34
        // Load default paths.
35
        $filesystemPaths = [
36
            __DIR__ . '/../config/default.yml',
37
            __DIR__ . '/../default.yml',
38
            static::getLocalConfigurationFilepath(),
39
        ];
40
41
        // Find all the composer.json to parse.
42
        $finder = (new Finder())
43
            ->files()
44
            ->exclude('tests')
45
            ->in([\dirname(\realpath($vendorDir)), $cwd])
46
            ->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
        foreach ($finder as $file) {
51
            $composerPackageDirectory = \dirname($file->getPathname());
52
53
            foreach ($filesToLoad as $taskmanFile) {
54
                foreach ([$composerPackageDirectory, $cwd] as $directory) {
55
                    $candidateFile = $directory . '/' . $taskmanFile;
56
                    if (\file_exists($candidateFile)) {
57
                        $filesystemPaths[$candidateFile] = $candidateFile;
58
                    }
59
                }
60
            }
61
62
            $composer = Taskman::getComposerFromDirectory(
63
                $composerPackageDirectory
64
            );
65
66
            $extra = $composer->getExtra();
67
68
            if (empty($extra)) {
69
                continue;
70
            }
71
72
            $extra += ['taskman' => []];
73
            $extra['taskman'] += ['files' => []];
74
75
            foreach ($extra['taskman']['files'] as $commandFile) {
76
                if (\file_exists($commandFile)) {
77
                    $filesystemPaths[$commandFile] = $commandFile;
78
79
                    continue;
80
                }
81
82
                $commandFile = $composerPackageDirectory . '/' . $commandFile;
83
84
                if (\file_exists($commandFile)) {
85
                    $filesystemPaths[$commandFile] = $commandFile;
86
87
                    continue;
88
                }
89
            }
90
        }
91
92
        return static::resolveImports(...\array_values($filesystemPaths));
93
    }
94
95
    /**
96
     * Get the local configuration filepath.
97
     *
98
     * @param string $configuration_file
99
     *   The default filepath.
100
     *
101
     * @return null|string
102
     *   The local configuration file path, or null if it doesn't exist.
103
     */
104
    public static function getLocalConfigurationFilepath($configuration_file = 'phptaskman/taskman.yml')
105
    {
106
        if ($config = \getenv('PHPTASKMAN_CONFIG')) {
107
            return $config;
108
        }
109
110
        if ($config = \getenv('XDG_CONFIG_HOME')) {
111
            return $config . '/' . $configuration_file;
112
        }
113
114
        if ($home = \getenv('HOME')) {
0 ignored issues
show
Unused Code introduced by
The assignment to $home is dead and can be removed.
Loading history...
115
            return \getenv('HOME') . '/.config/' . $configuration_file;
116
        }
117
118
        return null;
119
    }
120
121
    /**
122
     * Resolve YAML configurations files containing imports.
123
     *
124
     * Handles circular dependencies by ignoring them.
125
     *
126
     * @param string[] ...$filepaths
127
     *   A list of YML filepath to parse.
128
     *
129
     * @return string[]
130
     *   The list of all the YAML files to include.
131
     */
132
    public static function resolveImports(...$filepaths)
133
    {
134
        return (new YamlRecursivePathsFinder($filepaths))
135
            ->getAllPaths();
136
    }
137
}
138