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

orchestral / sidekick / 18160913675

01 Oct 2025 11:36AM UTC coverage: 93.22% (-2.2%) from 95.376%
18160913675

push

github

crynobone
Merge branch '1.1.x' into 1.2.x

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

0 of 4 new or added lines in 1 file covered. (0.0%)

165 of 177 relevant lines covered (93.22%)

6.62 hits per line

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

82.35
/src/functions.php
1
<?php
2

3
namespace Orchestra\Sidekick;
4

5
use BackedEnum;
6
use Closure;
7
use Illuminate\Foundation\Application;
8
use PHPUnit\Runner\Version;
9
use RuntimeException;
10
use UnitEnum;
11

12
if (! \function_exists('Orchestra\Sidekick\enum_name')) {
13
    /**
14
     * Get the proper name from enum.
15
     *
16
     * @api
17
     *
18
     * @throws \RuntimeException
19
     */
20
    function enum_name(BackedEnum|UnitEnum $enum): string
21
    {
22
        return mb_convert_case(str_replace('_', ' ', $enum->name), MB_CASE_TITLE, 'UTF-8');
5✔
23
    }
24
}
25

26
if (! \function_exists('Orchestra\Sidekick\enum_value')) {
27
    /**
28
     * Get the proper name from enum.
29
     *
30
     * @api
31
     *
32
     * @template TValue
33
     * @template TDefault
34
     *
35
     * @param  TValue  $value
36
     * @param  TDefault|callable(TValue): TDefault  $default
37
     * @return ($value is empty ? TDefault : mixed)
38
     *
39
     * @throws \RuntimeException
40
     */
41
    function enum_value(mixed $value, mixed $default = null): mixed
42
    {
43
        return match (true) {
44
            $value instanceof BackedEnum => $value->value,
20✔
45
            $value instanceof UnitEnum => $value->name,
16✔
46

47
            default => $value ?? value($default),
20✔
48
        };
49
    }
50
}
51

52
if (! \function_exists('Orchestra\Sidekick\join_paths')) {
53
    /**
54
     * Join the given paths together.
55
     *
56
     * @api
57
     */
58
    function join_paths(?string $basePath, string ...$paths): string
59
    {
60
        foreach ($paths as $index => $path) {
20✔
61
            if (empty($path) && $path !== '0') {
20✔
62
                unset($paths[$index]);
20✔
63
            } else {
64
                $paths[$index] = DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR);
20✔
65
            }
66
        }
67

68
        return $basePath.implode('', $paths);
20✔
69
    }
70
}
71

72
if (! \function_exists('Orchestra\Sidekick\once')) {
73
    /**
74
     * Run callback only once.
75
     *
76
     * @api
77
     *
78
     * @param  mixed  $callback
79
     * @return \Closure():mixed
80
     */
81
    function once($callback): Closure
82
    {
83
        $response = new UndefinedValue;
24✔
84

85
        return function () use ($callback, &$response) {
24✔
86
            if ($response instanceof UndefinedValue) {
24✔
87
                $response = value($callback) ?? null;
24✔
88
            }
89

90
            return $response;
24✔
91
        };
24✔
92
    }
93
}
94

95
if (! \function_exists('Orchestra\Sidekick\is_safe_callable')) {
96
    /**
97
     * Determine if the value is a callable and not a string matching an available function name.
98
     *
99
     * @api
100
     */
101
    function is_safe_callable(mixed $value): bool
102
    {
103
        if ($value instanceof Closure) {
6✔
104
            return true;
1✔
105
        }
106

107
        if (! \is_callable($value)) {
5✔
108
            return false;
2✔
109
        }
110

111
        if (\is_array($value)) {
3✔
112
            return \count($value) === 2 && array_is_list($value) && method_exists(...$value);
1✔
113
        }
114

115
        return ! \is_string($value);
2✔
116
    }
117
}
118

119
if (! \function_exists('Orchestra\Sidekick\is_symlink')) {
120
    /**
121
     * Determine if the path is a symlink for both Unix and Windows environments.
122
     *
123
     * @api
124
     */
125
    function is_symlink(string $path): bool
126
    {
127
        if (windows_os() && is_dir($path) && readlink($path) !== $path) {
1✔
128
            return true;
×
129
        } elseif (is_link($path)) {
1✔
130
            return true;
×
131
        }
132

133
        return false;
1✔
134
    }
135
}
136

