Skip to content
This repository has been archived by the owner on Sep 12, 2022. It is now read-only.

Commit

Permalink
#45 [WIP] Add current state
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian Kleinhans committed Nov 23, 2016
1 parent e450c27 commit 47ed3f2
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,33 @@
abstract class AbstractTreePreProcessorStage
{
protected $treePreProcessor; // reference to parent
protected $template;

/**
* @param \StackFormation\PreProcessor\TreePreProcessor $treePreProcessor
* @param Template $template
*/
public function __construct(\StackFormation\PreProcessor\TreePreProcessor $treePreProcessor) {
public function __construct(\StackFormation\PreProcessor\TreePreProcessor $treePreProcessor, Template $template) {
$this->treePreProcessor = $treePreProcessor;
$this->template = $template;
}

/**
* @param Template $template
* @return Template $template
* @throws \StackFormation\Exception\TreePreProcessorException
*/
public function __invoke(Template $template)
public function __invoke()
{
try {
return $this->invoke($template);
$tree = $this->template->getTree();
$this->invoke($tree);
$this->template->setTree($tree);
} catch (\Exception $e) {
throw new \StackFormation\Exception\TreePreProcessorException($template, $e);
throw new \StackFormation\Exception\TreePreProcessorException($this->template, $e);
}
}

/**
* @param Template $template
* @param $tree
*/
abstract function invoke(Template $template);
abstract function invoke(array &$tree);
}
14 changes: 4 additions & 10 deletions src/StackFormation/PreProcessor/Stage/Tree/ExpandPort.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,18 @@
namespace StackFormation\PreProcessor\Stage\Tree;

use StackFormation\PreProcessor\Stage\AbstractTreePreProcessorStage;
use StackFormation\Template;

class ExpandPort extends AbstractTreePreProcessorStage
{
/**
* @param Template $template
* @return Template $template
* @param array $tree
*/
public function invoke(Template $template)
public function invoke(array &$tree)
{
$tree = $template->getTree();
$this->treePreProcessor->searchTreeByExpression('/^Port$/', $tree, function (&$tree, $key, $value) {
$this->treePreProcessor->searchTreeByExpression('/^Port$/', $tree, function (&$tree, $key, $value, $matches) {
unset($tree[$key]);
$tree['FromPort'] = $value;
$tree['ToPort'] = $value;
}, 'key');
$template->setTree($tree);

return $template;
}, true);
}
}
86 changes: 86 additions & 0 deletions src/StackFormation/PreProcessor/Stage/Tree/InjectFilecontent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace StackFormation\PreProcessor\Stage\Tree;

use StackFormation\PreProcessor\Stage\AbstractTreePreProcessorStage;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;

class InjectFilecontent extends AbstractTreePreProcessorStage
{
const MAX_JS_FILE_INCLUDE_SIZE = 4096;

/**
* @param array $tree
*/
public function invoke(array &$tree)
{
// Search in array key
$this->treePreProcessor->searchTreeByExpression('/^Fn::FileContent(|Unpretty|TrimLines|Minify)$/', $tree, function (array &$tree, $key, $value, $matches) {
unset($tree[$key]);
$lines = $this->renderFileContent($value, $matches[1]);
$tree['Fn::Join'] = [ '', [implode('', $lines)]];
}, true);

// Search in values (content)
$this->treePreProcessor->searchTreeByExpression('/Fn::FileContent(|Unpretty|TrimLines|Minify)(:)(.*)/', $tree, function (array &$tree, $key, $value, $matches) {
unset($tree[$key]);
$lines = $this->renderFileContent(trim(end($matches)), $matches[1]);
$tree[$key] = ['Fn::Join' => [ '', [implode('', $lines)]]];
});
}

/**
* @param string $file
* @param string $modus
* @return array
* @throws \Exception
*/
protected function renderFileContent($file, $modus)
{
$file = $this->template->getBasePath() . '/' . $file;
if (!is_file($file)) {
throw new FileNotFoundException("File '$file' not found");
}

$ext = pathinfo($file, PATHINFO_EXTENSION);
if ($modus == 'Minify' && $ext != 'js') {
throw new \Exception('Fn::FileContentMinify is only supported for *.js files. (File: ' . $file . ')');
}

$fileContent = file_get_contents($file);

# TODO in own stage ?
#$fileContent = $this->injectInclude($fileContent, dirname(realpath($file)));

if ($ext === 'js') {
if ($modus == 'Minify') {
$fileContent = \JShrink\Minifier::minify($fileContent, ['flaggedComments' => false]);
}

$size = strlen($fileContent);
if ($size > self::MAX_JS_FILE_INCLUDE_SIZE) {
// this is assuming you are uploading an inline JS file to AWS Lambda
throw new \Exception(sprintf("JS file is larger than %s bytes (actual size: %s bytes)", self::MAX_JS_FILE_INCLUDE_SIZE, $size));
}
}

// TODO: this isn't optimal. Why are we processing this here in between?
#$fileContent = $this->base64encodedJson($fileContent);

$lines = explode("\n", $fileContent);
foreach ($lines as $lineKey => &$line) {
if ($modus == 'TrimLines') {
$line = trim($line);
if (empty($line)) {
unset($lines[$lineKey]);
}
}
$line .= "\n";
}

#$whitespace = trim($matches[1], "\n");
#$result = str_replace("\n", "\n" . $whitespace, $result);

return $lines;
}
}
22 changes: 12 additions & 10 deletions src/StackFormation/PreProcessor/TreePreProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public function process(Template $template)
{
$stageClasses = [
'\StackFormation\PreProcessor\Stage\Tree\ExpandPort',
'\StackFormation\PreProcessor\Stage\Tree\InjectFilecontent',

# TODO, check also if we still need that
#'\StackFormation\PreProcessor\Stage\Tree\ParseRefInDoubleQuotedStrings',
#'\StackFormation\PreProcessor\Stage\Tree\InjectFilecontent',
#'\StackFormation\PreProcessor\Stage\Tree\Base64encodedJson',
#'\StackFormation\PreProcessor\Stage\Tree\Split',
#'\StackFormation\PreProcessor\Stage\Tree\ReplaceFnGetAttr',
Expand All @@ -28,30 +28,32 @@ public function process(Template $template)

$pipeline = new Pipeline();
foreach ($stageClasses as $stageClass) {
$pipeline->addStage(new $stageClass($this));
$pipeline->addStage(new $stageClass($this, $template));
}

return $pipeline->process($template);
$pipeline->process('');
}

/**
* @param string $expression
* @param array $tree
* @param callable $callback
* @param string $mode
* @param bool $expressionUsedOnKey
*/
public function searchTreeByExpression($expression, array &$tree, callable $callback, $mode = '')
public function searchTreeByExpression($expression, array &$tree, callable $callback, $expressionUsedOnKey = false)
{
#print_r($tree);die();

foreach ($tree as $key => &$leaf) {
if (is_array($leaf)) {
$this->searchTreeByExpression($expression, $leaf, $callback, $mode);
$this->searchTreeByExpression($expression, $leaf, $callback, $expressionUsedOnKey);
continue;
}

$subject = ($mode == 'key' ? $key : $leaf);
if (preg_match($expression, $subject)) {
$callback($tree, $key, $leaf);
}
$subject = ($expressionUsedOnKey === true ? $key : $leaf);
preg_replace_callback($expression, function(array $matches) use ($callback, &$tree, $key, $leaf) {
$callback($tree, $key, $leaf, $matches);
}, $subject);
}
}
}
15 changes: 15 additions & 0 deletions src/StackFormation/PrefixedTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public function getProcessedTemplate()
if ($this->prefix) {
if (!$this->cache->has(__METHOD__)) {
$content = parent::getProcessedTemplate();




# TODO $content is now an Template object


$content = $this->updateRef($this->prefix, $content);
$content = $this->updateDependsOn($this->prefix, $content);
$content = $this->updateDependsOnMultiple($this->prefix, $content);
Expand All @@ -47,6 +54,14 @@ public function getProcessedTemplate()

return $this->cache->get(__METHOD__);
} else {




# TODO return $this instead of



return parent::getProcessedTemplate();
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/StackFormation/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public function getProcessedTemplate()
return $this->cache->get(
__METHOD__,
function () {
return $this->treePreProcessor->process($this);
$this->treePreProcessor->process($this);
return $this;
}
);
}
Expand All @@ -78,16 +79,16 @@ public function getData()
$yamlParser = new \Symfony\Component\Yaml\Parser();
$this->tree = $yamlParser->parse($fileContent);

$this->getProcessedTemplate();
$template = $this->getProcessedTemplate();

if (!is_array($this->tree)) {
throw new TemplateDecodeException($this->getFilePath(), sprintf("Error decoding file '%s'", $this->getFilePath()));
if (!is_array($template->getTree())) {
throw new TemplateDecodeException($template->getFilePath(), sprintf("Error decoding file '%s'", $template->getFilePath()));
}
if ($this->tree['AWSTemplateFormatVersion'] != '2010-09-09') {
throw new TemplateInvalidException($this->getFilePath(), 'Invalid AWSTemplateFormatVersion');
if ($template->tree['AWSTemplateFormatVersion'] != '2010-09-09') {
throw new TemplateInvalidException($template->getFilePath(), 'Invalid AWSTemplateFormatVersion');
}

$this->cache->set(__METHOD__, $this->tree);
$this->cache->set(__METHOD__, $template->tree);
}

return $this->cache->get(__METHOD__);
Expand Down
3 changes: 1 addition & 2 deletions src/StackFormation/TemplateMerger.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ public function merge(array $templates, $description = null, array $additionalDa
if (Div::isProgramInstalled('jq')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'json_validate_');
$yaml = new \Symfony\Component\Yaml\Yaml();
$output = $yaml->dump($template->getProcessedTemplate());
file_put_contents($tmpfile, $output);
file_put_contents($tmpfile, $yaml->dump($data));
passthru('jq . ' . $tmpfile);
unlink($tmpfile);
}
Expand Down
13 changes: 13 additions & 0 deletions tests/StackFormation/PreprocessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
parent::setUp();



#
#
# TODO switch Preprocessor and rewrite/add tests
#
#
#
#



$this->preprocessor = new \StackFormation\Preprocessor();
}

Expand Down

0 comments on commit 47ed3f2

Please sign in to comment.