Compare commits

...

21 commits

Author SHA1 Message Date
eb5ee10f70 Set PHP 7.2 2020-02-10 09:15:38 +00:00
51bb9927ff Remove composer.lock 2020-02-10 08:48:02 +00:00
8d5effa151 Add .travis.yml 2020-02-10 08:36:45 +00:00
82ba102094 Add friendsofphp/php-cs-fixer 2020-02-10 08:36:25 +00:00
c5dc5a6b88 Add demo link 2020-02-10 07:28:51 +00:00
7f10ecb7d3 Add D7 usage instructions 2020-02-10 07:27:29 +00:00
df583e31d8 Add installation instructions 2020-02-10 07:27:11 +00:00
88147ec4e5 Add D7 aliases 2020-02-09 21:49:52 +00:00
a186fcf721 Update command name 2020-02-09 21:49:52 +00:00
bee4a6b5d8 Update output 2020-02-09 21:49:52 +00:00
41c23185c4 Remove unused import and variable 2020-02-09 21:41:24 +00:00
66e358b802 Add application name 2020-02-09 21:40:17 +00:00
0d6bd4e070 Populate more of the test stub 2020-02-09 21:38:57 +00:00
ea2f5a4ae8 Change the description string 2020-02-09 21:38:57 +00:00
c983048346 Mark classes as final 2020-02-09 21:29:35 +00:00
738031ec5d Search for autoload.php in different locations 2020-02-09 21:29:35 +00:00
edf8b9a368 Be explicit about fixtures path 2020-02-09 21:27:08 +00:00
4ac7fee102 Support multiple versions of Symfony packages 2020-02-09 21:26:37 +00:00
65877402ba Declare the dmg binary 2020-02-09 21:26:27 +00:00
13faa12bfe Update properties 2020-02-09 20:54:52 +00:00
28696ce13f Add a readable module name 2020-02-09 19:16:57 +00:00
14 changed files with 165 additions and 2249 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/vendor/
/composer.lock

14
.php_cs.dist Normal file
View file

@ -0,0 +1,14 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->exclude(['fixtures']);
return PhpCsFixer\Config::create()
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'ordered_imports' => true,
'phpdoc_order' => true,
])
->setFinder($finder);

17
.travis.yml Normal file
View file

@ -0,0 +1,17 @@
language: php
php:
- 7.2
- 7.3
- 7.4
env:
matrix:
- COMPOSER_FLAGS="--prefer-lowest"
- COMPOSER_FLAGS=""
before_script:
- composer install --dev --prefer-source --no-interaction
script:
- vendor/bin/phpunit

View file