137
if (! \function_exists('Orchestra\Sidekick\is_testbench_cli')) {
138
    /**
139
     * Determine if command executed via Testbench CLI.
140
     *
141
     * @api
142
     */
143
    function is_testbench_cli(): bool
144
    {
NEW
145
        return \defined('TESTBENCH_CORE') === true;
×
146
    }
147
}
148

149
if (! \function_exists('Orchestra\Sidekick\transform_relative_path')) {
150
    /**
151
     * Transform relative path.
152
     *
153
     * @api
154
     */
155
    function transform_relative_path(string $path, string $workingPath): string
156
    {
157
        return str_starts_with($path, './')
1✔
158
            ? rtrim($workingPath, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.mb_substr($path, 2)
1✔
159
            : $path;
1✔
160
    }
161
}
162

163
if (! \function_exists('Orchestra\Sidekick\working_path')) {
164
    /**
165
     * Get the working path.
166
     *
167
     * @api
168
     *
169
     * @no-named-arguments
170
     *
171
     * @param  array<int, string|null>|string  ...$path
172
     */
173
    function working_path(array|string $path = ''): string
174
    {
NEW
175
        return is_testbench_cli() && \function_exists('Orchestra\Testbench\package_path')
×
NEW
176
            ? \Orchestra\Testbench\package_path($path)
×
NEW
177
            : base_path(join_paths(...Arr::wrap(\func_num_args() > 1 ? \func_get_args() : $path)));
×
178
    }
179
}
180

181
if (! \function_exists('Orchestra\Sidekick\laravel_version_compare')) {
182
    /**
183
     * Laravel version compare.
184
     *
185
     * @api
186
     *
187
     * @template TOperator of string|null
188
     *
189
     * @phpstan-param  TOperator  $operator
190
     *
191
     * @phpstan-return (TOperator is null ? int : bool)
192
     *
193
     * @codeCoverageIgnore
194
     */
195
    function laravel_version_compare(string $version, ?string $operator = null): int|bool
196
    {
197
        if (! class_exists(Application::class)) {
198
            throw new RuntimeException('Unable to verify Laravel Framework version');
199
        }
200

201
        /** @var string $laravel */
202
        $laravel = transform(
203
            Application::VERSION,
204
            fn (string $version) => match ($version) {
205
                '13.x-dev' => '13.0.0',
206
                default => $version,
207
            }
208
        );
209

210
        if (\is_null($operator)) {
211
            return version_compare($laravel, $version);
212
        }
213

214
        return version_compare($laravel, $version, $operator);
215
    }
216
}
217

218
if (! \function_exists('Orchestra\Sidekick\phpunit_version_compare')) {
219
    /**
220
     * PHPUnit version compare.
221
     *
222
     * @api
223
     *
224
     * @template TOperator of string|null
225
     *
226
     * @phpstan-param  TOperator  $operator
227
     *
228
     * @phpstan-return (TOperator is null ? int : bool)
229
     *
230
     * @throws \RuntimeException
231
     *
232
     * @codeCoverageIgnore
233
     */
234
    function phpunit_version_compare(string $version, ?string $operator = null): int|bool
235
    {
236
        if (! class_exists(Version::class)) {
237
            throw new RuntimeException('Unable to verify PHPUnit version');
238
        }
239

240
        /** @var string $phpunit */
241
        $phpunit = transform(
242
            Version::id(),
243
            fn (string $version) => match (true) {
244
                str_starts_with($version, '12.4-') => '12.4.0',
245
                default => $version,
246
            }
247
        );
248

249
        if (\is_null($operator)) {
250
            return version_compare($phpunit, $version);
251
        }
252

253
        return version_compare($phpunit, $version, $operator);
254
    }
255
}
256

257
if (! \function_exists('Orchestra\Sidekick\php_binary')) {
258
    /**
259
     * Determine the PHP Binary.
260
     *
261
     * @api
262
     *
263
     * @codeCoverageIgnore
264
     */
265
    function php_binary(): string
266
    {
267
        return (new PhpExecutableFinder)->find(false) ?: 'php';
268
    }
269
}
270

271
if (! \function_exists('Orchestra\Sidekick\windows_os')) {
272
    /**
273
     * Determine whether the current environment is Windows-based.
274
     *
275
     * @api
276
     *
277
     * @codeCoverageIgnore
278
     */
279
    function windows_os(): bool
280
    {
281
        return PHP_OS_FAMILY === 'Windows';
282
    }
283
}
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