Skip to content

Commit 7cc8072

Browse files
committed
Detect PSR-4 prefixes
1 parent 04e337f commit 7cc8072

File tree

5 files changed

+72
-8
lines changed

5 files changed

+72
-8
lines changed

src/Command/GenerateTypesCommand.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,32 @@ final class GenerateTypesCommand extends Command
3535
{
3636
private const DEFAULT_CONFIG_FILE = 'schema.yaml';
3737

38+
private $namespacePrefix;
39+
private $defaultOutput;
40+
3841
/**
3942
* {@inheritdoc}
4043
*/
4144
protected function configure(): void
4245
{
46+
if (file_exists('composer.json') && is_file('composer.json') && is_readable('composer.json')) {
47+
$composer = json_decode(file_get_contents('composer.json'), true);
48+
foreach ($composer['autoload']['psr-4'] ?? [] as $prefix => $output) {
49+
if ('' === $prefix) {
50+
continue;
51+
}
52+
53+
$this->namespacePrefix = $prefix;
54+
$this->defaultOutput = $output;
55+
56+
break;
57+
}
58+
}
59+
4360
$this
4461
->setName('generate-types')
4562
->setDescription('Generate types')
46-
->addArgument('output', InputArgument::REQUIRED, 'The output directory')
63+
->addArgument('output', $this->defaultOutput ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The output directory', $this->defaultOutput)
4764
->addArgument('config', InputArgument::OPTIONAL, 'The config file to use (default to "schema.yaml" in the current directory, will generate all types if no config file exists)');
4865
}
4966

@@ -52,10 +69,18 @@ protected function configure(): void
5269
*/
5370
protected function execute(InputInterface $input, OutputInterface $output): void
5471
{
72+
$defaultOutput = $this->defaultOutput ? realpath($this->defaultOutput) : null;
5573
$outputDir = $input->getArgument('output');
74+
$configArgument = $input->getArgument('config');
75+
5676
if ($dir = realpath($input->getArgument('output'))) {
5777
if (!is_dir($dir)) {
58-
throw new \InvalidArgumentException(sprintf('The file "%s" is not a directory.', $dir));
78+
if (!$this->defaultOutput) {
79+
throw new \InvalidArgumentException(sprintf('The file "%s" is not a directory.', $dir));
80+
}
81+
82+
$dir = $defaultOutput;
83+
$configArgument = $outputDir;
5984
}
6085

6186
if (!is_writable($dir)) {
@@ -69,7 +94,6 @@ protected function execute(InputInterface $input, OutputInterface $output): void
6994
$outputDir = realpath($outputDir);
7095
}
7196

72-
$configArgument = $input->getArgument('config');
7397
if ($configArgument) {
7498
if (!file_exists($configArgument)) {
7599
throw new \InvalidArgumentException(sprintf('The file "%s" doesn\'t exist.', $configArgument));
@@ -95,7 +119,7 @@ protected function execute(InputInterface $input, OutputInterface $output): void
95119
}
96120

97121
$processor = new Processor();
98-
$configuration = new TypesGeneratorConfiguration();
122+
$configuration = new TypesGeneratorConfiguration($dir === $defaultOutput ? $this->namespacePrefix : null);
99123
$processedConfiguration = $processor->processConfiguration($configuration, [$config]);
100124
$processedConfiguration['output'] = $outputDir;
101125
if (!$processedConfiguration['output']) {

src/TypesGeneratorConfiguration.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,20 @@ final class TypesGeneratorConfiguration implements ConfigurationInterface
3939
public const GOOD_RELATIONS_OWL_URL = __DIR__.'/../data/v1.owl';
4040
public const SCHEMA_ORG_NAMESPACE = 'http://schema.org/';
4141

42+
private $defaultPrefix;
43+
44+
public function __construct(?string $defaultPrefix = null)
45+
{
46+
$this->defaultPrefix = $defaultPrefix;
47+
}
48+
4249
/**
4350
* {@inheritdoc}
4451
*/
4552
public function getConfigTreeBuilder(): TreeBuilder
4653
{
54+
$namespacePrefix = $this->defaultPrefix ?? 'AppBundle\\';
55+
4756
$treeBuilder = new TreeBuilder();
4857
$rootNode = $treeBuilder->root('config');
4958
$rootNode
@@ -92,10 +101,10 @@ function ($rdfa) {
92101
->addDefaultsIfNotSet()
93102
->info('PHP namespaces')
94103
->children()
95-
->scalarNode('prefix')->defaultNull()->info('The global namespace\'s prefix')->example('App\\')->end()
96-
->scalarNode('entity')->defaultValue('AppBundle\Entity')->info('The namespace of the generated entities')->example('App\Entity')->end()
97-
->scalarNode('enum')->defaultValue('AppBundle\Enum')->info('The namespace of the generated enumerations')->example('App\Enum')->end()
98-
->scalarNode('interface')->defaultValue('AppBundle\Model')->info('The namespace of the generated interfaces')->example('App\Model')->end()
104+
->scalarNode('prefix')->defaultValue($this->defaultPrefix)->info('The global namespace\'s prefix')->example('App\\')->end()
105+
->scalarNode('entity')->defaultValue("{$namespacePrefix}Entity")->info('The namespace of the generated entities')->example('App\Entity')->end()
106+
->scalarNode('enum')->defaultValue("{$namespacePrefix}Enum")->info('The namespace of the generated enumerations')->example('App\Enum')->end()
107+
->scalarNode('interface')->defaultValue("{$namespacePrefix}Model")->info('The namespace of the generated interfaces')->example('App\Model')->end()
99108
->end()
100109
->end()
101110
->arrayNode('doctrine')

tests/Command/GenerateTypesCommandTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,4 +323,26 @@ public function testNamespacesPrefix()
323323

324324
$this->assertContains('namespace App\Entity;', $person);
325325
}
326+
327+
public function testNamespacesPrefixAutodetect()
328+
{
329+
$outputDir = __DIR__.'/../../build/namespaces-prefix-autodetect/';
330+
331+
$this->fs->mkdir($outputDir);
332+
$this->fs->copy(__DIR__.'/../config/namespaces-prefix-autodetect/composer.json', "$outputDir/composer.json");
333+
$this->fs->copy(__DIR__.'/../config/namespaces-prefix-autodetect/schema.yaml', "$outputDir/schema.yaml");
334+
335+
$currentDir = getcwd();
336+
chdir($outputDir);
337+
try {
338+
$commandTester = new CommandTester(new GenerateTypesCommand());
339+
$this->assertEquals(0, $commandTester->execute([]));
340+
341+
$person = file_get_contents("$outputDir/src/Entity/Person.php");
342+
343+
$this->assertContains('namespace App\Entity;', $person);
344+
} finally {
345+
chdir($currentDir);
346+
}
347+
}
326348
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"autoload": {
3+
"psr-4": { "App\\": "src/" }
4+
}
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
types:
2+
Person:
3+
properties:
4+
name: ~

0 commit comments

Comments
 (0)