diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c244c3b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +version: ~> 1.0 + +import: + - silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range.yml diff --git a/README.md b/README.md index 6d19569..cf0c5bd 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ This module adds an implementation of [graphiql](https://github.com/graphql/grap This is because GraphQL 4 has its own `DevelopmentAdmin` controller. +The GraphQL v4 version of the module allows you to clear your schema by calling the `/dev/graphql/clear` task. + ## Security By default, the tool has the same restrictions as other development tools like `dev/build`: @@ -101,4 +103,3 @@ SilverStripe\Control\Director: CDN to download the latest distribution and drop it into this repository. Be sure to update the comment at the top of the `bundle.js` file to track the URL it was downloaded from. - diff --git a/_config/config.yml b/_config/config.yml index 6d678e5..0a99422 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -21,6 +21,10 @@ SilverStripe\GraphQL\Dev\DevelopmentAdmin: controller: 'SilverStripe\GraphQLDevTools\Controller' links: ide: Run the GraphQL IDE + clear: + controller: SilverStripe\GraphQLDevTools\Clear + links: + clear: Clear the GraphQL schema --- Name: graphql3-devtool-routes diff --git a/composer.json b/composer.json index a85a7fa..ca9b7cb 100644 --- a/composer.json +++ b/composer.json @@ -2,18 +2,23 @@ "name": "silverstripe/graphql-devtools", "description": "Tools to help developers building new applications on SilverStripe’s GraphQL API", "type": "silverstripe-vendormodule", + "license": "BSD-3-Clause", "require": { - "silverstripe/graphql": "*" + "silverstripe/graphql": "^3 || ^4", + "symfony/finder": "^4 || ^5", + "symfony/filesystem": "^4 || ^5" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.0" }, "autoload": { "psr-4": { - "SilverStripe\\GraphQLDevTools\\": "src/" + "SilverStripe\\GraphQLDevTools\\": "src/", + "SilverStripe\\GraphQLDevTools\\Tests\\": "tests/" } }, "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - }, "expose": [ "client/" ] diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..953aa54 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,28 @@ + + + CodeSniffer ruleset for SilverStripe coding conventions. + + src + tests + + */\.graphql-generated/* + + + + + + + + + + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..0281bef --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + tests + + + + + + src/ + + tests/ + + + + + diff --git a/src/Clear.php b/src/Clear.php new file mode 100644 index 0000000..8562117 --- /dev/null +++ b/src/Clear.php @@ -0,0 +1,49 @@ + 'clear', + ]; + + private static $allowed_actions = [ + 'clear', + ]; + + public function clear(HTTPRequest $request): void + { + $logger = Injector::inst()->get(LoggerInterface::class . '.graphql-build'); + $dirName = CodeGenerationStore::config()->get('dirName'); + $expectedPath = BASE_PATH . DIRECTORY_SEPARATOR . $dirName; + $fs = new Filesystem(); + + $finder = new Finder(); + // Make finder not recursive + $finder->depth('== 0'); + + $logger->info('Clearing GraphQL code generation directory'); + if ($fs->exists($expectedPath)) { + $logger->info('Directory has been found'); + if ($finder->in($expectedPath)->hasResults()) { + foreach ($finder as $file) { + $logger->info('Removing ' . $file->getFilename()); + $fs->remove($file->getRealPath()); + } + $logger->info('Directory now empty'); + } else { + $logger->info('Directory is already empty.'); + } + } else { + $logger->info('Directory was not found. There is nothing to clear'); + } + } +} diff --git a/src/Controller.php b/src/Controller.php index da74eb8..5047321 100644 --- a/src/Controller.php +++ b/src/Controller.php @@ -117,7 +117,6 @@ protected function findAvailableRoutes($schemas = []): array } } catch (InjectorNotFoundException $ex) { } - } return $routes; } diff --git a/tests/ClearTest.php b/tests/ClearTest.php new file mode 100644 index 0000000..54c2b39 --- /dev/null +++ b/tests/ClearTest.php @@ -0,0 +1,68 @@ +markTestSkipped('GraphQL 4 test ' . __CLASS__ . ' skipped'); + return; + } + + $this->originalDirName = CodeGenerationStore::config()->get('dirName'); + Logger::singleton()->setVerbosity(Logger::EMERGENCY); + CodeGenerationStore::config()->set('dirName', $this->dirName); + + $fs = new Filesystem(); + $fs->mkdir($this->absDirName); + } + + protected function tearDown(): void + { + parent::tearDown(); + CodeGenerationStore::config()->set('dirName', $this->originalDirName); + $fs = new Filesystem(); + if ($fs->exists($this->absDirName)) { + $fs->remove($this->absDirName); + } + } + + public function testClear() + { + $fs = new Filesystem(); + $finder = new Finder(); + $finder->in($this->absDirName); + + $this->assertTrue($fs->exists($this->absDirName), 'Test should begin with a fake code gen folder'); + + $this->get('dev/graphql/clear'); + $this->assertFalse($finder->hasResults(), 'GraphQL clear should not break on an empty folder'); + + $fs->mkdir($this->absDirName . DIRECTORY_SEPARATOR . 'default'); + $this->assertTrue($finder->hasResults(), 'A fake schema folder should have been created'); + + $this->get('dev/graphql/clear'); + $this->assertFalse($finder->hasResults(), 'GraphQL clear should have removed the fake schema folder'); + + $fs->remove($this->absDirName); + $this->get('dev/graphql/clear'); + $this->assertFalse($fs->exists($this->absDirName), 'GraphQL clear should not break on a non-existent folder'); + } +}