Skip to content

Commit

Permalink
Merge pull request #105 from duncan3dc/fallback-to-installed-json
Browse files Browse the repository at this point in the history
Use installed.json instead of relying on each package's composer.json
  • Loading branch information
maglnet authored Mar 10, 2019
2 parents 63bacd6 + 57cbad2 commit baf224d
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace ComposerRequireChecker\Exception;

class DependenciesNotInstalledException extends \Exception
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace ComposerRequireChecker\FileLocator;

use ComposerRequireChecker\Exception\DependenciesNotInstalledException;
use ComposerRequireChecker\Exception\NotReadableException;
use ComposerRequireChecker\JsonLoader;
use Generator;
use function array_key_exists;
use function file_get_contents;
use function json_decode;

final class LocateComposerPackageDirectDependenciesSourceFiles
{
Expand All @@ -13,23 +18,48 @@ public function __invoke(string $composerJsonPath): Generator

$composerJson = json_decode(file_get_contents($composerJsonPath), true);
$configVendorDir = $composerJson['config']['vendor-dir'] ?? 'vendor';
$vendorDirs = array_values(
array_map(
function (string $vendorName) use ($packageDir, $configVendorDir) {
return $packageDir . '/' . $configVendorDir . '/' . $vendorName;
},
array_keys($composerJson['require'] ?? [])
)
);

foreach ($vendorDirs as $vendorDir) {
if (!file_exists($vendorDir . '/composer.json')) {
$vendorDirs = [];
foreach ($composerJson['require'] ?? [] as $vendorName => $vendorRequiredVersion) {
$vendorDirs[$vendorName] = $packageDir . '/' . $configVendorDir . '/' . $vendorName;
};

$installedPackages = $this->getInstalledPackages($packageDir . '/' . $configVendorDir);

foreach ($vendorDirs as $vendorName => $vendorDir) {
if (!array_key_exists($vendorName, $installedPackages)) {
continue;
}

$composerData = (new JsonLoader($vendorDir . '/composer.json'))->getData();
yield from (new LocateComposerPackageSourceFiles())->__invoke($installedPackages[$vendorName], $vendorDir);
}
}


yield from (new LocateComposerPackageSourceFiles())->__invoke($composerData, $vendorDir);
/**
* Lookup each vendor package's composer.json info from installed.json
*
* @param string $vendorDir
*
* @return array Keys are the package name and value is the composer.json as an array
* @throws DependenciesNotInstalledException When composer install/update has not been run
*/
private function getInstalledPackages(string $vendorDir): array
{
try {
$installedData = (new JsonLoader($vendorDir . '/composer/installed.json'))->getData();
} catch (NotReadableException $e) {
$message = 'The composer dependencies have not been installed, run composer install/update first';
throw new DependenciesNotInstalledException($message);
}

$installedPackages = [];

$packages = $installedData['packages'] ?? $installedData;
foreach ($packages as $vendorJson) {
$vendorName = $vendorJson['name'];
$installedPackages[$vendorName] = $vendorJson;
}

return $installedPackages;
}
}
2 changes: 1 addition & 1 deletion test/ComposerRequireCheckerTest/BinaryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ public function testInvalidConfiguration()
$path = __DIR__ . "/../fixtures/validJson.json";
exec("{$this->bin} check {$path} 2>&1", $output, $return);
$this->assertSame(1, $return);
$this->assertContains("please check your configuration", implode("\n", $output));
$this->assertContains("dependencies have not been installed", implode("\n", $output));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ protected function setUp()

public function testNoDependencies()
{
$composerJson = vfsStream::newFile('composer.json')->at($this->root)->withContent('{}')->url();
vfsStream::create([
'composer.json' => '{}',
'vendor' => [
'composer' => [
'installed.json' => '{"packages":[]}',
],
],
]);

$files = $this->locate($composerJson);
$files = $this->locate($this->root->getChild('composer.json')->url());

$this->assertCount(0, $files);
}
Expand All @@ -39,9 +46,11 @@ public function testSingleDependency()
vfsStream::create([
'composer.json' => '{"require":{"foo/bar": "^1.0"}}',
'vendor' => [
'composer' => [
'installed.json' => '{"packages":[{"name": "foo/bar", "autoload":{"psr-4":{"":"src"}}}]}',
],
'foo' => [
'bar' => [
'composer.json' => '{"autoload":{"psr-4":{"":"src"}}}',
'src' => [
'MyClass.php' => '',
],
Expand All @@ -64,6 +73,9 @@ public function testVendorDirsWithoutComposerFilesAreIgnored()
vfsStream::create([
'composer.json' => '{"require": {"foo/bar": "^1.0"}}',
'vendor' => [
'composer' => [
'installed.json' => '{"packages":[]}',
],
'foo' => [
'bar' => [
'src' => [
Expand All @@ -84,9 +96,11 @@ public function testVendorConfigSettingIsBeingUsed()
vfsStream::create([
'composer.json' => '{"require":{"foo/bar": "^1.0"},"config":{"vendor-dir":"alternate-vendor"}}',
'alternate-vendor' => [
'composer' => [
'installed.json' => '{"packages":[{"name": "foo/bar", "autoload":{"psr-4":{"":"src"}}}]}',
],
'foo' => [
'bar' => [
'composer.json' => '{"autoload":{"psr-4":{"":"src"}}}',
'src' => [
'MyClass.php' => '',
],
Expand All @@ -104,6 +118,70 @@ public function testVendorConfigSettingIsBeingUsed()
$this->assertSame($expectedFile, $actualFile);
}

public function testInstalledJsonUsedAsFallback()
{
vfsStream::create([
'composer.json' => '{"require":{"foo/bar": "^1.0"}}',
'vendor' => [
'composer' => [
'installed.json' => '{"packages": [{"name": "foo/bar", "autoload":{"psr-4":{"":"src"}}}]}',
],
'foo' => [
'bar' => [
'src' => [
'MyClass.php' => '',
],
],
],
],
]);

$files = $this->locate($this->root->getChild('composer.json')->url());

$this->assertCount(1, $files);

$expectedFile = $this->root->getChild('vendor/foo/bar/src/MyClass.php')->url();
$actualFile = str_replace('\\', '/', reset($files));
$this->assertSame($expectedFile, $actualFile);

# Ensure we didn't leave our temporary composer.json lying around
$this->assertFalse($this->root->hasChild('vendor/foo/bar/composer.json'));
}


/**
* https://github.com/composer/composer/pull/7999
*/
public function testOldInstalledJsonUsedAsFallback()
{
vfsStream::create([
'composer.json' => '{"require":{"foo/bar": "^1.0"}}',
'vendor' => [
'composer' => [
'installed.json' => '[{"name": "foo/bar", "autoload":{"psr-4":{"":"src"}}}]',
],
'foo' => [
'bar' => [
'src' => [
'MyClass.php' => '',
],
],
],
],
]);

$files = $this->locate($this->root->getChild('composer.json')->url());

$this->assertCount(1, $files);

$expectedFile = $this->root->getChild('vendor/foo/bar/src/MyClass.php')->url();
$actualFile = str_replace('\\', '/', reset($files));
$this->assertSame($expectedFile, $actualFile);

# Ensure we didn't leave our temporary composer.json lying around
$this->assertFalse($this->root->hasChild('vendor/foo/bar/composer.json'));
}

/**
* @return string[]
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]

0 comments on commit baf224d

Please sign in to comment.