From ae63c209e945a4b96c78ede6410edee1a84108ce Mon Sep 17 00:00:00 2001 From: Vassyli Date: Fri, 29 Jul 2016 09:35:33 +0200 Subject: [PATCH] Clean-ups Left overs to clean and changes from discussion. Fixed config path finding --- bin/daenerys | 2 - config/lotgd.yml | 11 ++++ phpunit.xml | 2 +- src/BootConfiguration.php | 57 +++++++++++++++----- src/BootConfigurationManager.php | 4 +- src/Bootstrap.php | 23 ++++++-- src/ComposerManager.php | 12 +++-- tests/BootstrapTest.php | 91 +++++++------------------------- tests/FakeModule/Bootstrap.php | 26 --------- tests/ModelTestCase.php | 3 +- 10 files changed, 108 insertions(+), 123 deletions(-) create mode 100644 config/lotgd.yml delete mode 100644 tests/FakeModule/Bootstrap.php diff --git a/bin/daenerys b/bin/daenerys index 24a14ac..dd9ec5b 100755 --- a/bin/daenerys +++ b/bin/daenerys @@ -16,7 +16,5 @@ includeIfExists(getcwd() . '/vendor/autoload.php') || includeIfExists(__DIR__ . '/../vendor/autoload.php') || includeIfExists(__DIR__ . '/../autoload.php'); -putenv("LOTGD_CONFIG=./config/test.yml"); - $daenerys = new DaenerysConsole(); $daenerys->run(); \ No newline at end of file diff --git a/config/lotgd.yml b/config/lotgd.yml new file mode 100644 index 0000000..1b49ef8 --- /dev/null +++ b/config/lotgd.yml @@ -0,0 +1,11 @@ +database: + dsn: "sqlite::memory:" + name: daenerys + user: root + password: +game: + epoch: 2016-07-01 00:00:00.0 -8 + offsetSeconds: 0 + daysPerDay: 1 +logs: + path: ../logs diff --git a/phpunit.xml b/phpunit.xml index c9d1a73..9073a4b 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,6 +1,6 @@ - + diff --git a/src/BootConfiguration.php b/src/BootConfiguration.php index e18a5f1..03c17b4 100644 --- a/src/BootConfiguration.php +++ b/src/BootConfiguration.php @@ -24,17 +24,33 @@ class BootConfiguration private $rawConfig; private $models; private $daenerysCommands; + private $cwd; - public function __construct(ComposerManager $composerManager, PackageInterface $package) + public function __construct(ComposerManager $composerManager, PackageInterface $package, string $cwd) { $this->composerManager = $composerManager; $this->package = $package; + $this->cwd = $cwd; $installationManager = $composerManager->getComposer()->getInstallationManager(); - $confFile = $installationManager->getInstallPath($package) . "/lotgd.yml"; + + // only lotgd-modules are installed in the vendor directory + if ($package->getType() === "lotgd-module") { + $confFile = $installationManager->getInstallPath($package) . "/lotgd.yml"; + } + else { + $confFile = $cwd . "/lotgd.yml"; + } $this->rootNamespace = $this->findRootNamespace($package); - $this->rawConfig = Yaml::parse(file_get_contents($confFile)); + if (file_exists($confFile)) { + $this->rawConfig = Yaml::parse(file_get_contents($confFile)); + } + else { + $name = $package->getName(); + $type = $package->getType(); + throw new \Exception("Package {$name} of type {$type} does not have a lotgd.yml in it's root ($confFile)."); + } $this->findEntityDirectory(); $this->findDenerysCommands(); @@ -45,7 +61,6 @@ class BootConfiguration * * This function searches the package's configuration to find it's root namespace. * For this, it uses the following order: - * - look in ["extra"]["lotgd-namespace"] * - check psr-4 autoload configuration. If used, it takes the first element * - check psr-0 autoload configuration. If used, it takes the first element * @param PackageInterface $package @@ -54,24 +69,24 @@ class BootConfiguration */ protected function findRootNamespace(PackageInterface $package): string { - // if one is defined, we use that. - if (isset($package->getExtra()["lotgd-namespace"])) { - return $package->getExtra()["lotgd-namespace"]; - } - $autoload = $package->getAutoload(); if (isset($autoload["psr-4"]) && count($autoload["psr-4"]) > 0) { - return $autoload["psr-4"][0]; + return key($autoload["psr-4"]); } if (isset($autoload["psr-0"]) && count($autoload["psr-0"]) > 0) { - return $autoload["psr-0"][0]; + return key($autoload["psr-0"]); } $name = $package->getName(); throw new \Exception("{$name} has no valid namespace."); } + /** + * Returns a subkey if it exists or null. + * @param array $arguments + * @return type + */ protected function getSubKeyIfItExists(array $arguments) { $parent = $this->rawConfig; @@ -125,7 +140,7 @@ class BootConfiguration $entityNamespace = $this->rootNamespace . $entityNamespace; if (is_null($entityNamespace) === false) { - $entityDirectory = $this->composerManager->getComposer()->translateNamespaceToPath($entityNamespace); + $entityDirectory = $this->composerManager->translateNamespaceToPath($entityNamespace, $this->cwd); if (is_dir($entityDirectory) === false) { throw new \Exception("{$entityDirectory}, generated from {$entityNamespace}, is not a valid directory."); @@ -153,6 +168,10 @@ class BootConfiguration return $this->entityDirectory; } + /** + * Searches the config file for daenerys commands and, if found, adds the class name to a list + * @return type + */ protected function findDenerysCommands() { $list = $this->iterateKey("bootstrap", "daenerysCommands"); @@ -167,6 +186,20 @@ class BootConfiguration } } + /** + * Returns true if this configuration has daenerys commands + * @return bool + */ + public function hasDaenerysCommands(): bool + { + return count($this->daenerysCommands) > 0 ? true : false; + } + + /** + * Adds daenerys commands from this configuration to the application. + * @param \LotGD\Core\Game $game + * @param Application $application + */ public function addDaenerysCommands(Game $game, Application $application) { foreach ($this->daenerysCommands as $command) { diff --git a/src/BootConfigurationManager.php b/src/BootConfigurationManager.php index cbcc6ec..4a30ebf 100644 --- a/src/BootConfigurationManager.php +++ b/src/BootConfigurationManager.php @@ -22,7 +22,7 @@ class BootConfigurationManager foreach($packages as $package) { if ($package->getType() === "lotgd-crate" || $package->getType() === "lotgd-module") { - $this->configurations[] = new BootConfiguration($composerManager, $package); + $this->configurations[] = new BootConfiguration($composerManager, $package, $cwd); } } } @@ -48,7 +48,7 @@ class BootConfigurationManager { foreach ($this->configurations as $config) { if ($config->hasDaenerysCommands()) { - $this->addDaenerysCommands($game, $application); + $config->addDaenerysCommands($game, $application); } } } diff --git a/src/Bootstrap.php b/src/Bootstrap.php index 4989f0b..2d2cef9 100644 --- a/src/Bootstrap.php +++ b/src/Bootstrap.php @@ -32,16 +32,18 @@ class Bootstrap /** * Create a new Game object, with all the necessary configuration. + * @param string $rootDir The root directory if it is different from getcwd() * @return Game The newly created Game object. */ - public static function createGame(): Game + public static function createGame(string $rootDir = null): Game { $game = new self(); - return $game->getGame(); + return $game->getGame($rootDir); } /** * Starts the game kernel with the most important classes and returns the object + * @param string $rootDir The root directory if it is different from getcwd() * @return Game */ public function getGame(string $rootDir = null): Game @@ -64,7 +66,13 @@ class Bootstrap return $this->game; } - public function createBootConfigurationManager( + /** + * Creates the boot configuration manager + * @param ComposerManager $composerManager + * @param string $cwd + * @return \LotGD\Core\BootConfigurationManager + */ + protected function createBootConfigurationManager( ComposerManager $composerManager, string $cwd ): BootConfigurationManager { @@ -136,7 +144,14 @@ class Bootstrap */ protected function createConfiguration(): Configuration { - $configFilePath = getenv('LOTGD_CONFIG') ?? "/config/lotgd.yml"; + $configFilePath = getenv('LOTGD_CONFIG'); + + if (empty($configFilePath)) { + $configFilePath = $this->rootDir . "/config/lotgd.yml"; + } + else { + $configFilePath = $this->rootDir . $configFilePath; + } if ($configFilePath === false || strlen($configFilePath) == 0 || is_file($configFilePath) === false) { throw new InvalidConfigurationException("Invalid or missing configuration file: {$configFilePath}."); diff --git a/src/ComposerManager.php b/src/ComposerManager.php index 01db5e9..7a570dc 100644 --- a/src/ComposerManager.php +++ b/src/ComposerManager.php @@ -97,14 +97,16 @@ class ComposerManager /** * Find the filesystem path where the code for a namespace can be found. * @param string $namespace The namespace to translate. + * @param string $cwd Current working directory * @return string|null Path representing $namespace or null if $namespace * cannot be found or if the path does not exist. */ - public function translateNamespaceToPath(string $namespace) + public function translateNamespaceToPath(string $namespace, string $cwd = null) { // Find the directory for this namespace by using the autoloader's // classmap. - $autoloader = require(ComposerManager::findAutoloader()); + $cwd = $cwd ?? getcwd(); + $autoloader = require(ComposerManager::findAutoloader($cwd)); $prefixes = $autoloader->getPrefixesPsr4(); // Standardize the namespace to remove any leading \ and add a trailing \ @@ -145,16 +147,18 @@ class ComposerManager /** * Returns a path (could be relative) to the proper autoload.php file in * the current setup. + * @param string $cwd current working directory */ - public static function findAutoloader(): string + public static function findAutoloader(string $cwd): string { // Dance to find the autoloader. // TOOD: change this to open up the Composer config and use $c['config']['vendor-dir'] instead of "vendor" $order = [ - getcwd() . '/vendor/autoload.php', + $cwd . '/vendor/autoload.php', __DIR__ . '/../vendor/autoload.php', __DIR__ . '/../autoload.php', ]; + foreach ($order as $path) { if (file_exists($path)) { return $path; diff --git a/tests/BootstrapTest.php b/tests/BootstrapTest.php index 59a2e97..3667765 100644 --- a/tests/BootstrapTest.php +++ b/tests/BootstrapTest.php @@ -32,25 +32,6 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase $this->assertNotNull($g->getLogger()); } - public function testWorkingFromChildWorkingDirectory() - { - $cwd = getcwd(); - $oldconf = getenv("LOTGD_CONFIG"); - chdir($cwd . "/tests/"); - putenv("LOTGD_CONFIG=../".$oldconf); - - $this->assertStringEndsWith("/tests", getcwd()); - $this->assertStringStartsWith(".././", getenv("LOTGD_CONFIG")); - - $game = Bootstrap::createGame(); - - chdir($cwd); - putenv("LOTGD_CONFIG=" . $oldconf); - - $this->assertStringEndsNotWith("/tests", getcwd()); - $this->assertStringStartsNotWith(".././", getenv("LOTGD_CONFIG")); - } - public function testBootstrapLoadsPackageModels() { $installationManager = $this->getMockBuilder(InstallationManager::class) @@ -61,28 +42,32 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase $composer = $this->getMockBuilder(\Composer\Composer::class) ->disableOriginalConstructor() - ->setMethods(["getInstallationManager", "translateNamespaceToPath"]) + ->setMethods(["getInstallationManager"]) ->getMock(); $composer->method("getInstallationManager")->willReturn($installationManager); - $composer + + $fakeModulePackage = $this->getMockBuilder(AliasPackage::class) + ->disableOriginalConstructor() + ->setMethods(["getType", "getAutoload"]) + ->getMock(); + $fakeModulePackage->method("getType")->willReturn("lotgd-module"); + $fakeModulePackage->method("getAutoload")->willReturn([ + "psr-4" => [ + "LotGD\\Core\\Tests\\FakeModule\\" => "FakeModule/" + ] + ]); + + $composerManager = $this->getMockBuilder(ComposerManager::class) + ->setMethods(["getPackages", "getComposer", "translateNamespaceToPath"]) + ->getMock(); + $composerManager->method("getPackages")->willReturn([$fakeModulePackage]); + $composerManager->method("getComposer")->willReturn($composer); + $composerManager ->expects($this->exactly(1)) ->method("translateNamespaceToPath") ->with("LotGD\\Core\\Tests\\FakeModule\\Models") ->willReturn(__DIR__ . "/FakeModule/Models"); - $fakeModulePackage = $this->getMockBuilder(AliasPackage::class) - ->disableOriginalConstructor() - ->setMethods(["getType", "getExtra"]) - ->getMock(); - $fakeModulePackage->method("getType")->willReturn("lotgd-module"); - $fakeModulePackage->method("getExtra")->willReturn(["lotgd-namespace" => "LotGD\\Core\\Tests\\FakeModule\\"]); - - $composerManager = $this->getMockBuilder(ComposerManager::class) - ->setMethods(["getPackages", "getComposer"]) - ->getMock(); - $composerManager->method("getPackages")->willReturn([$fakeModulePackage]); - $composerManager->method("getComposer")->willReturn($composer); - $bootstrap = $this->getMockBuilder(Bootstrap::class) ->setMethods(["createComposerManager"]) ->getMock(); @@ -93,42 +78,6 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase $this->assertGreaterThanorEqual(3, $bootstrap->getReadAnnotationDirectories()); - /*$user = new UserEntity(); - $user->setName("Monthy"); - $game->getEntityManager()->persist($user); - $game->getEntityManager()->flush(); - $id = $user->getId(); - $this->assertInternalType("int", $id); - $game->getEntityManager()->clear(); - $user = $game->getEntityManager()->getRepository(UserEntity::class)->find($id); - $this->assertInternalType("int", $user->getId()); - $this->assertInternalType("string", $user->getName()); - $this->assertSame("Monthy", $user->getName());*/ - } - - /*public function testGenerateAnnotationDirectories() - { - $composerManager = $this->getMockBuilder(ComposerManager::class) - ->disableOriginalConstructor() - ->getMock(); - - $package = $this->getMockForAbstractClass(PackageInterface::class); - $package->method('getName')->willReturn('lotgd/BootstrapTest'); - $package->method('getExtra')->willReturn(array( - 'lotgd-namespace' => 'LotGD\\Core\\Tests\\FakeModule\\', - )); - $composerManager->method('getPackages')->willReturn(array($package)); - - $bootstrap = $this->getMockBuilder(Bootstrap::class) - ->setMethods(["createComposerManager"]) - ->getMock(); - - $bootstrap->method("createComposerManager")->willReturn($composerManager); - - $game = $bootstrap->getGame(); - - $this->assertGreaterThanOrEqual(2, $bootstrap->getReadAnnotationDirectories()); - $user = new UserEntity(); $user->setName("Monthy"); $game->getEntityManager()->persist($user); @@ -140,5 +89,5 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase $this->assertInternalType("int", $user->getId()); $this->assertInternalType("string", $user->getName()); $this->assertSame("Monthy", $user->getName()); - }*/ + } } diff --git a/tests/FakeModule/Bootstrap.php b/tests/FakeModule/Bootstrap.php deleted file mode 100644 index 8654905..0000000 --- a/tests/FakeModule/Bootstrap.php +++ /dev/null @@ -1,26 +0,0 @@ -connection === null) { - $configFilePath = getenv('LOTGD_CONFIG'); + $configFilePath = getcwd() . getenv('LOTGD_CONFIG'); if ($configFilePath === false || strlen($configFilePath) == 0 || is_file($configFilePath) === false) { throw new InvalidConfigurationException("Invalid or missing configuration file: '{$configFilePath}'."); }