From b8af4a4b1fbe938e3c2bbf166e2d4fca91380da8 Mon Sep 17 00:00:00 2001 From: Salem Ghoweri Date: Sat, 26 Aug 2017 12:54:15 -0400 Subject: [PATCH 1/3] Working solution to automatically regenerate any Styleguidekit Assets Default files in the public dir if entire directory gets wiped. Solves https://github.com/drupal-pattern-lab/patternlab-php-core/issues/14 --- src/PatternLab/Builder.php | 225 ++++++++++++++++++++++--------------- 1 file changed, 133 insertions(+), 92 deletions(-) diff --git a/src/PatternLab/Builder.php b/src/PatternLab/Builder.php index fb91068f..a7ac535d 100644 --- a/src/PatternLab/Builder.php +++ b/src/PatternLab/Builder.php @@ -29,77 +29,118 @@ use \Symfony\Component\Finder\Finder; class Builder { - + /** * When initializing the Builder class make sure the template helper is set-up */ public function __construct() { - + // set-up the pattern engine PatternEngine::init(); - + // set-up the various attributes for rendering templates Template::init(); - + } - + /** * Generates the annotations js file */ protected function generateAnnotations() { - + // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); - + // note the start of the operation $dispatcherInstance->dispatch("builder.generateAnnotationsStart"); - + // default var $publicDir = Config::getOption("publicDir"); - + // encode the content so it can be written out $json = json_encode(Annotations::get()); - + // make sure annotations/ exists if (!is_dir($publicDir."/annotations")) { mkdir($publicDir."/annotations"); } - + // write out the new annotations.js file file_put_contents($publicDir."/annotations/annotations.js","var comments = ".$json.";"); - + // note the end of the operation $dispatcherInstance->dispatch("builder.generateAnnotationsEnd"); - + } - + /** * Generates the data that powers the index page */ protected function generateIndex() { - - // bomb if missing index.html + + /** + * Handle missing index.html. Solves https://github.com/drupal-pattern-lab/patternlab-php-core/issues/14 + * Could also be used to re-add missing styleguidekit assets with a few edits? + * + * 1. @TODO: What would be a better way to find our base vendor directory from here? + * 2. Locate the current theme's styleguidekit assets via the patternlab-styleguidekit `type` in composer.json + * 3. @TODO: Figure out a better way to future-proof path resolution for styleguidekit `dist` folder + * 4. Recusirively copy files from styleguidekit to publicDir via https://stackoverflow.com/a/7775949 + * 5. Make sure we only try to create new directories if they don't already exist + * 6. Only copy files if they are missing (vs changed, etc) + */ if (!file_exists(Config::getOption("publicDir")."/index.html")) { $index = Console::getHumanReadablePath(Config::getOption("publicDir")).DIRECTORY_SEPARATOR."index.html"; - Console::writeError("".$index." is missing. grab a copy from your StyleguideKit..."); + Console::writeWarning($index . " is missing. No biggie. Grabbing a copy from your StyleguideKit..."); + + $finder = new Finder(); + $base = __DIR__."/../../../"; /* [1] */ + $finder->files()->name("composer.json")->in($base)->contains('patternlab-styleguidekit')->sortByName(); /* [2] */ + + foreach ($finder as $file) { + $src = dirname($file->getRealPath()) . DIRECTORY_SEPARATOR . 'dist'; /* [3] */ + $dest= Config::getOption("publicDir"); + + if (is_dir($src)){ + + if(!is_dir($dest)) { + mkdir($dest, 0755); + } + + foreach ( /* [4] */ + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($src, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item + ) { + if ($item->isDir()) { + if(!is_dir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) { /* [5] */ + mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } + } else { + if(!file_exists($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) { /* [6] */ + copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } + } + } + } + } } - + // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); - + // note the start of the operation $dispatcherInstance->dispatch("builder.generateIndexStart"); - + // default var $dataDir = Config::getOption("publicDir")."/styleguide/data"; - + // double-check that the data directory exists if (!is_dir($dataDir)) { FileUtil::makeDir($dataDir); } - + $output = ""; - + // load and write out the config options $config = array(); $exposedOptions = Config::getOption("exposedOptions"); @@ -107,7 +148,7 @@ protected function generateIndex() { $config[$exposedOption] = Config::getOption($exposedOption); } $output .= "var config = ".json_encode($config).";\n"; - + // load the ish Controls $ishControls = array(); $controlsToHide = array(); @@ -119,24 +160,24 @@ protected function generateIndex() { } $ishControls["ishControlsHide"] = $controlsToHide; $output .= "var ishControls = ".json_encode($ishControls).";\n"; - + // load and write out the items for the navigation $niExporter = new NavItemsExporter(); $navItems = $niExporter->run(); $output .= "var navItems = ".json_encode($navItems).";\n"; - + // load and write out the items for the pattern paths $patternPaths = array(); $ppdExporter = new PatternPathDestsExporter(); $patternPaths = $ppdExporter->run(); $output .= "var patternPaths = ".json_encode($patternPaths).";\n"; - + // load and write out the items for the view all paths $viewAllPaths = array(); $vapExporter = new ViewAllPathsExporter(); $viewAllPaths = $vapExporter->run($navItems); $output .= "var viewAllPaths = ".json_encode($viewAllPaths).";\n"; - + // gather plugin package information $packagesInfo = array(); $componentDir = Config::getOption("componentDir"); @@ -167,27 +208,27 @@ protected function generateIndex() { } } $output .= "var plugins = ".json_encode($packagesInfo).";"; - + // write out the data file_put_contents($dataDir."/patternlab-data.js",$output); - + // note the end of the operation $dispatcherInstance->dispatch("builder.generateIndexEnd"); - + } - + /** * Generates all of the patterns and puts them in the public directory * @param {Array} various options that might affect the export. primarily the location. */ protected function generatePatterns($options = array()) { - + // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); - + // note the beginning of the operation $dispatcherInstance->dispatch("builder.generatePatternsStart"); - + // set-up common vars $exportFiles = (isset($options["exportFiles"]) && $options["exportFiles"]); $exportDir = Config::getOption("exportDir"); @@ -197,66 +238,66 @@ protected function generatePatterns($options = array()) { $suffixRendered = Config::getOption("outputFileSuffixes.rendered"); $suffixRaw = Config::getOption("outputFileSuffixes.rawTemplate"); $suffixMarkupOnly = Config::getOption("outputFileSuffixes.markupOnly"); - + // make sure the export dir exists if ($exportFiles && !is_dir($exportDir)) { mkdir($exportDir); } - + // make sure patterns exists if (!is_dir($patternPublicDir)) { mkdir($patternPublicDir); } - + // loop over the pattern data store to render the individual patterns $store = PatternData::get(); foreach ($store as $patternStoreKey => $patternStoreData) { - + if (($patternStoreData["category"] == "pattern") && isset($patternStoreData["hidden"]) && (!$patternStoreData["hidden"])) { - + $path = $patternStoreData["pathDash"]; $pathName = (isset($patternStoreData["pseudo"])) ? $patternStoreData["pathOrig"] : $patternStoreData["pathName"]; - + // modify the pattern mark-up $markup = $patternStoreData["code"]; $markupFull = $patternStoreData["header"].$markup.$patternStoreData["footer"]; $markupEngine = file_get_contents($patternSourceDir."/".$pathName.".".$patternExtension); - + // if the pattern directory doesn't exist create it if (!is_dir($patternPublicDir."/".$path)) { mkdir($patternPublicDir."/".$path); } - + // write out the various pattern files file_put_contents($patternPublicDir."/".$path."/".$path.$suffixRendered.".html",$markupFull); if (!$exportFiles) { file_put_contents($patternPublicDir."/".$path."/".$path.$suffixMarkupOnly.".html",$markup); file_put_contents($patternPublicDir."/".$path."/".$path.$suffixRaw.".".$patternExtension,$markupEngine); } - + } - + } - + // note the end of the operation $dispatcherInstance->dispatch("builder.generatePatternsEnd"); - + } - + /** * Generates the style guide view */ protected function generateStyleguide() { - + // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); - + // note the beginning of the operation $dispatcherInstance->dispatch("builder.generateStyleguideStart"); - + // default var $publicDir = Config::getOption("publicDir"); - + // load the pattern loader $ppdExporter = new PatternPathSrcExporter(); $patternPathSrc = $ppdExporter->run(); @@ -265,56 +306,56 @@ protected function generateStyleguide() { $patternEngineBasePath = PatternEngine::getInstance()->getBasePath(); $patternLoaderClass = $patternEngineBasePath."\Loaders\PatternLoader"; $patternLoader = new $patternLoaderClass($options); - + // check directories i need if (!is_dir($publicDir."/styleguide/")) { mkdir($publicDir."/styleguide/"); } - + if (!is_dir($publicDir."/styleguide/html/")) { mkdir($publicDir."/styleguide/html/"); } - + // grab the partials into a data object for the style guide $ppExporter = new PatternPartialsExporter(); $partials = $ppExporter->run(); - + // add the pattern data so it can be exported $patternData = array(); - + // add the pattern lab specific mark-up $filesystemLoader = Template::getFilesystemLoader(); $stringLoader = Template::getStringLoader(); - + $globalData = Data::get(); $globalData["patternLabHead"] = $stringLoader->render(array("string" => Template::getHTMLHead(), "data" => array("cacheBuster" => $partials["cacheBuster"]))); $globalData["patternLabFoot"] = $stringLoader->render(array("string" => Template::getHTMLFoot(), "data" => array("cacheBuster" => $partials["cacheBuster"], "patternData" => json_encode($patternData)))); $globalData["viewall"] = true; - + $header = $patternLoader->render(array("pattern" => Template::getPatternHead(), "data" => $globalData)); $code = $filesystemLoader->render(array("template" => "viewall", "data" => $partials)); $footer = $patternLoader->render(array("pattern" => Template::getPatternFoot(), "data" => $globalData)); - + $styleGuidePage = $header.$code.$footer; - + file_put_contents($publicDir."/styleguide/html/styleguide.html",$styleGuidePage); - + // note the end of the operation $dispatcherInstance->dispatch("builder.generateStyleguideEnd"); - + } - + /** * Generates the view all pages */ protected function generateViewAllPages() { - + // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); - + // note the beginning of the operation $dispatcherInstance->dispatch("builder.generateViewAllPagesStart"); - + // default vars $patternPublicDir = Config::getOption("patternPublicDir"); $htmlHead = Template::getHTMLHead(); @@ -324,7 +365,7 @@ protected function generateViewAllPages() { $filesystemLoader = Template::getFilesystemLoader(); $stringLoader = Template::getStringLoader(); $globalData = Data::get(); - + // load the pattern loader $ppdExporter = new PatternPathSrcExporter(); $patternPathSrc = $ppdExporter->run(); @@ -333,40 +374,40 @@ protected function generateViewAllPages() { $patternEngineBasePath = PatternEngine::getInstance()->getBasePath(); $patternLoaderClass = $patternEngineBasePath."\Loaders\PatternLoader"; $patternLoader = new $patternLoaderClass($options); - + // make sure view all is set $globalData["viewall"] = true; - + // make sure the pattern dir exists if (!is_dir($patternPublicDir)) { mkdir($patternPublicDir); } - + // add view all to each list $store = PatternData::get(); foreach ($store as $patternStoreKey => $patternStoreData) { - + if ($patternStoreData["category"] == "patternSubtype") { - + // grab the partials into a data object for the style guide $ppExporter = new PatternPartialsExporter(); $partials = $ppExporter->run($patternStoreData["type"],$patternStoreData["name"]); - + if (!empty($partials["partials"])) { - + // add the pattern data so it can be exported $patternData = array(); $patternData["patternPartial"] = "viewall-".$patternStoreData["typeDash"]."-".$patternStoreData["nameDash"]; - + $globalData["patternLabHead"] = $stringLoader->render(array("string" => Template::getHTMLHead(), "data" => array("cacheBuster" => $partials["cacheBuster"]))); $globalData["patternLabFoot"] = $stringLoader->render(array("string" => Template::getHTMLFoot(), "data" => array("cacheBuster" => $partials["cacheBuster"], "patternData" => json_encode($patternData)))); - + // render the parts and join them $header = $patternLoader->render(array("pattern" => $patternHead, "data" => $globalData)); $code = $filesystemLoader->render(array("template" => "viewall", "data" => $partials)); $footer = $patternLoader->render(array("pattern" => $patternFoot, "data" => $globalData)); $viewAllPage = $header.$code.$footer; - + // if the pattern directory doesn't exist create it $patternPath = $patternStoreData["pathDash"]; if (!is_dir($patternPublicDir."/".$patternPath)) { @@ -375,31 +416,31 @@ protected function generateViewAllPages() { } else { file_put_contents($patternPublicDir."/".$patternPath."/index.html",$viewAllPage); } - + } - + } else if (($patternStoreData["category"] == "patternType") && PatternData::hasPatternSubtype($patternStoreData["nameDash"])) { - + // grab the partials into a data object for the style guide $ppExporter = new PatternPartialsExporter(); $partials = $ppExporter->run($patternStoreData["name"]); - + if (!empty($partials["partials"])) { - + // add the pattern data so it can be exported $patternData = array(); $patternData["patternPartial"] = "viewall-".$patternStoreData["nameDash"]."-all"; - + // add the pattern lab specific mark-up $globalData["patternLabHead"] = $stringLoader->render(array("string" => $htmlHead, "data" => array("cacheBuster" => $partials["cacheBuster"]))); $globalData["patternLabFoot"] = $stringLoader->render(array("string" => $htmlFoot, "data" => array("cacheBuster" => $partials["cacheBuster"], "patternData" => json_encode($patternData)))); - + // render the parts and join them $header = $patternLoader->render(array("pattern" => $patternHead, "data" => $globalData)); $code = $filesystemLoader->render(array("template" => "viewall", "data" => $partials)); $footer = $patternLoader->render(array("pattern" => $patternFoot, "data" => $globalData)); $viewAllPage = $header.$code.$footer; - + // if the pattern directory doesn't exist create it $patternPath = $patternStoreData["pathDash"]; if (!is_dir($patternPublicDir."/".$patternPath)) { @@ -408,16 +449,16 @@ protected function generateViewAllPages() { } else { file_put_contents($patternPublicDir."/".$patternPath."/index.html",$viewAllPage); } - + } - + } - + } - + // note the end of the operation $dispatcherInstance->dispatch("builder.generateViewAllPagesEnd"); - + } - + } From 0eace9ea6b2926c1126d1437b923298225851f27 Mon Sep 17 00:00:00 2001 From: Evan Lovely Date: Mon, 28 Aug 2017 11:33:00 -0700 Subject: [PATCH 2/3] adding styleguidekit path var --- src/PatternLab/Builder.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PatternLab/Builder.php b/src/PatternLab/Builder.php index a7ac535d..39034273 100644 --- a/src/PatternLab/Builder.php +++ b/src/PatternLab/Builder.php @@ -95,6 +95,7 @@ protected function generateIndex() { $finder = new Finder(); $base = __DIR__."/../../../"; /* [1] */ + $kit_path = Config::getOption("styleguideKitPath"); $finder->files()->name("composer.json")->in($base)->contains('patternlab-styleguidekit')->sortByName(); /* [2] */ foreach ($finder as $file) { From b16f3f6f7b0a6b0da7ec04d7ca28e091f43c11fa Mon Sep 17 00:00:00 2001 From: Salem Ghoweri Date: Sat, 2 Sep 2017 18:51:22 -0400 Subject: [PATCH 3/3] fix: cleaning up base path directory logic to make a little less prone to breaking --- src/PatternLab/Builder.php | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/PatternLab/Builder.php b/src/PatternLab/Builder.php index 39034273..bceb8147 100644 --- a/src/PatternLab/Builder.php +++ b/src/PatternLab/Builder.php @@ -82,24 +82,23 @@ protected function generateIndex() { * Handle missing index.html. Solves https://github.com/drupal-pattern-lab/patternlab-php-core/issues/14 * Could also be used to re-add missing styleguidekit assets with a few edits? * - * 1. @TODO: What would be a better way to find our base vendor directory from here? - * 2. Locate the current theme's styleguidekit assets via the patternlab-styleguidekit `type` in composer.json - * 3. @TODO: Figure out a better way to future-proof path resolution for styleguidekit `dist` folder - * 4. Recusirively copy files from styleguidekit to publicDir via https://stackoverflow.com/a/7775949 - * 5. Make sure we only try to create new directories if they don't already exist - * 6. Only copy files if they are missing (vs changed, etc) + * 1. @TODO: Figure out a better way to future-proof path resolution for styleguidekit `dist` folder + * 2. Recusirively copy files from styleguidekit to publicDir via https://stackoverflow.com/a/7775949 + * 3. Make sure we only try to create new directories if they don't already exist + * 4. Only copy files if they are missing (vs changed, etc) */ if (!file_exists(Config::getOption("publicDir")."/index.html")) { $index = Console::getHumanReadablePath(Config::getOption("publicDir")).DIRECTORY_SEPARATOR."index.html"; - Console::writeWarning($index . " is missing. No biggie. Grabbing a copy from your StyleguideKit..."); + Console::writeWarning($index . " is missing. No biggie. Grabbing a fresh copy from your StyleguideKit..."); + $baseDir = Config::getOption("baseDir") . '/vendor'; $finder = new Finder(); - $base = __DIR__."/../../../"; /* [1] */ - $kit_path = Config::getOption("styleguideKitPath"); - $finder->files()->name("composer.json")->in($base)->contains('patternlab-styleguidekit')->sortByName(); /* [2] */ + + // Locate the current theme's styleguidekit assets via the patternlab-styleguidekit `type` in composer.json + $finder->files()->name("composer.json")->in($baseDir)->contains('patternlab-styleguidekit')->sortByName(); foreach ($finder as $file) { - $src = dirname($file->getRealPath()) . DIRECTORY_SEPARATOR . 'dist'; /* [3] */ + $src = dirname($file->getRealPath()) . DIRECTORY_SEPARATOR . 'dist'; /* [1] */ $dest= Config::getOption("publicDir"); if (is_dir($src)){ @@ -108,16 +107,16 @@ protected function generateIndex() { mkdir($dest, 0755); } - foreach ( /* [4] */ + foreach ( /* [2] */ $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($src, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item ) { if ($item->isDir()) { - if(!is_dir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) { /* [5] */ + if(!is_dir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) { /* [3] */ mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); } } else { - if(!file_exists($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) { /* [6] */ + if(!file_exists($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) { /* [4] */ copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); } }