@ -1,7 +1,28 @@
# Drupal Module Generator (dmg)
A scaffolding tool for generating new modules for Drupal 7 and 8.
A scaffolding tool for generating new modules for Drupal 7 and (soon) 8.
[Watch a short demo][demo].
[demo]: https://opdavi.es/6i3YZ 'A short demo video on YouTube'
## Installation
The Drupal Module Generator is installed via [Composer][]:
```bash
composer global require opdavies/drupal-module-generator
```
[composer]: https://getcomposer.org
## Usage
TODO
### Drupal 7
```bash
dmg generate:drupal-7-module {name}
```
Generated Drupal 7 modules contain the appropriately named `.info` and `.module` files,
as well as a test case located in `src/Tests/Functional` which [is loaded automatically](https://www.oliverdavies.uk/articles/psr4-autoloading-test-cases-drupal-7).

12
bin/dmg Normal file → Executable file
View file

@ -2,19 +2,25 @@
<?php
use Opdavies\DrupalModuleGenerator\Command\GenerateDrupal7Command;
use Opdavies\DrupalModuleGenerator\Service\ModuleNameConverter;
use Opdavies\DrupalModuleGenerator\Service\TestNameConverter;
use Symfony\Component\Console\Application;
use Symfony\Component\Finder\Finder;
require_once __DIR__.'/../vendor/autoload.php';
if (file_exists(__DIR__.'/../../../autoload.php')) {
require __DIR__.'/../../../autoload.php';
} else {
require __DIR__.'/../vendor/autoload.php';
}
$app = new Application();
$app = new Application('Drupal Module Generator');
$finder = new Finder();
$moduleNameConverter = new ModuleNameConverter();
$testNameConverter = new TestNameConverter();
$app->addCommands([
new GenerateDrupal7Command($finder, $testNameConverter),
new GenerateDrupal7Command($finder, $moduleNameConverter, $testNameConverter),
]);
$app->run();

View file

@ -3,16 +3,17 @@
"description": "Generates boilerplate code for Drupal modules.",
"type": "project",
"require": {
"symfony/console": "^5.0",
"symfony/dependency-injection": "^5.0",
"symfony/filesystem": "^5.0",
"symfony/finder": "^5.0",
"php": "^7.2",
"symfony/console": "^4.0 || ^5.0",
"symfony/dependency-injection": "^4.0 || ^5.0",
"symfony/filesystem": "^4.0 || ^5.0",
"symfony/finder": "^4.0 || ^5.0",
"tightenco/collect": "^6.14"
},
"require-dev": {
"php": "5.6 || ^7.0",
"phpunit/phpunit": "^9.0",
"symfony/var-dumper": "^5.0"
"friendsofphp/php-cs-fixer": "^2.16",
"phpunit/phpunit": "^8.5",
"symfony/var-dumper": "^4.0 || ^5.0"
},
"license": "MIT",
"authors": [
@ -31,7 +32,13 @@
"Opdavies\\Tests\\DrupalModuleGenerator\\": "tests/"
}
},
"bin": [
"bin/dmg"
],
"config": {
"platform": {
"php": "7.2.5"
},
"sort-packages": true
}
}

2200
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,3 @@
name = {{ name }}
description = The description for {{ name }}.
description = {{ name }} module.
core = 7.x

View file

@ -1,5 +1,21 @@
<?php
namespace Drupal\{{ name }}\Tests\Functional;
namespace Drupal\{{ machine_name }}\Tests\Functional;
final class {{ test_name }} extends \DrupalWebTestCase {}
final class {{ test_name }} extends \DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => '{{ name }}',
'description' => '{{ name }} tests.',
'group' => '{{ name }}',
);
}
public function test_that_the_front_page_loads() {
$this->drupalGet('<front>');
$this->assertResponse(200);
}
}

View file

@ -3,49 +3,45 @@
namespace Opdavies\DrupalModuleGenerator\Command;
use Opdavies\DrupalModuleGenerator\Exception\CannotCreateModuleException;
use Opdavies\DrupalModuleGenerator\Service\ModuleNameConverter;
use Opdavies\DrupalModuleGenerator\Service\TestNameConverter;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Tightenco\Collect\Support\Collection;
class GenerateDrupal7Command extends Command
final class GenerateDrupal7Command extends Command
{
private $moduleName;
private $machineName;
private $testName;
/** @var Filesystem */
private $filesystem;
/** @var Finder */
private $finder;
/** @var SymfonyStyle $io */
private $io;
/** @var TestNameConverter */
private $moduleNameConverter;
private $testNameConverter;
public function __construct(
Finder $finder,
ModuleNameConverter $moduleNameConverter,
TestNameConverter $testNameConverter,
string $name = null
) {
parent::__construct($name);
$this->finder = $finder;
$this->moduleNameConverter = $moduleNameConverter;
$this->testNameConverter = $testNameConverter;
}
/**
* {@inheritdoc}
*/
protected static $defaultName = 'generate-drupal-7-module';
protected static $defaultName = 'generate:drupal-7-module';
/**
* {@inheritDoc}
@ -53,8 +49,10 @@ class GenerateDrupal7Command extends Command
protected function configure()
{
$this
->setDescription('Generate a new Drupal 7 module.')
->addArgument('module-name', InputArgument::REQUIRED, 'The name of the module to create');
->setDescription('Generate a new Drupal 7 module')
->addArgument('module-name', InputArgument::REQUIRED, 'The name of the module to create')
->setAliases(['d7', 'drupal7'])
;
}
/**
@ -64,8 +62,11 @@ class GenerateDrupal7Command extends Command
{
$this->io = new SymfonyStyle($input, $output);
$this->moduleName = $input->getArgument('module-name');
$this->testName = $this->testNameConverter->__invoke($this->moduleName);
$this->io->title("Drupal Module Generator (D7)");
$this->machineName = $input->getArgument('module-name');
$this->moduleName = $this->moduleNameConverter->__invoke($this->machineName);
$this->testName = $this->testNameConverter->__invoke($this->machineName);
$this
->ensureDirectoryDoesNotExist()
@ -80,7 +81,7 @@ class GenerateDrupal7Command extends Command
*/
private function ensureDirectoryDoesNotExist()
{
if (is_dir($this->moduleName)) {
if (is_dir($this->machineName)) {
throw CannotCreateModuleException::directoryAlreadyExists();
}
@ -89,7 +90,7 @@ class GenerateDrupal7Command extends Command
private function createModuleDirectory()
{
mkdir($this->moduleName);
mkdir($this->machineName);
return $this;
}
@ -97,14 +98,13 @@ class GenerateDrupal7Command extends Command
private function createFiles()
{
$createdFiles = new Collection();
$testNameConverter = new TestNameConverter();
/** @var SplFileInfo $file */
foreach ($this->finder->in('fixtures/drupal7_module')->files() as $file) {
$filename = "{$this->moduleName}.{$file->getExtension()}";
foreach ($this->finder->in(__DIR__.'/../../fixtures/drupal7_module')->files() as $file) {
$filename = "{$this->machineName}.{$file->getExtension()}";
if ($file->getRelativePath()) {
mkdir("{$this->moduleName}/{$file->getRelativePath()}", 0777, $recursive = true);
mkdir("{$this->machineName}/{$file->getRelativePath()}", 0777, $recursive = true);
$filename = "{$this->testName}.php";
$filename = "{$file->getRelativePath()}/{$filename}";
@ -112,16 +112,21 @@ class GenerateDrupal7Command extends Command
$contents = $this->updateFileContents($file->getContents());
file_put_contents("{$this->moduleName}/{$filename}", $contents);
file_put_contents("{$this->machineName}/{$filename}", $contents);
$createdFiles->push($filename);
}
$this->io->listing($createdFiles->filter()->sort()->toArray());
if ($createdFiles->isNotEmpty()) {
$this->io->block('Files generated:');
$this->io->listing($createdFiles->sort()->toArray());
}
}
private function updateFileContents($contents)
{
$contents = str_replace('{{ machine_name }}', $this->machineName, $contents);
$contents = str_replace('{{ name }}', $this->moduleName, $contents);
$contents = str_replace('{{ test_name }}', $this->testName, $contents);

View file

@ -2,7 +2,7 @@
namespace Opdavies\DrupalModuleGenerator\Exception;
class CannotCreateModuleException extends \RuntimeException
final class CannotCreateModuleException extends \RuntimeException
{
public static function directoryAlreadyExists()
{

View file

@ -0,0 +1,17 @@
<?php
namespace Opdavies\DrupalModuleGenerator\Service;
final class ModuleNameConverter
{
public function __invoke(string $moduleName)
{
$parts = explode('_', $moduleName);
$parts = array_map(function ($part) {
return ucfirst($part);
}, $parts);
return implode(' ', $parts);
}
}

View file

@ -2,7 +2,7 @@
namespace Opdavies\DrupalModuleGenerator\Service;
class TestNameConverter
final class TestNameConverter
{
public function __invoke(string $moduleName)
{

View file

@ -4,13 +4,14 @@ namespace Opdavies\Tests\DrupalModuleGenerator\Command;
use Opdavies\DrupalModuleGenerator\Command\GenerateDrupal7Command;
use Opdavies\DrupalModuleGenerator\Exception\CannotCreateModuleException;
use Opdavies\DrupalModuleGenerator\Service\ModuleNameConverter;
use Opdavies\DrupalModuleGenerator\Service\TestNameConverter;
use Symfony\Component\Console\Tester\CommandTester;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
class GenerateDrupal7ModuleCommandTest extends TestCase
final class GenerateDrupal7ModuleCommandTest extends TestCase
{
protected function tearDown(): void
{
@ -24,8 +25,9 @@ class GenerateDrupal7ModuleCommandTest extends TestCase
$this->expectExceptionObject(CannotCreateModuleException::directoryAlreadyExists());
$finder = new Finder();
$moduleNameConverter = new ModuleNameConverter();
$testNameConverter = new TestNameConverter();
$command = new GenerateDrupal7Command($finder, $testNameConverter);
$command = new GenerateDrupal7Command($finder, $moduleNameConverter, $testNameConverter);
$commandTester = new CommandTester($command);
$commandTester->execute([
@ -37,8 +39,9 @@ class GenerateDrupal7ModuleCommandTest extends TestCase
public function it_creates_a_new_module_directory()
{
$finder = new Finder();
$moduleNameConverter = new ModuleNameConverter();
$testNameConverter = new TestNameConverter();
$command = new GenerateDrupal7Command($finder, $testNameConverter);
$command = new GenerateDrupal7Command($finder, $moduleNameConverter, $testNameConverter);
$commandTester = new CommandTester($command);
$commandTester->execute([
@ -52,8 +55,9 @@ class GenerateDrupal7ModuleCommandTest extends TestCase
public function it_generates_an_info_file()
{
$finder = new Finder();
$moduleNameConverter = new ModuleNameConverter();
$testNameConverter = new TestNameConverter();
$command = new GenerateDrupal7Command($finder, $testNameConverter);
$command = new GenerateDrupal7Command($finder, $moduleNameConverter, $testNameConverter);
$commandTester = new CommandTester($command);
$commandTester->execute([
@ -64,16 +68,17 @@ class GenerateDrupal7ModuleCommandTest extends TestCase
$contents = file_get_contents('test_module/test_module.info');
$this->assertStringContainsString('name = test_module', $contents);
$this->assertStringContainsString('description = The description for test_module.', $contents);
$this->assertStringContainsString('name = Test Module', $contents);
$this->assertStringContainsString('description = Test Module module.', $contents);
}
/** @test */
public function it_generates_a_module_file()
{
$finder = new Finder();
$moduleNameConverter = new ModuleNameConverter();
$testNameConverter = new TestNameConverter();
$command = new GenerateDrupal7Command($finder, $testNameConverter);
$command = new GenerateDrupal7Command($finder, $moduleNameConverter, $testNameConverter);
$commandTester = new CommandTester($command);
$commandTester->execute([
@ -84,15 +89,16 @@ class GenerateDrupal7ModuleCommandTest extends TestCase
$contents = file_get_contents('test_module/test_module.module');
$this->assertStringContainsString('The main module file for test_module.', $contents);
$this->assertStringContainsString('The main module file for Test Module.', $contents);
}
/** @test */
public function it_generates_a_test_case()
{
$finder = new Finder();
$moduleNameConverter = new ModuleNameConverter();
$testNameConverter = new TestNameConverter();
$command = new GenerateDrupal7Command($finder, $testNameConverter);
$command = new GenerateDrupal7Command($finder, $moduleNameConverter, $testNameConverter);
$commandTester = new CommandTester($command);
$commandTester->execute([
@ -103,6 +109,12 @@ class GenerateDrupal7ModuleCommandTest extends TestCase
$contents = file_get_contents('test_module/src/Tests/Functional/TestModuleTest.php');
$this->assertStringContainsString('namespace Drupal\\test_module\\Tests\\Functional', $contents);
$this->assertStringContainsString('final class TestModuleTest', $contents);
$this->assertStringContainsString("'name' => 'Test Module'", $contents);
$this->assertStringContainsString("'description' => 'Test Module tests.'", $contents);
$this->assertStringContainsString("'group' => 'Test Module'", $contents);
}
}