cloudformation-plus-plus: cfn template preprocessor
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

231 lines
5.2 KiB

<?php
declare(strict_types=1);
namespace App\Engine;
/**
* Main class responsible for controlling the compilation process.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class Engine
{
/**
* Compiler for processing documents.
*
* @var \App\Engine\ICompile
*/
protected $compile;
/**
* Serializer to convert documents back to whatever line/disk format we
* want.
*
* @var \App\Serialize\ISerialize
*/
protected $serialize;
/**
* Unserializer to convert line/disk format documents into documents.
*
* @var \App\Serialize\IUnserialize
*/
protected $unserialize;
/**
* Represents the current document state after any operations called.
*
* @var \App\Dom\Document
*/
protected $document;
/**
* Process a domdocument, applying some higher level operations such as
* stacking documents.
*
* @todo break all this stuff out
* @param string $input_file
* @param IOptions $options
* @return string
*/
public function process(string $input_file, IOptions $options): string
{
$file_helper = new File([dirname(realpath($input_file))]);
$documents = [];
// Figure out which files to process and load all files.
$files = [realpath($input_file)];
for ($i = 0; $i < sizeof($files); $i++)
{
if (!isset($documents[$files[$i]]))
{
$documents[$files[$i]] = $document = $this->unserialize->unserialize(file_get_contents($files[$i]));
$document->setDocumentName($files[$i]);
$includes = [];
try
{
$includes = $document->getMeta('stack');
}
catch (\Exception $ex)
{
}
if (sizeof($includes))
{
$file_helper->clear();
$file_helper->appendPath(dirname($files[$i]));
foreach ($includes as &$include)
{
$include = $file_helper->resolve($include);
}
unset($include);
$document->setMeta('stack', $includes);
array_splice($files, $i, 0, $includes);
--$i;
}
}
}
$documents = array_values($documents);
// Pass it all in and compile
$this->compileDocuments($documents, $options);
$document = $this->getOutputDocument();
// Remove cfnpp block, that doesn't go to CloudFormation
$cfnpp = $document->getChildByName('cfnpp');
if (isset($cfnpp))
{
$cfnpp->remove();
}
// Serialize and return
// TODO: We'll want to return parameters/etc later.
return $this->serialize->serialize($document);
}
/**
* Set the compiler to use.
*
* @param ICompile $compiler
* @return Engine
*/
public function setCompiler(ICompile $compiler): Engine
{
$this->compile = $compiler;
return $this;
}
/**
* Set the serializer to use.
*
* @param \App\Serialize\ISerialize $serializer
* @return Engine
*/
public function setSerializer(\App\Serialize\ISerialize $serializer): Engine
{
$this->serialize = $serializer;
return $this;
}
/**
* Set the unserializer to use.
*
* @param \App\Serialize\IUnserialize $unserializer
* @return Engine
*/
public function setUnserializer(\App\Serialize\IUnserialize $unserializer): Engine
{
$this->unserialize = $unserializer;
return $this;
}
/**
* Set the initial compiler state.
*
* @param \App\Dom\Document $document
* @return Engine
*/
public function setInputDocument(\App\Dom\Document $document): Engine
{
$this->document = $document;
return $this;
}
/**
* Set the initial compiler state from a serialized string.
*
* @param string $document_string
* @return Engine
*/
public function setInput(string $document_string): Engine
{
$document = $this->unserialize->unserialize($document_string);
$this->setInputDocument($document);
return $this;
}
/**
* Compile a new document, mutating current state.
*
* @param string $document_string
* @param IOptions $options
* @return Engine
*/
public function compile(string $document_string, IOptions $options): Engine
{
$document = $this->unserialize->unserialize($document_string);
$this->compileDocument($document, $options);
return $this;
}
/**
* Compile a new document, mutating current state.
*
* @param \App\Dom\Document $document
* @param IOptions $options
* @return Engine
*/
public function compileDocument(\App\Dom\Document $document, IOptions $options): Engine
{
$this->document = $this->compile->compile(isset($this->document) ? [$this->document, $document] : [$document], $options);
return $this;
}
/**
* Compile a set of documents, mutating current state.
*
* @param \App\Dom\Document[] $documents
* @param IOptions $options
* @return Engine
*/
public function compileDocuments(array $documents, IOptions $options): Engine
{
$this->document = $this->compile->compile(isset($this->document) ? array_merge([$this->document], $documents) : $documents, $options);
return $this;
}
/**
* Get the document state after all applied compile() calls.
*
* @return \App\Dom\Document
*/
public function getOutputDocument(): \App\Dom\Document
{
return $this->document;
}
/**
* Get the document state after all applied compile() calls and serialize
* it, returning line/disk format.
*
* @return string
*/
public function getOutput(): string
{
$document = $this->getOutputDocument();
return $this->serialize->serialize($document);
}
}