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

JBZoo / Cli / 18073060279

28 Sep 2025 10:34AM UTC coverage: 80.982% (-0.3%) from 81.315%
18073060279

push

github

web-flow
build(deps): Upgrade Symfony to v7 and PHP to 8.2 (#30)

- Bump Symfony components (console, process, lock) to ^7.3.4.
- Increase minimum PHP requirement to 8.2.
- Replace external process manager with an internal
JBZoo\Cli\ProcessManager implementation to maintain compatibility with
Symfony 7.
- Update other core dependencies: jbzoo/utils, jbzoo/event,
monolog/monolog, jbzoo/toolbox-dev.
- Adjust CI workflows to support PHP 8.2+ and remove scheduled runs.
- Refactor various classes to be final and update type hints for
improved code quality and Psalm compatibility.
- Remove deprecated phpstan.neon configuration file.

65 of 78 new or added lines in 6 files covered. (83.33%)

15 existing lines in 3 files now uncovered.

1056 of 1304 relevant lines covered (80.98%)

229.63 hits per line

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

61.11
/src/CliHelper.php
1
<?php
2

3
/**
4
 * JBZoo Toolbox - Cli.
5
 *
6
 * This file is part of the JBZoo Toolbox project.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT
11
 * @copyright  Copyright (C) JBZoo.com, All rights reserved.
12
 * @see        https://github.com/JBZoo/Cli
13
 */
14

15
declare(strict_types=1);
16

17
namespace JBZoo\Cli;
18

19
use JBZoo\Cli\OutputMods\AbstractOutputMode;
20
use JBZoo\Utils\Env;
21
use JBZoo\Utils\Str;
22

23
use function JBZoo\Utils\int;
24
use function JBZoo\Utils\isStrEmpty;
25

26
final class CliHelper
27
{
28
    private static ?AbstractOutputMode $outputMode = null;
29

30
    public static function arrayMergeRecursiveDistinct(array &$array1, array &$array2): array
31
    {
32
        $merged = $array1;
18✔
33

34
        foreach ($array2 as $key => &$value) {
18✔
35
            if (\is_array($value) && isset($merged[$key]) && \is_array($merged[$key])) {
18✔
36
                $merged[$key] = self::arrayMergeRecursiveDistinct($merged[$key], $value);
18✔
37
            } else {
38
                $merged[$key] = $value;
18✔
39
            }
40
        }
41

42
        return $merged;
18✔
43
    }
44

45
    public static function getRootPath(): string
46
    {
47
        $rootPath = \defined('JBZOO_PATH_ROOT') ? (string)JBZOO_PATH_ROOT : null;
18✔
48
        if (isStrEmpty($rootPath)) {
18✔
UNCOV
49
            return Env::string('JBZOO_PATH_ROOT');
×
50
        }
51

52
        return (string)$rootPath;
18✔
53
    }
54

55
    public static function getBinPath(): string
56
    {
57
        $binPath = \defined('JBZOO_PATH_BIN') ? (string)JBZOO_PATH_BIN : null;
18✔
58
        if (isStrEmpty($binPath)) {
18✔
UNCOV
59
            return Env::string('JBZOO_PATH_BIN');
×
60
        }
61

62
        return (string)$binPath;
18✔
63
    }
64

65
    /**
66
     * @see https://github.com/phpstan/phpstan-src/blob/f8be122188/src/Process/CpuCoreCounter.php
67
     */
68
    public static function getNumberOfCpuCores(): int
69
    {
70
        static $numberOfCpuCores = null;
18✔
71

72
        if ($numberOfCpuCores !== null) {
18✔
73
            return $numberOfCpuCores;
18✔
74
        }
75

76
        if (!\function_exists('proc_open')) {
18✔
77
            return $numberOfCpuCores = 1;
×
78
        }
79

80
        // from brianium/paratest
81
        // Linux (and potentially Windows with linux sub systems)
82
        if (\is_file('/proc/cpuinfo')) {
18✔
83
            $cpuinfo = \file_get_contents('/proc/cpuinfo');
18✔
84
            if ($cpuinfo !== false) {
18✔
85
                \preg_match_all('/^processor/m', $cpuinfo, $matches);
18✔
86

87
                return $numberOfCpuCores = \count($matches[0]);
18✔
88
            }
89
        }
90

91
        // Windows
92
        if (\DIRECTORY_SEPARATOR === '\\') {
×
93
            $process = \popen('wmic cpu get NumberOfLogicalProcessors', 'rb');
×
94
            if (\is_resource($process)) {
×
95
                /** @phan-suppress-next-line PhanPluginUseReturnValueInternalKnown */
96
                \fgets($process);
×
97
                $cores = int(\fgets($process));
×
98
                \pclose($process);
×
99

100
                return $numberOfCpuCores = $cores;
×
101
            }
102
        }
103

104
        // *nix (Linux, BSD and Mac)
105
        $process = \popen('sysctl -n hw.ncpu', 'rb');
×
106
        if (\is_resource($process)) {
×
107
            $cores = int(\fgets($process));
×
108
            \pclose($process);
×
109

110
            return $numberOfCpuCores = $cores;
×
111
        }
112

113
        return $numberOfCpuCores = 2;
×
114
    }
115

116
    public static function renderListForHelpDescription(array $keyValues): string
117
    {
118
        $result = '';
846✔
119

120
        foreach ($keyValues as $key => $value) {
846✔
121
            $result .= "<comment>{$key}</comment> - {$value}\n";
846✔
122
        }
123

124
        return $result;
846✔
125
    }
126

127
    public static function createOrGetTraceId(): string
128
    {
129
        static $traceId = null;
234✔
130

131
        if ($traceId === null) {
234✔
132
            $traceId = Str::uuid();
234✔
133
        }
134

135
        return $traceId;
234✔
136
    }
137

138
    public static function renderExpectedValues(array $values): string
139
    {
140
        $result = '';
×
141

142
        foreach ($values as $value) {
×
143
            $result .= "\"{$value}\", ";
×
144
        }
145

146
        return \rtrim($result);
×
147
    }
148

149
    public static function setInstance(AbstractOutputMode $outputMode): void
150
    {
151
        self::$outputMode = $outputMode;
846✔
152
    }
153

154
    public static function getInstance(): AbstractOutputMode
155
    {
156
        $result = self::$outputMode;
270✔
157

158
        if ($result === null) {
270✔
159
            throw new Exception('Output mode is not defined');
×
160
        }
161

162
        return $result;
270✔
163
    }
164
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc