• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

move-elevator / composer-translation-validator / 16402091592

20 Jul 2025 04:47PM UTC coverage: 96.554% (-0.009%) from 96.563%
16402091592

push

github

web-flow
Merge pull request #39 from move-elevator/file-headers

feat: add file headers to all PHP files for licensing and attribution

108 of 118 new or added lines in 32 files covered. (91.53%)

1737 of 1799 relevant lines covered (96.55%)

8.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.67
/src/Config/ConfigFileReader.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer plugin "composer-translation-validator".
7
 *
8
 * Copyright (C) 2025 Konrad Michalik <km@move-elevator.de>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace MoveElevator\ComposerTranslationValidator\Config;
25

26
use InvalidArgumentException;
27
use JsonException;
28
use RuntimeException;
29
use Symfony\Component\Yaml\Yaml;
30

31
class ConfigFileReader
32
{
33
    public function __construct(
15✔
34
        private readonly ConfigFactory $factory = new ConfigFactory(),
35
    ) {}
15✔
36

37
    /**
38
     * @return array<string, mixed>
39
     *
40
     * @throws JsonException
41
     */
42
    public function readFile(string $configPath): array
11✔
43
    {
44
        if (!file_exists($configPath)) {
11✔
45
            throw new InvalidArgumentException("Configuration file not found: {$configPath}");
1✔
46
        }
47

48
        if (!is_readable($configPath)) {
10✔
49
            throw new RuntimeException("Configuration file is not readable: {$configPath}");
1✔
50
        }
51

52
        $extension = pathinfo($configPath, PATHINFO_EXTENSION);
9✔
53

54
        return match ($extension) {
9✔
55
            'php' => $this->readPhpConfigAsArray($configPath),
1✔
56
            'json' => $this->readJsonConfig($configPath),
4✔
57
            'yaml', 'yml' => $this->readYamlConfig($configPath),
3✔
58
            default => throw new InvalidArgumentException("Unsupported configuration file format: {$extension}"),
5✔
59
        };
9✔
60
    }
61

62
    /**
63
     * @throws JsonException
64
     */
65
    public function readAsConfig(string $configPath): TranslationValidatorConfig
5✔
66
    {
67
        $extension = pathinfo($configPath, PATHINFO_EXTENSION);
5✔
68

69
        if ('php' === $extension) {
5✔
70
            return $this->readPhpConfig($configPath);
4✔
71
        }
72

73
        $data = $this->readFile($configPath);
1✔
74

75
        return $this->factory->createFromArray($data);
1✔
76
    }
77

78
    /**
79
     * @return array<string, mixed>
80
     */
81
    private function readPhpConfigAsArray(string $configPath): array
1✔
82
    {
83
        return $this->readPhpConfig($configPath)->toArray();
1✔
84
    }
85

86
    private function readPhpConfig(string $configPath): TranslationValidatorConfig
5✔
87
    {
88
        $realPath = realpath($configPath);
5✔
89
        if (false === $realPath) {
5✔
90
            throw new RuntimeException("Invalid configuration file path: {$configPath}");
1✔
91
        }
92
        $config = require $realPath;
4✔
93

94
        if (!$config instanceof TranslationValidatorConfig) {
4✔
95
            throw new RuntimeException('PHP configuration file must return an instance of TranslationValidatorConfig');
1✔
96
        }
97

98
        return $config;
3✔
99
    }
100

101
    /**
102
     * @return array<string, mixed>
103
     *
104
     * @throws JsonException
105
     */
106
    private function readJsonConfig(string $configPath): array
4✔
107
    {
108
        $content = file_get_contents($configPath);
4✔
109
        if (false === $content) {
4✔
NEW
110
            throw new RuntimeException("Failed to read configuration file: {$configPath}");
×
111
        }
112

113
        $data = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
4✔
114
        if (!is_array($data)) {
3✔
115
            throw new RuntimeException("Invalid JSON configuration file: {$configPath}");
1✔
116
        }
117

118
        return $data;
2✔
119
    }
120

121
    /**
122
     * @return array<string, mixed>
123
     */
124
    private function readYamlConfig(string $configPath): array
3✔
125
    {
126
        $data = Yaml::parseFile($configPath);
3✔
127
        if (!is_array($data)) {
2✔
128
            throw new RuntimeException("Invalid YAML configuration file: {$configPath}");
1✔
129
        }
130

131
        return $data;
1✔
132
    }
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc