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

orchestral / sidekick / 18191084082

02 Oct 2025 11:02AM UTC coverage: 92.35% (-0.9%) from 93.22%
18191084082

push

github

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

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

6 of 7 new or added lines in 1 file covered. (85.71%)

5 existing lines in 2 files now uncovered.

169 of 183 relevant lines covered (92.35%)

6.28 hits per line

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

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

3
namespace Orchestra\Sidekick;
4

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

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

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

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

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

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

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

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

91
            return $response;
22✔
92
        };
22✔
93
    }
94
}
95

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

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

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

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

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

134
        return false;
1✔
135
    }
136
}
137

138
if (! \function_exists('Orchestra\Sidekick\is_testbench_cli')) {
139
    /**
140
     * Determine if command executed via Testbench CLI.
141
     *
142
     * @api
143
     */
144
    function is_testbench_cli(?bool $dusk = null): bool
145
    {
146
        $usingTestbench = \defined('TESTBENCH_CORE');
1✔
147
        $usingTestbenchDusk = \defined('TESTBENCH_DUSK');
1✔
148

149
        return match ($dusk) {
1✔
NEW
150
            false => $usingTestbench === true && $usingTestbenchDusk === false,
×
151
            true => $usingTestbench === true && $usingTestbenchDusk === true,
1✔
152
            default => $usingTestbench === true,
1✔
153
        };
1✔
154
    }
155
}
156

157
if (! \function_exists('Orchestra\Sidekick\transform_relative_path')) {
158
    /**
159
     * Transform relative path.
160
     *
161
     * @api
162
     */
163
    function transform_relative_path(string $path, string $workingPath): string
164
    {
165
        return str_starts_with($path, './')
1✔
166
            ? rtrim($workingPath, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.mb_substr($path, 2)
1✔
167
            : $path;
1✔
168
    }
169
}
170

171
if (! \function_exists('Orchestra\Sidekick\working_path')) {
172
    /**
173
     * Get the working path.
174
     *
175
     * @api
176
     *
177
     * @no-named-arguments
178
     *
179
     * @param  array<int, string|null>|string  ...$path
180
     */
181
    function working_path(array|string $path = ''): string
182
    {
183
        return is_testbench_cli() && \function_exists('Orchestra\Testbench\package_path')
1✔
184
            ? \Orchestra\Testbench\package_path($path)
×
185
            : base_path(join_paths(...Arr::wrap(\func_num_args() > 1 ? \func_get_args() : $path)));
1✔
186
    }
187
}
188

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

209
        /** @var string $laravel */
210
        $laravel = transform(
211
            Application::VERSION,
212
            fn (string $version) => match ($version) {
213
                '13.x-dev' => '13.0.0',
214
                default => $version,
215
            }
216
        );
217

218
        if (\is_null($operator)) {
219
            return version_compare($laravel, $version);
220
        }
221

222
        return version_compare($laravel, $version, $operator);
223
    }
224
}
225

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

248
        /** @var string $phpunit */
249
        $phpunit = transform(
250
            Version::id(),
251
            fn (string $version) => match (true) {
252
                str_starts_with($version, '12.4-') => '12.4.0',
253
                default => $version,
254
            }
255
        );
256

257
        if (\is_null($operator)) {
258
            return version_compare($phpunit, $version);
259
        }
260

261
        return version_compare($phpunit, $version, $operator);
262
    }
263
}
264

265
if (! \function_exists('Orchestra\Sidekick\php_binary')) {
266
    /**
267
     * Determine the PHP Binary.
268
     *
269
     * @api
270
     *
271
     * @codeCoverageIgnore
272
     */
273
    function php_binary(): string
274
    {
275
        return (new PhpExecutableFinder)->find(false) ?: 'php';
276
    }
277
}
278

279
if (! \function_exists('Orchestra\Sidekick\windows_os')) {
280
    /**
281
     * Determine whether the current environment is Windows-based.
282
     *
283
     * @api
284
     *
285
     * @codeCoverageIgnore
286
     */
287
    function windows_os(): bool
288
    {
289
        return PHP_OS_FAMILY === 'Windows';
290
    }
291
}
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

© 2026 Coveralls, Inc