Completed
Push — master ( ff8711...d29de7 )
by Pol
05:47
created

Config   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 77.27%

Importance

Changes 0
Metric Value
eloc 46
dl 0
loc 122
ccs 34
cts 44
cp 0.7727
rs 10
c 0
b 0
f 0
wmc 12

3 Methods

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