Repository: Roave/BetterReflection (php)

Issue:
Misleading exception message
After adding #711, the exception message should be correct. I overlooked this as part of my PR before. 

I've just seen that the exception needs to be adjusted. It still contains path-info to vendor/composer/installed.json

https://github.com/Roave/BetterReflection/blob/ecd6c1e0af34df5bc2d94f850f2b37f1dc29b782/src/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJson.php#L16

It's not critical, but misleading, but I would need to add the vendor-dir to the input variables for the exception otherwise the vendor-dir would be unknown to the function. 

Feel free to assign me and I'll try to cleanup my mess. 

Pull request:
[BUGFIX] Add custom `vendor-dir` to `MakeLocationForInstalledJson` + Correcting exception messages
Resolves #714 

Patch:
diff --git a/src/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJson.php b/src/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJson.php
index 8fd7963c..a90c218f 100644
--- a/src/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJson.php
+++ b/src/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJson.php
@@ -13,7 +13,7 @@ final class MissingInstalledJson extends UnexpectedValueException implements Exc
     public static function inProjectPath(string $path): self
     {
         return new self(sprintf(
-            'Could not locate a "vendor/composer/installed.json" file in "%s"',
+            'Could not locate a "composer/installed.json" file in "%s"',
             $path,
         ));
     }
diff --git a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php
index 89a0feba..6350c1a2 100644
--- a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php
+++ b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php
@@ -56,7 +56,7 @@ final class MakeLocatorForComposerJsonAndInstalledJson
         $installedJsonPath = $realInstallationPath . '/' . $vendorDir . '/composer/installed.json';
 
         if (! file_exists($installedJsonPath)) {
-            throw MissingInstalledJson::inProjectPath($installationPath);
+            throw MissingInstalledJson::inProjectPath($realInstallationPath . '/' . $vendorDir);
         }
 
         /** @var array{packages: list<array>}|list<array>|null $installedJson */
diff --git a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php
index abc2c8c6..7e2652dd 100644
--- a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php
+++ b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php
@@ -8,6 +8,7 @@ use Roave\BetterReflection\SourceLocator\Ast\Locator;
 use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
 use Roave\BetterReflection\SourceLocator\Type\Composer\Factory\Exception\FailedToParseJson;
 use Roave\BetterReflection\SourceLocator\Type\Composer\Factory\Exception\InvalidProjectDirectory;
+use Roave\BetterReflection\SourceLocator\Type\Composer\Factory\Exception\MissingComposerJson;
 use Roave\BetterReflection\SourceLocator\Type\Composer\Factory\Exception\MissingInstalledJson;
 use Roave\BetterReflection\SourceLocator\Type\Composer\Psr\Psr0Mapping;
 use Roave\BetterReflection\SourceLocator\Type\Composer\Psr\Psr4Mapping;
@@ -37,10 +38,25 @@ final class MakeLocatorForInstalledJson
             throw InvalidProjectDirectory::atPath($installationPath);
         }
 
-        $installedJsonPath = $realInstallationPath . '/vendor/composer/installed.json';
+        $composerJsonPath = $realInstallationPath . '/composer.json';
+
+        if (! file_exists($composerJsonPath)) {
+            throw MissingComposerJson::inProjectPath($installationPath);
+        }
+
+        /**
+         * @psalm-var array{
+         * autoload: array{classmap: array<int, string>, files: array<int, string>, psr-4: array<string, array<int, string>>, psr-0: array<string, array<int, string>>},
+         * config: array{vendor-dir?: string}
+         * }|null $composer
+         */
+        $composer  = json_decode((string) file_get_contents($composerJsonPath), true);
+        $vendorDir = $composer['config']['vendor-dir'] ?? 'vendor';
+
+        $installedJsonPath = $realInstallationPath . '/' . $vendorDir . '/composer/installed.json';
 
         if (! file_exists($installedJsonPath)) {
-            throw MissingInstalledJson::inProjectPath($installationPath);
+            throw MissingInstalledJson::inProjectPath($realInstallationPath . '/' . $vendorDir);
         }
 
         /** @var array{packages: list<array>}|list<array>|null $installedJson */


Test patch:
diff --git a/test/unit/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJsonTest.php b/test/unit/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJsonTest.php
index 720ef0b7..dc4ac2d6 100644
--- a/test/unit/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJsonTest.php
+++ b/test/unit/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJsonTest.php
@@ -15,8 +15,8 @@ class MissingInstalledJsonTest extends TestCase
     public function testInProjectPath(): void
     {
         self::assertSame(
-            'Could not locate a "vendor/composer/installed.json" file in "foo/bar"',
-            MissingInstalledJson::inProjectPath('foo/bar')
+            'Could not locate a "composer/installed.json" file in "foo/bar/vendor"',
+            MissingInstalledJson::inProjectPath('foo/bar/vendor')
                 ->getMessage(),
         );
     }