Completed
Push — master ( 8d6189...196a37 )
by Pol
04:33 queued 31s
created

Config   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Test Coverage

Coverage 85.11%

Importance

Changes 0
Metric Value
eloc 49
dl 0
loc 131
ccs 40
cts 47
cp 0.8511
rs 10
c 0
b 0
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getLocalConfigurationFilepath() 0 15 4
A resolveImports() 0 4 1
B findFilesToIncludeInConfiguration() 0 76 7
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
        // Check if composer.json exists.
23 1
        $composerPath = \realpath($cwd . '/composer.json');
24
25 1
        if (false === $composerPath) {
26
            return [];
27
        }
28
29
        // Get the vendor-bin property from the composer.json.
30 1
        $composerConfig = Taskman::createJsonConfiguration([$composerPath]);
31 1
        $vendorDir = $composerConfig->get('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
        // Check if composer.lock exists.
48 1
        $composerLockPath = \realpath($cwd . '/composer.lock');
49
50 1
        if (false === $composerLockPath) {
51
            return [];
52
        }
53
54 1
        $composerLockConfig = Taskman::createJsonConfiguration(
55 1
            [$composerLockPath]
56
        );
57
58
        // Get the dependencies packages directories.
59 1
        $packageDirectories = \array_filter(
60 1
            \array_map(
61
                static function ($package) use ($vendorDir) {
62 1
                    return \realpath($vendorDir . '/' . $package['name']);
63 1
                },
64 1
                \array_merge(
65 1
                    $composerLockConfig->get('packages', []),
66 1
                    $composerLockConfig->get('packages-dev', [])
67
                )
68
            )
69
        );
70
71 1
        $packageDirectories[] = $cwd;
72
73
        // Loop over each composer.json, deduct the package directory and probe for files to include.
74 1
        foreach ($packageDirectories as $packageDirectory) {
75 1
            foreach ($filesToLoad as $taskmanFile) {
76 1
                foreach ([$packageDirectory, $cwd] as $directory) {
77 1
                    $candidateFile = $directory . '/' . $taskmanFile;
78 1
                    $filesystemPaths[$candidateFile] = $candidateFile;
79
                }
80
            }
81
82 1
            $composerConfig = Taskman::createJsonConfiguration(
83 1
                [$packageDirectory . '/composer.json']
84
            );
85
86 1
            foreach ($composerConfig->get('extra.taskman.files', []) as $commandFile) {
87
                $filesystemPaths[$commandFile] = $commandFile;
88
                $commandFile = $packageDirectory . '/' . $commandFile;
89 1
                $filesystemPaths[$commandFile] = $commandFile;
90
            }
91
        }
92
93 1
        return \array_filter(
94 1
            static::resolveImports(...\array_values($filesystemPaths)),
95 1
            'file_exists'
96
        );
97
    }
98
99
    /**
100
     * Get the local configuration filepath.
101
     *
102
     * @param string $configuration_file
103
     *   The default filepath.
104
     *
105
     * @return null|string
106
     *   The local configuration file path, or null if it doesn't exist.
107
     */
108 1
    public static function getLocalConfigurationFilepath($configuration_file = 'phptaskman/taskman.yml')
109
    {
110 1
        if ($config = \getenv('PHPTASKMAN_CONFIG')) {
111
            return $config;
112
        }
113
114 1
        if ($config = \getenv('XDG_CONFIG_HOME')) {
115
            return $config . '/' . $configuration_file;
116
        }
117
118 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...
119 1
            return \getenv('HOME') . '/.config/' . $configuration_file;
120
        }
121
122
        return null;
123
    }
124
125
    /**
126
     * Resolve YAML configurations files containing imports.
127
     *
128
     * Handles circular dependencies by ignoring them.
129
     *
130
     * @param string[] ...$filepaths
131
     *   A list of YML filepath to parse.
132
     *
133
     * @return string[]
134
     *   The list of all the YAML files to include.
135
     */
136 1
    public static function resolveImports(...$filepaths)
137
    {
138 1
        return (new YamlRecursivePathsFinder($filepaths))
139 1
            ->getAllPaths();
140
    }
141
}
142