From 99e161770494412d52aef0e7a5304261306d208e Mon Sep 17 00:00:00 2001 From: Hussard Date: Sat, 16 Jul 2016 00:25:38 +0200 Subject: [PATCH 1/8] Extend Metadata with YAML data files defined in configuration --- src/Module/Config/Step/LoadConfig.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Module/Config/Step/LoadConfig.php b/src/Module/Config/Step/LoadConfig.php index 93df1a35..181813f9 100644 --- a/src/Module/Config/Step/LoadConfig.php +++ b/src/Module/Config/Step/LoadConfig.php @@ -51,6 +51,12 @@ public function __invoke(Project $project) } $metadata = $this->parseYamlFile($filename); + + if (array_key_exists('dataFiles', $metadata)) { + // Extend configuration with extra data files. + $metadata['dataFiles'] = $this->loadDataFiles($metadata['dataFiles'], $project->sourceDirectory); + } + $metadata = $this->validateConfig($metadata); $project->metadata->setMany($metadata); @@ -99,4 +105,23 @@ private function validateConfig($values) return $values; } + + /** + * Load extra data files defined in configuration file. + * + * @param array $dataFiles Array of data files to load. + * @param string $relativeTo Path from where files will be resolved. + * + * @return array Array - key,value - of loaded data. + */ + private function loadDataFiles($dataFiles, $relativeTo) + { + $loadedData = array(); + foreach ($dataFiles as $key => $dataFile) { + // Load this data file. + $loadedData["$key"] = $this->parseYamlFile($relativeTo . DIRECTORY_SEPARATOR . $dataFile); + } + + return $loadedData; + } } From 4bca9919d1d0b857d9d6d927f76bd1aca5839e4c Mon Sep 17 00:00:00 2001 From: Hussard Date: Sat, 16 Jul 2016 00:44:04 +0200 Subject: [PATCH 2/8] StyleCI: fixes for coding-style --- src/Module/Config/Step/LoadConfig.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Module/Config/Step/LoadConfig.php b/src/Module/Config/Step/LoadConfig.php index 181813f9..61079a25 100644 --- a/src/Module/Config/Step/LoadConfig.php +++ b/src/Module/Config/Step/LoadConfig.php @@ -109,17 +109,17 @@ private function validateConfig($values) /** * Load extra data files defined in configuration file. * - * @param array $dataFiles Array of data files to load. - * @param string $relativeTo Path from where files will be resolved. + * @param array $dataFiles Array of data files to load. + * @param string $relativeTo Path from where files will be resolved * - * @return array Array - key,value - of loaded data. + * @return array Array - key,value - of loaded data. */ private function loadDataFiles($dataFiles, $relativeTo) { - $loadedData = array(); + $loadedData = []; foreach ($dataFiles as $key => $dataFile) { // Load this data file. - $loadedData["$key"] = $this->parseYamlFile($relativeTo . DIRECTORY_SEPARATOR . $dataFile); + $loadedData["$key"] = $this->parseYamlFile($relativeTo.DIRECTORY_SEPARATOR.$dataFile); } return $loadedData; From 1b8f7518b26c8d6afcce2fbf762e44d5bd17753b Mon Sep 17 00:00:00 2001 From: Hussard Date: Sat, 16 Jul 2016 00:58:58 +0200 Subject: [PATCH 3/8] Watch loaded files to rerun generate on any modifications --- src/Module/Config/Step/LoadConfig.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Module/Config/Step/LoadConfig.php b/src/Module/Config/Step/LoadConfig.php index 61079a25..5e497ad7 100644 --- a/src/Module/Config/Step/LoadConfig.php +++ b/src/Module/Config/Step/LoadConfig.php @@ -54,7 +54,7 @@ public function __invoke(Project $project) if (array_key_exists('dataFiles', $metadata)) { // Extend configuration with extra data files. - $metadata['dataFiles'] = $this->loadDataFiles($metadata['dataFiles'], $project->sourceDirectory); + $metadata['dataFiles'] = $this->loadDataFiles($metadata['dataFiles'], $project); } $metadata = $this->validateConfig($metadata); @@ -114,12 +114,18 @@ private function validateConfig($values) * * @return array Array - key,value - of loaded data. */ - private function loadDataFiles($dataFiles, $relativeTo) + private function loadDataFiles($dataFiles, $project) { $loadedData = []; foreach ($dataFiles as $key => $dataFile) { + // Resolve path to this file. + $path = $project->sourceDirectory.DIRECTORY_SEPARATOR.$dataFile; + // Load this data file. - $loadedData["$key"] = $this->parseYamlFile($relativeTo.DIRECTORY_SEPARATOR.$dataFile); + $loadedData["$key"] = $this->parseYamlFile($path); + + // Watch this file. + $project->watchlist->watchFile($path); } return $loadedData; From c8ec52d46d0664f65da8d70b6af4e09140ee73d7 Mon Sep 17 00:00:00 2001 From: Hussard Date: Thu, 21 Jul 2016 21:04:50 +0200 Subject: [PATCH 4/8] Rename dataFiles to import --- src/Module/Config/Step/LoadConfig.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Module/Config/Step/LoadConfig.php b/src/Module/Config/Step/LoadConfig.php index 5e497ad7..6c6350b3 100644 --- a/src/Module/Config/Step/LoadConfig.php +++ b/src/Module/Config/Step/LoadConfig.php @@ -52,9 +52,9 @@ public function __invoke(Project $project) $metadata = $this->parseYamlFile($filename); - if (array_key_exists('dataFiles', $metadata)) { + if (array_key_exists('import', $metadata)) { // Extend configuration with extra data files. - $metadata['dataFiles'] = $this->loadDataFiles($metadata['dataFiles'], $project); + $metadata['import'] = $this->loadDataFiles($metadata['import'], $project); } $metadata = $this->validateConfig($metadata); From d17d5b02f8f49a8e3ea447e6bf02fbe7250f0568 Mon Sep 17 00:00:00 2001 From: Hussard Date: Thu, 21 Jul 2016 22:15:29 +0200 Subject: [PATCH 5/8] Let imported files overwrite couscous.yml (merging strategy) --- src/Module/Config/Step/LoadConfig.php | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Module/Config/Step/LoadConfig.php b/src/Module/Config/Step/LoadConfig.php index 6c6350b3..d3fa9e14 100644 --- a/src/Module/Config/Step/LoadConfig.php +++ b/src/Module/Config/Step/LoadConfig.php @@ -54,7 +54,12 @@ public function __invoke(Project $project) if (array_key_exists('import', $metadata)) { // Extend configuration with extra data files. - $metadata['import'] = $this->loadDataFiles($metadata['import'], $project); + foreach ($metadata['import'] as $dataFile) { + $metadata = array_replace_recursive( + $metadata, + $this->loadDataFile($dataFile, $project) + ); + } } $metadata = $this->validateConfig($metadata); @@ -109,24 +114,21 @@ private function validateConfig($values) /** * Load extra data files defined in configuration file. * - * @param array $dataFiles Array of data files to load. - * @param string $relativeTo Path from where files will be resolved + * @param array $dataFile File to load. + * @param string $relativeTo Path from where files will be resolved. * * @return array Array - key,value - of loaded data. */ - private function loadDataFiles($dataFiles, $project) + private function loadDataFile($dataFile, $project) { - $loadedData = []; - foreach ($dataFiles as $key => $dataFile) { - // Resolve path to this file. - $path = $project->sourceDirectory.DIRECTORY_SEPARATOR.$dataFile; + // Resolve path to this file. + $path = $project->sourceDirectory.DIRECTORY_SEPARATOR.$dataFile; - // Load this data file. - $loadedData["$key"] = $this->parseYamlFile($path); + // Load this data file. + $loadedData = $this->parseYamlFile($path); - // Watch this file. - $project->watchlist->watchFile($path); - } + // Watch this file. + $project->watchlist->watchFile($path); return $loadedData; } From 804962441d88123d72b6c318ceb5b799a99a13f4 Mon Sep 17 00:00:00 2001 From: Hussard Date: Thu, 21 Jul 2016 22:18:56 +0200 Subject: [PATCH 6/8] Store files to import makes it less likely to go wazoo if file contains 'import' too --- src/Module/Config/Step/LoadConfig.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Module/Config/Step/LoadConfig.php b/src/Module/Config/Step/LoadConfig.php index d3fa9e14..3dfa29d1 100644 --- a/src/Module/Config/Step/LoadConfig.php +++ b/src/Module/Config/Step/LoadConfig.php @@ -54,7 +54,8 @@ public function __invoke(Project $project) if (array_key_exists('import', $metadata)) { // Extend configuration with extra data files. - foreach ($metadata['import'] as $dataFile) { + $filesToImport = $metadata['import']; + foreach ($filesToImport as $dataFile) { $metadata = array_replace_recursive( $metadata, $this->loadDataFile($dataFile, $project) From 87f81716970aa5045a50ae6ab3184df63c787ed1 Mon Sep 17 00:00:00 2001 From: Hussard Date: Fri, 22 Jul 2016 01:36:24 +0200 Subject: [PATCH 7/8] Some UnitTest for LoadConfig step (with and without import) --- .../Config/Step/Fixtures/couscous-simple.yml | 9 ++ .../Step/Fixtures/couscous-with-import.yml | 12 ++ .../Config/Step/Fixtures/imported-file1.yml | 6 + .../Module/Config/Step/LoadConfigTest.php | 113 ++++++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 tests/UnitTest/Module/Config/Step/Fixtures/couscous-simple.yml create mode 100644 tests/UnitTest/Module/Config/Step/Fixtures/couscous-with-import.yml create mode 100644 tests/UnitTest/Module/Config/Step/Fixtures/imported-file1.yml create mode 100644 tests/UnitTest/Module/Config/Step/LoadConfigTest.php diff --git a/tests/UnitTest/Module/Config/Step/Fixtures/couscous-simple.yml b/tests/UnitTest/Module/Config/Step/Fixtures/couscous-simple.yml new file mode 100644 index 00000000..cbd4495f --- /dev/null +++ b/tests/UnitTest/Module/Config/Step/Fixtures/couscous-simple.yml @@ -0,0 +1,9 @@ + +template: + index: index.md + +include: + - some/dir + - some/other/dir + +title: coucous-simple! diff --git a/tests/UnitTest/Module/Config/Step/Fixtures/couscous-with-import.yml b/tests/UnitTest/Module/Config/Step/Fixtures/couscous-with-import.yml new file mode 100644 index 00000000..4128ee7d --- /dev/null +++ b/tests/UnitTest/Module/Config/Step/Fixtures/couscous-with-import.yml @@ -0,0 +1,12 @@ + +template: + index: index.md + +include: + - some/dir + - some/other/dir + +title: coucous-simple! + +import: + - imported-file1.yml diff --git a/tests/UnitTest/Module/Config/Step/Fixtures/imported-file1.yml b/tests/UnitTest/Module/Config/Step/Fixtures/imported-file1.yml new file mode 100644 index 00000000..45a00a2f --- /dev/null +++ b/tests/UnitTest/Module/Config/Step/Fixtures/imported-file1.yml @@ -0,0 +1,6 @@ +include: + - some/dir + - some/other/dir + - other/dir/imported + +title: overwritten by imported-file1.yml \ No newline at end of file diff --git a/tests/UnitTest/Module/Config/Step/LoadConfigTest.php b/tests/UnitTest/Module/Config/Step/LoadConfigTest.php new file mode 100644 index 00000000..34074806 --- /dev/null +++ b/tests/UnitTest/Module/Config/Step/LoadConfigTest.php @@ -0,0 +1,113 @@ +filesystem = new Filesystem(); + $this->workingDir = $this->getUniqueTmpDirectory(); + } + + protected function tearDown() + { + if ($this->filesystem->exists($this->workingDir)) { + $this->filesystem->remove($this->workingDir); + } + } + + /** + * @test + */ + public function it_should_load_simple_config() + { + // Copy fixtures to working directory. + $this->filesystem->copy($this->getFixturePath("couscous-simple.yml"), $this->workingDir.DIRECTORY_SEPARATOR.LoadConfig::FILENAME); + + // Create a project for working directory. + $project = new Project($this->workingDir, ''); + + // Load config. + $parser = new Parser(); + $step = new LoadConfig($this->filesystem, $parser, new NullLogger()); + $step->__invoke($project); + + $this->assertEquals(['some/dir', 'some/other/dir'], $project->metadata['include']); + $this->assertEquals("coucous-simple!", $project->metadata['title']); + } + + /** + * @test + */ + public function it_should_overwrite_config() + { + // Copy fixtures to working directory. + $this->filesystem->copy($this->getFixturePath("couscous-with-import.yml"), $this->workingDir.DIRECTORY_SEPARATOR.LoadConfig::FILENAME); + $this->filesystem->copy($this->getFixturePath("imported-file1.yml"), $this->workingDir.DIRECTORY_SEPARATOR."imported-file1.yml"); + + // Create a project for working directory. + $project = new Project($this->workingDir, ''); + + // Load config. + $parser = new Parser(); + $step = new LoadConfig($this->filesystem, $parser, new NullLogger()); + $step->__invoke($project); + + $this->assertEquals(['some/dir', 'some/other/dir', 'other/dir/imported'], $project->metadata['include']); + $this->assertEquals("overwritten by imported-file1.yml", $project->metadata['title']); + } + + /** + * Locate fixtures and return path. + * + * @param string $name + * + * @return string + */ + protected function getFixturePath($name) + { + return __DIR__.'/Fixtures/'.$name; + } + + /** + * Create a unique working directory within temp dir. + * + * Shamelessly borrowed from Composer\TestCase. + * + * @return string + */ + public function getUniqueTmpDirectory() + { + $attempts = 5; + $root = sys_get_temp_dir(); + + do { + $unique = $root . DIRECTORY_SEPARATOR . uniqid('couscous-test-' . rand(1000, 9000)); + + if (!$this->filesystem->exists($unique)) { + // Create and return. + $this->filesystem->mkdir($unique, 0777); + return realpath($unique); + } + } while (--$attempts); + + throw new \RuntimeException('Failed to create a unique temporary directory.'); + } +} From e0b8861a3d3e8276ed95f6a4331e3e3c3cb609f0 Mon Sep 17 00:00:00 2001 From: Hussard Date: Fri, 22 Jul 2016 01:38:55 +0200 Subject: [PATCH 8/8] StyleCI fixes --- .../Module/Config/Step/LoadConfigTest.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/UnitTest/Module/Config/Step/LoadConfigTest.php b/tests/UnitTest/Module/Config/Step/LoadConfigTest.php index 34074806..61e0b8fd 100644 --- a/tests/UnitTest/Module/Config/Step/LoadConfigTest.php +++ b/tests/UnitTest/Module/Config/Step/LoadConfigTest.php @@ -4,9 +4,7 @@ use Couscous\Model\Project; use Couscous\Module\Config\Step\LoadConfig; - use Psr\Log\NullLogger; - use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Yaml\Parser; @@ -39,7 +37,7 @@ protected function tearDown() public function it_should_load_simple_config() { // Copy fixtures to working directory. - $this->filesystem->copy($this->getFixturePath("couscous-simple.yml"), $this->workingDir.DIRECTORY_SEPARATOR.LoadConfig::FILENAME); + $this->filesystem->copy($this->getFixturePath('couscous-simple.yml'), $this->workingDir.DIRECTORY_SEPARATOR.LoadConfig::FILENAME); // Create a project for working directory. $project = new Project($this->workingDir, ''); @@ -50,7 +48,7 @@ public function it_should_load_simple_config() $step->__invoke($project); $this->assertEquals(['some/dir', 'some/other/dir'], $project->metadata['include']); - $this->assertEquals("coucous-simple!", $project->metadata['title']); + $this->assertEquals('coucous-simple!', $project->metadata['title']); } /** @@ -59,8 +57,8 @@ public function it_should_load_simple_config() public function it_should_overwrite_config() { // Copy fixtures to working directory. - $this->filesystem->copy($this->getFixturePath("couscous-with-import.yml"), $this->workingDir.DIRECTORY_SEPARATOR.LoadConfig::FILENAME); - $this->filesystem->copy($this->getFixturePath("imported-file1.yml"), $this->workingDir.DIRECTORY_SEPARATOR."imported-file1.yml"); + $this->filesystem->copy($this->getFixturePath('couscous-with-import.yml'), $this->workingDir.DIRECTORY_SEPARATOR.LoadConfig::FILENAME); + $this->filesystem->copy($this->getFixturePath('imported-file1.yml'), $this->workingDir.DIRECTORY_SEPARATOR.'imported-file1.yml'); // Create a project for working directory. $project = new Project($this->workingDir, ''); @@ -71,13 +69,13 @@ public function it_should_overwrite_config() $step->__invoke($project); $this->assertEquals(['some/dir', 'some/other/dir', 'other/dir/imported'], $project->metadata['include']); - $this->assertEquals("overwritten by imported-file1.yml", $project->metadata['title']); + $this->assertEquals('overwritten by imported-file1.yml', $project->metadata['title']); } /** * Locate fixtures and return path. * - * @param string $name + * @param string $name * * @return string */ @@ -99,11 +97,12 @@ public function getUniqueTmpDirectory() $root = sys_get_temp_dir(); do { - $unique = $root . DIRECTORY_SEPARATOR . uniqid('couscous-test-' . rand(1000, 9000)); + $unique = $root.DIRECTORY_SEPARATOR.uniqid('couscous-test-'.rand(1000, 9000)); if (!$this->filesystem->exists($unique)) { // Create and return. $this->filesystem->mkdir($unique, 0777); + return realpath($unique); } } while (--$attempts);