Passed
Push — master ( bf93db...a9da14 )
by Pol
02:24
created

Config   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 80%

Importance

Changes 0
Metric Value
eloc 52
dl 0
loc 137
ccs 40
cts 50
cp 0.8
rs 10
c 0
b 0
f 0
wmc 14

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getLocalConfigurationFilepath() 0 15 4
B findFilesToIncludeInConfiguration() 0 82 9
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
9
final class Config
10
{
11
    /**
12
     * Find the files to include in the configuration.
13
     *
14
     * @param string $cwd
15
     *   The current working directory.
16
     *
17
     * @return string[]
18
     *   The list of all the YAML files to include.
19
     */
20 1
    public static function findFilesToIncludeInConfiguration($cwd)
21
    {
22
        // Get the vendor-bin property from the composer.json.
23 1
        $composer = Taskman::createJsonConfiguration([$cwd . '/composer.json']);
24
25 1
        if (null === $composer) {
26
            return [];
27
        }
28
29 1
        $vendorDir = $composer->get('vendor-dir') ?? $cwd . '/vendor';
30
31
        // Keep a reference of the default filename that we need to load from
32
        // each packages.
33
        $filesToLoad = [
34 1
            'taskman.yml.dist',
35
            'taskman.yml',
36
        ];
37
38
        // Load default paths.
39
        $filesystemPaths = [
40 1
            __DIR__ . '/../config/default.yml',
41
            __DIR__ . '/../default.yml',
42 1
            static::getLocalConfigurationFilepath(),
43
        ];
44
45
        // Check if composer.lock exists.
46 1
        $composerLockPath = \realpath($cwd . '/composer.lock');
47
48 1
        if (false === $composerLockPath) {
49
            return [];
50
        }
51
52 1
        $composerLockConfig = Taskman::createJsonConfiguration([$composerLockPath]);
53
54
        // Get the dependencies packages directories.
55 1
        $packageDirectories = \array_filter(
56 1
            \array_map(
57
                static function ($package) use ($cwd, $vendorDir) {
0 ignored issues
show
Unused Code introduced by
The import $cwd is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
58 1
                    return \realpath($vendorDir . '/' . $package['name']);
59 1
                },
60 1
                \array_merge(
61 1
                    $composerLockConfig->get('packages', []),
62 1
                    $composerLockConfig->get('packages-dev', [])
63
                )
64
            )
65
        );
66
67 1
        $packageDirectories[] = $cwd;
68
69
        // Loop over each composer.json, deduct the package directory and probe for files to include.
70 1
        foreach ($packageDirectories as $packageDirectory) {
71 1
            foreach ($filesToLoad as $taskmanFile) {
72 1
                foreach ([$packageDirectory, $cwd] as $directory) {
73 1
                    $candidateFile = $directory . '/' . $taskmanFile;
74 1
                    $filesystemPaths[$candidateFile] = $candidateFile;
75
                }
76
            }
77
78 1
            $composer = Taskman::getComposerFromDirectory(
79 1
                $packageDirectory
80
            );
81
82 1
            if (null === $composer) {
83
                continue;
84
            }
85
86 1
            $extraFiles = $composer->get('extra.taskman.files', []);
87
88 1
            if (empty($extraFiles)) {
89 1
                continue;
90
            }
91
92
            foreach ($extraFiles as $commandFile) {
93
                $filesystemPaths[$commandFile] = $commandFile;
94
                $commandFile = $packageDirectory . '/' . $commandFile;
95
                $filesystemPaths[$commandFile] = $commandFile;
96
            }
97
        }
98
99 1
        return \array_filter(
100 1
            static::resolveImports(...\array_values($filesystemPaths)),
101 1
            'file_exists'
102
        );
103
    }
104
105
    /**
106
     * Get the local configuration filepath.
107
     *
108
     * @param string $configuration_file
109
     *   The default filepath.
110
     *
111
     * @return null|string
112
     *   The local configuration file path, or null if it doesn't exist.
113
     */
114 1
    public static function getLocalConfigurationFilepath($configuration_file = 'phptaskman/taskman.yml')
115
    {
116 1
        if ($config = \getenv('PHPTASKMAN_CONFIG')) {
117
            return $config;
118
        }
119
120 1
        if ($config = \getenv('XDG_CONFIG_HOME')) {
121
            return $config . '/' . $configuration_file;
122
        }
123
124 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...
125 1
            return \getenv('HOME') . '/.config/' . $configuration_file;
126
        }
127
128
        return null;
129
    }
130
131
    /**
132
     * Resolve YAML configurations files containing imports.
133
     *
134
     * Handles circular dependencies by ignoring them.
135
     *
136
     * @param string[] ...$filepaths
137
     *   A list of YML filepath to parse.
138
     *
139
     * @return string[]
140
     *   The list of all the YAML files to include.
141
     */
142 1
    public static function resolveImports(...$filepaths)
143
    {
144 1
        return (new YamlRecursivePathsFinder($filepaths))
145 1
            ->getAllPaths();
146
    }
147
}
148