Skip to content

Commit 3df5165

Browse files
update
1 parent 0b13b48 commit 3df5165

File tree

1 file changed

+66
-13
lines changed

1 file changed

+66
-13
lines changed

src/Capsule/Traits/ArtisanDiscovery.php

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,50 @@ private function discoverExternal(): void
119119

120120
try {
121121
$provider = new $fqcn();
122-
if (method_exists($provider, 'register')) {
122+
$didRegister = false;
123+
124+
// Preferred: provider explicitly implements our interface
125+
if ($provider instanceof \Tamedevelopers\Support\Capsule\CommandProviderInterface) {
123126
$provider->register($this);
127+
$didRegister = true;
128+
}
129+
// Fallback: detect register() signature and call appropriately
130+
elseif (method_exists($provider, 'register')) {
131+
try {
132+
$rm = new \ReflectionMethod($provider, 'register');
133+
$paramCount = $rm->getNumberOfParameters();
134+
135+
if ($paramCount === 0) {
136+
// Laravel-like providers often have register() with no args
137+
$provider->register();
138+
$didRegister = true;
139+
} else {
140+
// If first param accepts our Artisan (or is untyped/mixed/optional), pass it
141+
$first = $rm->getParameters()[0];
142+
$canPassArtisan = true;
143+
144+
if ($first->hasType()) {
145+
$t = $first->getType();
146+
if ($t instanceof \ReflectionNamedType) {
147+
$name = ltrim($t->getName(), '\\');
148+
$canPassArtisan = ($name === 'Tamedevelopers\\Support\\Capsule\\Artisan') || ($name === 'mixed') || ($name === 'array') || ($name === 'object');
149+
}
150+
}
151+
152+
if ($canPassArtisan) {
153+
$provider->register($this);
154+
$didRegister = true;
155+
} elseif ($first->isOptional()) {
156+
$provider->register();
157+
$didRegister = true;
158+
}
159+
}
160+
} catch (\Throwable $ignored) {
161+
// If reflection or calling fails, we just skip this provider
162+
}
163+
}
164+
165+
if ($didRegister) {
124166
self::$registeredProviders[$fqcn] = true;
125167
}
126168
} catch (\Throwable $e) {
@@ -131,23 +173,34 @@ private function discoverExternal(): void
131173
}
132174

133175
/**
134-
* Resolve the vendor directory path for both dev (package root) and consumer app.
176+
* Resolve the vendor directory path robustly for both:
177+
* - Developing this package as the root project (support/vendor)
178+
* - When installed inside another project (project/vendor)
135179
*/
136180
private function resolveVendorPath(): ?string
137181
{
138-
// Current file: support/Capsule/Traits/ArtisanDiscovery.php
139-
$packageRoot = \dirname(__DIR__, 3); // .../support
182+
// Start from this file's directory and walk upwards to find:
183+
// - a 'vendor' directory sibling (e.g., support/vendor), or
184+
// - a parent directory named 'vendor' (e.g., project/vendor)
185+
$dir = __DIR__;
186+
187+
for ($i = 0; $i < 8; $i++) {
188+
if ($dir === DIRECTORY_SEPARATOR || $dir === '/' || $dir === '') {
189+
break;
190+
}
140191

141-
// Case 1: developing this package as the root project
142-
$vendor = $packageRoot . DIRECTORY_SEPARATOR . 'vendor';
143-
if (is_dir($vendor)) {
144-
return $vendor;
145-
}
192+
// Case A: current directory is the vendor directory
193+
if (\basename($dir) === 'vendor' && \is_dir($dir)) {
194+
return $dir;
195+
}
196+
197+
// Case B: there is a vendor directory inside the current directory
198+
$candidate = $dir . DIRECTORY_SEPARATOR . 'vendor';
199+
if (\is_dir($candidate)) {
200+
return $candidate;
201+
}
146202

147-
// Case 2: this package is installed as a dependency: project/vendor/tamedevelopers/support/...
148-
$maybeProjectVendor = \dirname($packageRoot, 2); // .../project/vendor
149-
if (is_dir($maybeProjectVendor)) {
150-
return $maybeProjectVendor;
203+
$dir = \dirname($dir);
151204
}
152205

153206
return null;

0 commit comments

Comments
 (0)