Skip to content

Commit

Permalink
Added base Generator for #315
Browse files Browse the repository at this point in the history
  • Loading branch information
carbontwelve committed Aug 15, 2018
1 parent b350812 commit 3485589
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 10 deletions.
10 changes: 7 additions & 3 deletions src/Entities/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions src/Entities/ProjectFileGeneratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace Tapestry\Entities;

/**
* Interface ProjectFileGeneratorInterface
* @deprecated
*/
interface ProjectFileGeneratorInterface
{
public function generate(Project $project);
Expand Down
12 changes: 8 additions & 4 deletions src/Modules/Generators/ContentGeneratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Tapestry\Modules\Generators;

use Tapestry\Entities\Project;
use Tapestry\Modules\Source\AbstractSource;
use Tapestry\Modules\Source\SourceInterface;

/**
* Class ContentGeneratorFactory
Expand Down Expand Up @@ -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;
}

/**
Expand Down
91 changes: 91 additions & 0 deletions src/Modules/Generators/Generator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace Tapestry\Modules\Generators;

use Tapestry\Entities\Project;
use Tapestry\Modules\Source\AbstractSource;
use Tapestry\Modules\Source\SourceInterface;

/**
* Class Generator
*
* This is the base generator, if a source file is found to define generators in its
* front matter its the job of this class to go over those generators and execute
* them in the order in which they are defined.
*/
class Generator extends AbstractGenerator implements GeneratorInterface
{
/**
* @var array|SourceInterface[]
*/
private $generated = [];

/**
* Run the generation and return an array of generated
* files (oddly implementing SourceInterface, naming
* things is hard!)
*
* @param Project $project
* @return array|SourceInterface[]
*/
public function generate(Project $project): array
{
if (!$generators = $this->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);
}
}
}
}
13 changes: 10 additions & 3 deletions tests/Unit/ContentGeneratorFactoryNTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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','/');
}
}

0 comments on commit 3485589

Please # to comment.