diff --git a/src/Entities/Project.php b/src/Entities/Project.php index ef89345..3b432f4 100644 --- a/src/Entities/Project.php +++ b/src/Entities/Project.php @@ -5,6 +5,8 @@ use Tapestry\ArrayContainer; use Tapestry\Exceptions\GraphException; use Tapestry\Entities\DependencyGraph\Graph; +use Tapestry\Modules\Generators\ContentGeneratorFactory; +use Tapestry\Modules\Generators\GeneratorInterface; use Tapestry\Modules\Source\SourceInterface; use Tapestry\Entities\Generators\FileGenerator; use Tapestry\Entities\Collections\FlatCollection; @@ -102,11 +104,13 @@ public function replaceFile(SourceInterface $oldFile, SourceInterface $newFile) * @param string $name * @param SourceInterface $file * - * @return ProjectFileGeneratorInterface + * @return GeneratorInterface */ - public function getContentGenerator($name, SourceInterface $file) + public function getContentGenerator(string $name, SourceInterface $file): GeneratorInterface { - return $this->get('content_generators')->get($name, $file); + /** @var ContentGeneratorFactory $factory */ + $factory = $this->get('content_generators'); + return $factory->get($name, $file); } /** diff --git a/src/Entities/ProjectFileGeneratorInterface.php b/src/Entities/ProjectFileGeneratorInterface.php index f8a7d69..903a71d 100644 --- a/src/Entities/ProjectFileGeneratorInterface.php +++ b/src/Entities/ProjectFileGeneratorInterface.php @@ -2,6 +2,10 @@ namespace Tapestry\Entities; +/** + * Interface ProjectFileGeneratorInterface + * @deprecated + */ interface ProjectFileGeneratorInterface { public function generate(Project $project); diff --git a/src/Modules/Generators/ContentGeneratorFactory.php b/src/Modules/Generators/ContentGeneratorFactory.php index 309fd8c..5c8c437 100644 --- a/src/Modules/Generators/ContentGeneratorFactory.php +++ b/src/Modules/Generators/ContentGeneratorFactory.php @@ -3,7 +3,7 @@ namespace Tapestry\Modules\Generators; use Tapestry\Entities\Project; -use Tapestry\Modules\Source\AbstractSource; +use Tapestry\Modules\Source\SourceInterface; /** * Class ContentGeneratorFactory @@ -60,13 +60,17 @@ public function add(string $class) * with the AbstractSource. * * @param string $name - * @param AbstractSource $file + * @param SourceInterface $source * @return GeneratorInterface */ - public function get(string $name, AbstractSource $file): GeneratorInterface + public function get(string $name, SourceInterface $source): GeneratorInterface { + /** @var GeneratorInterface $class */ + $class = new $this->items[$name]; + $class->setSource($source); + // @todo register new FileGenerator with the graph for #315 - return new $this->items[$name]($file); + return $class; } /** diff --git a/src/Modules/Generators/Generator.php b/src/Modules/Generators/Generator.php new file mode 100644 index 0000000..ff0f042 --- /dev/null +++ b/src/Modules/Generators/Generator.php @@ -0,0 +1,91 @@ +source->getData('generator')) { + return [$this->source]; + } + + // To begin with, kick off the generation with the first generator. Then follow up with a loop that continues + // until all generators have been ran. + + $first = reset($generators); + $this->mergeGenerated($project->getContentGenerator($first, $this->source)->generate($project)); + + // @todo there is scope for improvement with this loop, by removing items from $generated when they cant generate any more and placing them in a $result array for this method to return + while ($this->canGenerate()) { + foreach ($this->generated as $file) { + if (! $generators = $file->getData('generator')) { + continue; + } + $first = reset($generators); + $this->mergeGenerated($project->getContentGenerator($first, $file)->generate($project)); + } + } + + return $this->generated; + } + + /** + * Identify whether we can continue generating. + * + * @return bool + */ + private function canGenerate() : bool + { + foreach ($this->generated as $file) { + if ($uses = $file->getData('generator')) { + if (count($uses) > 0) { + return true; + } + } + } + + return false; + } + + /** + * Merge the generated files into our local generatedFiles list. + * + * @param AbstractSource|AbstractSource[] $generated + * @return void + */ + private function mergeGenerated($generated) + { + if (! is_array($generated)) { + $this->generated[$generated->getUid()] = $generated; + } else { + foreach ($generated as $file) { + $this->mergeGenerated($file); + } + } + } +} \ No newline at end of file diff --git a/tests/Unit/ContentGeneratorFactoryNTest.php b/tests/Unit/ContentGeneratorFactoryNTest.php index 5c6ee49..e7192e6 100644 --- a/tests/Unit/ContentGeneratorFactoryNTest.php +++ b/tests/Unit/ContentGeneratorFactoryNTest.php @@ -6,6 +6,7 @@ use Tapestry\Entities\DependencyGraph\SimpleNode; use Tapestry\Entities\Project; use Tapestry\Modules\Generators\ContentGeneratorFactory; +use Tapestry\Modules\Generators\Generator; use Tapestry\Modules\Source\MemorySource; use Tapestry\Tapestry; use Tapestry\Tests\TestCase; @@ -20,9 +21,15 @@ public function testContentGeneratorFactory() $this->assertFalse($factory->has('hello-world')); - $factory->add(\Tapestry\Entities\Generators\CollectionItemGenerator::class); - $this->assertTrue($factory->has('CollectionItemGenerator')); + $factory->add(Generator::class); + $this->assertTrue($factory->has('Generator')); + + $memory = new MemorySource('hello-world', '', 'index', 'phtml','/', '/index.phtml', []); + + $result = ($factory->get('Generator', $memory))->generate($project); + $this->assertTrue(is_array($result)); + $this->assertSame($memory, $result[0]); + - $memory = new MemorySource('hello-world', '', 'index', 'phtml','/'); } }