public function run()
 {
     if (Console::findCommandOption("list")) {
         // get all of the options
         $options = Config::getOptions();
         // sort 'em alphabetically
         ksort($options);
         // find length of longest option
         $lengthLong = 0;
         foreach ($options as $optionName => $optionValue) {
             $lengthLong = strlen($optionName) > $lengthLong ? strlen($optionName) : $lengthLong;
         }
         // iterate over each option and spit it out
         foreach ($options as $optionName => $optionValue) {
             $optionValue = is_array($optionValue) ? implode(", ", $optionValue) : $optionValue;
             $optionValue = !$optionValue ? "false" : $optionValue;
             $spacer = Console::getSpacer($lengthLong, strlen($optionName));
             Console::writeLine("<info>" . $optionName . ":</info>" . $spacer . $optionValue);
         }
     } else {
         if (Console::findCommandOption("get")) {
             // figure out which optino was passed
             $searchOption = Console::findCommandOptionValue("get");
             $optionValue = Config::getOption($searchOption);
             // write it out
             if (!$optionValue) {
                 Console::writeError("the --get value you provided, <info>" . $searchOption . "</info>, does not exists in the config...");
             } else {
                 $optionValue = is_array($optionValue) ? implode(", ", $optionValue) : $optionValue;
                 $optionValue = !$optionValue ? "false" : $optionValue;
                 Console::writeInfo($searchOption . ": <ok>" . $optionValue . "</ok>");
             }
         } else {
             if (Console::findCommandOption("set")) {
                 // find the value that was passed
                 $updateOption = Console::findCommandOptionValue("set");
                 $updateOptionBits = explode("=", $updateOption);
                 if (count($updateOptionBits) == 1) {
                     Console::writeError("the --set value should look like <info>optionName=\"optionValue\"</info>. nothing was updated...");
                 }
                 // set the name and value that were passed
                 $updateName = $updateOptionBits[0];
                 $updateValue = $updateOptionBits[1][0] == "\"" || $updateOptionBits[1][0] == "'" ? substr($updateOptionBits[1], 1, strlen($updateOptionBits[1]) - 1) : $updateOptionBits[1];
                 // make sure the option being updated already exists
                 $currentValue = Config::getOption($updateName);
                 if (!$currentValue) {
                     Console::writeError("the --set option you provided, <info>" . $updateName . "</info>, does not exists in the config. nothing will be updated...");
                 } else {
                     Config::updateConfigOption($updateName, $updateValue);
                 }
             } else {
                 // no acceptable options were passed so write out the help
                 Console::writeHelpCommand($this->command);
             }
         }
     }
 }
 /**
  * Returns the last error message when building a JSON file. Mimics json_last_error_msg() from PHP 5.5
  * @param  {String}       the file that generated the error
  */
 public static function lastErrorMsg($file, $message, $data)
 {
     Console::writeLine(PHP_EOL . "<error>The JSON file, " . $file . ", wasn't loaded. The error: " . $message . "</error>");
     if ($message == "Syntax error, malformed JSON") {
         Console::writeLine("");
         $parser = new JsonLint\JsonParser();
         $error = $parser->lint($data);
         Console::writeError($error->getMessage(), false, true);
     }
 }
 /**
  * Randomly prints a saying after the generate is complete
  */
 public function say()
 {
     // set a color
     $colors = array("ok", "options", "info", "warning");
     $randomNumber = rand(0, count($colors) - 1);
     $color = isset($colors[$randomNumber]) ? $colors[$randomNumber] : "desc";
     // set a 1 in 3 chance that a saying is printed
     $randomNumber = rand(0, (count($this->sayings) - 1) * 3);
     if (isset($this->sayings[$randomNumber])) {
         Console::writeLine("<" . $color . ">" . $this->sayings[$randomNumber] . "...</" . $color . ">");
     }
 }
 protected function starterKitSuggestions()
 {
     Console::writeLine("");
     $composerPath = Config::getOption("baseDir") . "/composer.json";
     if (file_exists($composerPath)) {
         $json = file_get_contents($composerPath);
         $data = json_decode($json, true);
         if ($jsonErrorMessage = JSON::hasError()) {
             JSON::lastErrorMsg(Console::getHumanReadablePath($oldStyleAnnotationsPath), $jsonErrorMessage, $data);
         }
         if (isset($data["extra"]) && isset($data["extra"]["patternlab"]) && isset($data["extra"]["patternlab"]["starterKitSuggestions"])) {
             $starterKitSuggestions = $data["extra"]["patternlab"]["starterKitSuggestions"];
             Console::writeInfo("suggested starterkits that work with this edition:", false, true);
             foreach ($starterKitSuggestions as $i => $suggestion) {
                 $num = $i + 1;
                 Console::writeLine($num . ": " . $suggestion, true);
             }
             // hack around installer util feature in Console::promptInput
             InstallerUtil::$isInteractive = true;
             // prompt for input on the suggestions
             Console::writeLine("");
             $prompt = "choose an option or hit return to cancel:";
             $options = "(ex. 1)";
             $input = Console::promptInput($prompt, $options, "1");
             $result = (int) $input - 1;
             if (isset($starterKitSuggestions[$result])) {
                 Console::writeLine("");
                 $f = new Fetch();
                 $result = $f->fetchStarterKit($starterKitSuggestions[$result]);
             }
         } else {
             Console::writeWarning("this edition has no starterkits to suggested...", false, true);
         }
     } else {
         Console::writeError("can't find composer.json to get suggestions...", false, true);
     }
 }
 /**
  * Randomly prints a saying after the generate is complete
  */
 public function printSaying()
 {
     $randomNumber = rand(0, 3);
     $colors = array("ok", "options", "info", "warning", "error");
     $color = isset($colors[$randomNumber]) ? $colors[$randomNumber] : "desc";
     $randomNumber = rand(0, 60);
     $sayings = array("have fun storming the castle", "be well, do good work, and keep in touch", "may the sun shine, all day long", "smile :)", "namaste", "walk as if you are kissing the earth with your feet", "to be beautiful means to be yourself", "i was thinking of the immortal words of socrates, who said \"...i drank what?\"", "let me take this moment to compliment you on your fashion sense, particularly your slippers", "42", "he who controls the spice controls the universe", "the greatest thing you'll ever learn is just to love and be loved in return", "nice wand", "i don't have time for a grudge match with every poseur in a parka", "han shot first", "what we've got here is a failure to communicate", "mama always said life was like a box of chocolates. you never know what you're gonna get", "soylent green is people", "a little word of advice, my friend. sometimes you gotta let those hard-to-reach chips go", "shop smart. shop s-mart", "klaatu barada nikto", "(╯°□°)╯︵ ┻━┻", "¸.·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º>", "@}~}~~~", "(>'.')> (>'.')> (>'.')> ", "\\(^-^)/");
     if (isset($sayings[$randomNumber])) {
         Console::writeLine("<" . $color . ">" . $sayings[$randomNumber] . "...</" . $color . ">");
     }
 }
 /**
  * Stop the timer
  */
 public static function stop()
 {
     // make sure start time is set
     if (empty(self::$startTime)) {
         Console::writeError("the timer wasn't started...");
     }
     // get the current time
     $endTime = self::getTime();
     // get the data for the output
     $totalTime = $endTime - self::$startTime;
     $mem = round(memory_get_peak_usage(true) / 1024 / 1024, 2);
     // figure out what tag to show
     $timeTag = "info";
     if ($totalTime > 0.5) {
         $timeTag = "error";
     } else {
         if ($totalTime > 0.3) {
             $timeTag = "warning";
         }
     }
     // write out time/mem stats
     Console::writeLine("site generation took <" . $timeTag . ">" . $totalTime . "</" . $timeTag . "> seconds and used <info>" . $mem . "MB</info> of memory...");
 }
 /**
  * Adds the config options to a var to be accessed from the rest of the system
  * If it's an old config or no config exists this will update and generate it.
  * @param  {Boolean}       whether we should print out the status of the config being loaded
  */
 public static function init($baseDir = "", $verbose = true)
 {
     // make sure a base dir was supplied
     if (empty($baseDir)) {
         Console::writeError("need a base directory to initialize the config class...");
     }
     // normalize the baseDir
     $baseDir = FileUtil::normalizePath($baseDir);
     // double-check the default config file exists
     if (!is_dir($baseDir)) {
         Console::writeError("make sure " . $baseDir . " exists...");
     }
     // set the baseDir option
     self::$options["baseDir"] = $baseDir[strlen($baseDir) - 1] == DIRECTORY_SEPARATOR ? $baseDir : $baseDir . DIRECTORY_SEPARATOR;
     // can't add __DIR__ above so adding here
     if (!self::$dirAdded) {
         // set-up the paths
         self::$userConfigDirClean = self::$options["baseDir"] . self::$userConfigDirClean;
         self::$userConfigDirDash = self::$options["baseDir"] . self::$userConfigDirDash;
         self::$userConfigDir = is_dir(self::$userConfigDirDash) ? self::$userConfigDirDash : self::$userConfigDirClean;
         self::$userConfigPath = self::$userConfigDir . DIRECTORY_SEPARATOR . self::$userConfig;
         self::$plConfigPath = self::$options["baseDir"] . "vendor/pattern-lab/core/" . self::$plConfigPath;
         self::$dirAdded = true;
         // just in case the config directory doesn't exist at all
         if (!is_dir(self::$userConfigDir)) {
             mkdir(self::$userConfigDir);
         }
     }
     // make sure migrate doesn't happen by default
     $migrate = false;
     $diffVersion = false;
     // double-check the default config file exists
     if (!file_exists(self::$plConfigPath)) {
         Console::writeError("make sure <path>" . self::$plConfigPath . "</path> exists before trying to have Pattern Lab build the config.yml file automagically...");
     }
     // set the default config using the pattern lab config
     try {
         $data = Yaml::parse(file_get_contents(self::$plConfigPath));
     } catch (ParseException $e) {
         Console::writeError("Config parse error in <path>" . self::$plConfigPath . "</path>: " . $e->getMessage());
     }
     // load the options from the default file
     self::loadOptions($data);
     // make sure these are copied
     $defaultOptions = self::$options;
     // check to see if the user config exists, if not create it
     if ($verbose) {
         Console::writeLine("configuring pattern lab...");
     }
     if (!file_exists(self::$userConfigPath)) {
         $migrate = true;
     } else {
         try {
             $data = Yaml::parse(file_get_contents(self::$userConfigPath));
         } catch (ParseException $e) {
             Console::writeError("Config parse error in <path>" . self::$userConfigPath . "</path>: " . $e->getMessage());
         }
         self::loadOptions($data);
     }
     // compare version numbers
     $diffVersion = self::$options["v"] != $defaultOptions["v"] ? true : false;
     // run an upgrade and migrations if necessary
     if ($migrate || $diffVersion) {
         if ($verbose) {
             Console::writeInfo("upgrading your version of pattern lab...");
         }
         if ($migrate) {
             if (!@copy(self::$plConfigPath, self::$userConfigPath)) {
                 Console::writeError("make sure that Pattern Lab can write a new config to " . self::$userConfigPath . "...");
                 exit;
             }
         } else {
             self::$options = self::writeNewConfigFile(self::$options, $defaultOptions);
         }
     }
     // making sure the config isn't empty
     if (empty(self::$options) && $verbose) {
         Console::writeError("a set of configuration options is required to use Pattern Lab...");
         exit;
     }
     // set-up the various dirs
     self::$options["coreDir"] = is_dir(self::$options["baseDir"] . "_core") ? self::$options["baseDir"] . "_core" : self::$options["baseDir"] . "core";
     self::$options["exportDir"] = isset(self::$options["exportDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["exportDir"]) : self::$options["baseDir"] . "exports";
     self::$options["packagesDir"] = isset(self::$options["packagesDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["packagesDir"]) : self::$options["baseDir"] . "packages";
     self::$options["publicDir"] = isset(self::$options["publicDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["publicDir"]) : self::$options["baseDir"] . "public";
     self::$options["scriptsDir"] = isset(self::$options["scriptsDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["scriptsDir"]) : self::$options["baseDir"] . "scripts";
     self::$options["sourceDir"] = isset(self::$options["sourceDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["sourceDir"]) : self::$options["baseDir"] . "source";
     self::$options["componentDir"] = self::$options["publicDir"] . "/patternlab-components";
     self::$options["dataDir"] = self::$options["sourceDir"] . "/_data";
     self::$options["patternExportDir"] = self::$options["exportDir"] . "/patterns";
     self::$options["patternPublicDir"] = self::$options["publicDir"] . "/patterns";
     self::$options["patternSourceDir"] = self::$options["sourceDir"] . "/_patterns";
     // make sure styleguideExcludes is set to an array even if it's empty
     if (is_string(self::$options["styleGuideExcludes"])) {
         self::$options["styleGuideExcludes"] = array();
     }
     // set the cacheBuster
     self::$options["cacheBuster"] = self::$options["cacheBusterOn"] == "false" ? 0 : time();
     // provide the default for enable CSS. performance hog so it should be run infrequently
     self::$options["enableCSS"] = false;
     // which of these should be exposed in the front-end?
     self::$options["exposedOptions"] = array();
     self::setExposedOption("cacheBuster");
     self::setExposedOption("ishFontSize");
     self::setExposedOption("ishMaximum");
     self::setExposedOption("ishMinimum");
 }
 /**
  * Pulls together a bunch of functions from builder.lib.php in an order that makes sense
  * @param  {Boolean}       decide if CSS should be parsed and saved. performance hog.
  * @param  {Boolean}       decide if static files like CSS and JS should be moved
  */
 public function generate($options = array())
 {
     // double-checks options was properly set
     if (empty($options)) {
         Console::writeError("need to pass options to generate...");
     }
     // set the default vars
     $moveStatic = isset($options["moveStatic"]) ? $options["moveStatic"] : true;
     $noCacheBuster = isset($options["noCacheBuster"]) ? $options["noCacheBuster"] : false;
     $exportFiles = isset($options["exportFiles"]) ? $options["exportFiles"] : false;
     $exportClean = isset($options["exportClean"]) ? $options["exportClean"] : false;
     $watchMessage = isset($options["watchMessage"]) ? $options["watchMessage"] : false;
     $watchVerbose = isset($options["watchVerbose"]) ? $options["watchVerbose"] : false;
     if ($noCacheBuster) {
         Config::setOption("cacheBuster", 0);
     }
     // gather up all of the data to be used in patterns
     Data::gather();
     // gather all of the various pattern info
     $options = array();
     $options["exportClean"] = $exportClean;
     $options["exportFiles"] = $exportFiles;
     PatternData::gather($options);
     // gather the annotations
     Annotations::gather();
     // clean the public directory to remove old files
     if (Config::getOption("cleanPublic") == "true" && $moveStatic) {
         FileUtil::cleanPublic();
     }
     // render out the index and style guide
     $this->generateIndex();
     $this->generateStyleguide();
     $this->generateViewAllPages();
     // render out the patterns and move them to public/patterns
     $options = array();
     $options["exportFiles"] = $exportFiles;
     $this->generatePatterns($options);
     // render the annotations as a js file
     $this->generateAnnotations();
     // move all of the files unless pattern only is set
     if ($moveStatic) {
         $this->moveStatic();
     }
     // update the change time so the auto-reload will fire (doesn't work for the index and style guide)
     Util::updateChangeTime();
     if ($watchVerbose && $watchMessage) {
         Console::writeLine($watchMessage);
     } else {
         Console::writeLine("your site has been generated...");
         Timer::stop();
     }
 }
 public function watchStarterKit()
 {
     // default vars
     $starterKitPath = $this->starterKitPathPrompt();
     $sourceDir = Config::getOption("sourceDir");
     $fs = new Filesystem();
     $c = false;
     // track that one loop through the pattern file listing has completed
     $o = new \stdClass();
     // create an object to hold the properties
     $cp = new \stdClass();
     // create an object to hold a clone of $o
     $o->patterns = new \stdClass();
     Console::writeLine("watching your starterkit for changes...");
     // run forever
     while (true) {
         // clone the patterns so they can be checked in case something gets deleted
         $cp = clone $o->patterns;
         $objects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($starterKitPath), \RecursiveIteratorIterator::SELF_FIRST);
         // make sure dots are skipped
         $objects->setFlags(\FilesystemIterator::SKIP_DOTS);
         foreach ($objects as $name => $object) {
             // clean-up the file name and make sure it's not one of the pattern lab files or to be ignored
             $fileName = str_replace($starterKitPath . DIRECTORY_SEPARATOR, "", $name);
             // check to see if it's a new directory
             if ($object->isDir() && !isset($o->{$fileName}) && !is_dir($starterKitPath . "/" . $fileName)) {
                 mkdir($sourceDir . "/" . $fileName);
                 $o->{$fileName} = "dir created";
                 // placeholder
                 Console::writeLine($fileName . "/ directory was created...");
             }
             // check to see if it's a new file or a file that has changed
             if (file_exists($name)) {
                 $mt = $object->getMTime();
                 if ($object->isFile() && !isset($o->{$fileName}) && !file_exists($sourceDir . DIRECTORY_SEPARATOR . $fileName)) {
                     $o->{$fileName} = $mt;
                     $fs->copy($starterKitPath . DIRECTORY_SEPARATOR . $fileName, $sourceDir . DIRECTORY_SEPARATOR . $fileName);
                     Console::writeInfo($fileName . " added...");
                 } else {
                     if ($object->isFile() && isset($o->{$fileName}) && $o->{$fileName} != $mt) {
                         $o->{$fileName} = $mt;
                         $fs->copy($starterKitPath . DIRECTORY_SEPARATOR . $fileName, $sourceDir . DIRECTORY_SEPARATOR . $fileName);
                         Console::writeInfo($fileName . " changed...");
                     } else {
                         if (!isset($o->fileName)) {
                             $o->{$fileName} = $mt;
                         }
                     }
                 }
             } else {
                 unset($o->{$fileName});
             }
         }
         $c = true;
         // taking out the garbage. basically killing mustache after each run.
         if (gc_enabled()) {
             gc_collect_cycles();
         }
         // pause for .05 seconds to give the CPU a rest
         usleep(50000);
     }
 }
 /**
  * Randomly prints a saying after the generate is complete
  */
 public function printSaying()
 {
     $randomNumber = rand(0, 3);
     $colors = array("ok", "options", "info", "warning", "error");
     $color = isset($colors[$randomNumber]) ? $colors[$randomNumber] : "desc";
     $randomNumber = rand(0, 60);
     $sayings = array("have fun storming the castle", "be well, do good work, and keep in touch", "may the sun shine, all day long", "smile :)", "namaste", "walk as if you are kissing the earth with your feet", "to be beautiful means to be yourself", "i was thinking of the immortal words of socrates, who said '...i drank what?'", "let me take this moment to compliment you on your fashion sense, particularly your slippers", "42", "he who controls the spice controls the universe", "the greatest thing you'll ever learn is just to love and be loved in return", "nice wand", "i don't have time for a grudge match with every poseur in a parka", "han shot first", "what we've got here is a failure to communicate", "mama always said life was like a box of chocolates. you never know what you're gonna get", "soylent green is people", "a little word of advice, my friend. sometimes you gotta let those hard-to-reach chips go", "you don't understand! i coulda had class. i coulda been a contender. i could've been somebody, instead of a bum, which is what i am", "shop smart. shop s-mart", "i see dead people", "well, nobody's perfect", "it's alive! it's alive!", "you've got to ask yourself one question: 'do I feel lucky?' well, do ya, punk?", "badges? we ain't got no badges! we don't need no badges! i don't have to show you any stinking badges!", "the holy roman empire was neither holy nor roman. discuss.", "well, here's another nice mess you've gotten me into!", "here's johnny!", "hello, gorgeous", "nobody puts baby in a corner", "life moves pretty fast. if you don't stop and look around once in a while, you could miss it", "my precious", "be yourself; everyone else is already taken", "the ships hung in the sky in much the same way that bricks don't", "klaatu barada nikto", "i am putting myself to the fullest possible use, which is all i think that any conscious entity can ever hope to do", "just what do you think you're doing, dave?", "do what i do. hold tight and pretend it's a plan!", "(╯°□°)╯︵ ┻━┻", "¸.·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º>", "@}~}~~~", "(>'.')> (>'.')> (>'.')> ", "\\(^-^)/", "you've been at this awhile; perhaps it's time for a walk outside?");
     if (isset($sayings[$randomNumber])) {
         Console::writeLine("<" . $color . ">" . $sayings[$randomNumber] . "...</" . $color . ">");
     }
 }
 /**
  * Write out the given options. Check to see if it's a nested sequential or associative array
  * @param  {Mixed}       the options to check and write out
  * @param  {String}      copy to be added to the beginning of the option if nested
  */
 private function writeOutOptions($options, $pre = "")
 {
     foreach ($options as $optionName => $optionValue) {
         if (is_array($optionValue) && count($optionValue) > 0 && !isset($optionValue[0])) {
             $this->writeOutOptions($optionValue, $optionName . ".");
         } else {
             $optionValue = is_array($optionValue) && isset($optionValue[0]) ? implode(", ", $optionValue) : $optionValue;
             $optionValue = !$optionValue ? "false" : $optionValue;
             $spacer = Console::getSpacer($this->lengthLong, strlen($pre . $optionName));
             Console::writeLine("<info>" . $pre . $optionName . ":</info>" . $spacer . $optionValue);
         }
     }
 }
 /**
  * Ask questions after the create package is done
  * @param  {Object}     a script event object from composer
  */
 public static function postCreateProjectCmd($event)
 {
     // see if there is an extra component
     $extra = $event->getComposer()->getPackage()->getExtra();
     if (isset($extra["patternlab"])) {
         self::init();
         Console::writeLine("");
         // see if we have any starterkits to suggest
         if (isset($extra["patternlab"]["starterKitSuggestions"]) && is_array($extra["patternlab"]["starterKitSuggestions"])) {
             $suggestions = $extra["patternlab"]["starterKitSuggestions"];
             // suggest starterkits
             Console::writeInfo("suggested starterkits that work with this edition:", false, true);
             foreach ($suggestions as $i => $suggestion) {
                 // write each suggestion
                 $num = $i + 1;
                 Console::writeLine($num . ": " . $suggestion, true);
             }
             // prompt for input on the suggestions
             Console::writeLine("");
             $prompt = "choose an option or hit return to skip:";
             $options = "(ex. 1)";
             $input = Console::promptInput($prompt, $options);
             $result = (int) $input - 1;
             if (isset($suggestions[$result])) {
                 Console::writeLine("");
                 $f = new Fetch();
                 $result = $f->fetchStarterKit($suggestions[$result]);
                 if ($result) {
                     Console::writeLine("");
                     $g = new Generator();
                     $g->generate(array("foo" => "bar"));
                     Console::writeLine("");
                     Console::writeInfo("type <desc>php core/console --server</desc> to start the built-in server and see Pattern Lab...", false, true);
                 }
             } else {
                 Console::writeWarning("you will need to install a StarterKit before using Pattern Lab...");
             }
         }
     }
 }
 /**
  * Handle some Pattern Lab specific tasks based on what's found in the package's composer.json file on install
  * @param  {Array}      the info culled from installing various pattern lab-related packages
  */
 protected static function packagesInstall($installerInfo, $event)
 {
     // mark if this is an interactive call or not
     self::$isInteractive = $event->getIO()->isInteractive();
     // initialize a bunch of stuff like config and console
     self::init();
     // reorder packages so the starterkit is first if it's being installed as a package
     if (isset($installerInfo["packages"])) {
         $packages = $installerInfo["packages"];
         $packages = array_merge(array_filter($packages, "self::includeStarterKit"), array_filter($packages, "self::excludeStarterKit"));
         foreach ($packages as $package) {
             // set-up package info
             $extra = $package["extra"];
             $type = $package["type"];
             $name = $package["name"];
             $pathBase = $package["pathBase"];
             $pathDist = $package["pathDist"];
             // make sure that it has the name-spaced section of data to be parsed. if it exists parse it
             if (!empty($extra)) {
                 self::parseComposerExtraList($extra, $name, $pathDist);
             }
             // see if the package has a listener
             self::scanForListener($pathBase);
             // address other specific needs based on type
             if ($type == "patternlab-patternengine") {
                 self::scanForPatternEngineRule($pathBase);
             } else {
                 if ($type == "patternlab-styleguidekit" && strpos($name, "-assets-") === false) {
                     $dir = str_replace(Config::getOption("baseDir"), "", $pathBase);
                     $dir = $dir[strlen($dir) - 1] == DIRECTORY_SEPARATOR ? rtrim($dir, DIRECTORY_SEPARATOR) : $dir;
                     Config::updateConfigOption("styleguideKit", $name);
                     Config::updateConfigOption("styleguideKitPath", $dir);
                 }
             }
         }
     }
     // make sure user is prompted to install starterkit
     if (!empty($installerInfo["suggestedStarterKits"])) {
         self::promptStarterKitInstall($installerInfo["suggestedStarterKits"]);
     }
     // override any configs that have been set-up
     if (!empty($installerInfo["configOverrides"])) {
         foreach ($installerInfo["configOverrides"] as $option => $value) {
             Config::updateConfigOption($option, $value, true);
             // forces the update
         }
     }
     if ($installerInfo["projectInstall"]) {
         Console::writeLine("");
         Console::writeLine("<h1><fire3>Thank you for installing...</fire3></h1>", false, true);
         Console::writeLine("<fire1>(                               (             </fire1>");
         Console::writeLine("<fire2>)\\ )        )   )               )\\ )         )</fire2>");
         Console::writeLine("<fire3>(()/(   ) ( /(( /(  (  (        (()/(    ) ( /(</fire3>");
         Console::writeLine("<fire4>/(_)| /( )\\())\\())))\\ )(   (    /(_))( /( )\\())</fire4>");
         Console::writeLine("<fire5>(</fire5><cool>_</cool><fire5>)) )(_)|</fire5><cool>_</cool><fire5>))(</fire5><cool>_</cool><fire5>))//((_|()\\  )\\ )(</fire5><cool>_</cool><fire5>))  )(_)|(_)\\</fire5>");
         Console::writeLine("<cool>| _ </cool><fire6>((</fire6><cool>_</cool><fire6>)</fire6><cool>_| |_| |_</cool><fire6>(</fire6><cool>_</cool><fire6>))  ((</fire6><cool>_</cool><fire6>)</fire6><cool>_</cool><fire6>(</fire6><cool>_</cool><fire6>/(</fire6><cool>| |  </cool><fire6>((</fire6><cool>_</cool><fire6>)</fire6><cool>_| |</cool><fire6>(</fire6><cool>_</cool><fire6>)</fire6>");
         Console::writeLine("<cool>|  _/ _` |  _|  _/ -_)| '_| ' \\</cool><fire6>))</fire6><cool> |__/ _` | '_ \\  </cool>");
         Console::writeLine("<cool>|_| \\__,_|\\__|\\__\\___||_| |_||_||____\\__,_|_.__/  </cool>", false, true);
     }
 }
Beispiel #14
0
 /**
  * Adds the config options to a var to be accessed from the rest of the system
  * If it's an old config or no config exists this will update and generate it.
  * @param  {Boolean}       whether we should print out the status of the config being loaded
  */
 public static function init($baseDir = "", $verbose = true)
 {
     // make sure a base dir was supplied
     if (empty($baseDir)) {
         Console::writeError("need a base directory to initialize the config class...");
     }
     // normalize the baseDir
     $baseDir = FileUtil::normalizePath($baseDir);
     // double-check the default config file exists
     if (!is_dir($baseDir)) {
         Console::writeError("make sure " . $baseDir . " exists...");
     }
     // set the baseDir option
     self::$options["baseDir"] = $baseDir[strlen($baseDir) - 1] == DIRECTORY_SEPARATOR ? $baseDir : $baseDir . DIRECTORY_SEPARATOR;
     // set-up the paths
     self::$userConfigDirClean = self::$options["baseDir"] . self::$userConfigDirClean;
     self::$userConfigDirDash = self::$options["baseDir"] . self::$userConfigDirDash;
     self::$userConfigDir = is_dir(self::$userConfigDirDash) ? self::$userConfigDirDash : self::$userConfigDirClean;
     self::$userConfigPath = self::$userConfigDir . DIRECTORY_SEPARATOR . self::$userConfig;
     self::$plConfigPath = self::$options["baseDir"] . "vendor/pattern-lab/core/" . self::$plConfigPath;
     // can't add __DIR__ above so adding here
     if (!is_dir(self::$userConfigDir)) {
         mkdir(self::$userConfigDir);
     }
     // check to see if the user config exists, if not create it
     if ($verbose) {
         Console::writeLine("configuring pattern lab...");
     }
     // make sure migrate doesn't happen by default
     $migrate = false;
     $diffVersion = false;
     $defaultOptions = array();
     $userOptions = array();
     // double-check the default config file exists
     if (!file_exists(self::$plConfigPath)) {
         Console::writeError("the default options for Pattern Lab don't seem to exist at <path>" . Console::getHumanReadablePath(self::$plConfigPath) . "</path>. please check on the install location of pattern lab...");
     }
     // set the default config using the pattern lab config
     try {
         $defaultOptions = Yaml::parse(file_get_contents(self::$plConfigPath));
         self::$options = array_merge(self::$options, $defaultOptions);
     } catch (ParseException $e) {
         Console::writeError("Config parse error in <path>" . Console::getHumanReadablePath(self::$plConfigPath) . "</path>: " . $e->getMessage());
     }
     // double-check the user's config exists. if not mark that we should migrate the default one
     if (file_exists(self::$userConfigPath)) {
         try {
             $userOptions = Yaml::parse(file_get_contents(self::$userConfigPath));
             self::$options = array_merge(self::$options, $userOptions);
         } catch (ParseException $e) {
             Console::writeError("Config parse error in <path>" . Console::getHumanReadablePath(self::$userConfigPath) . "</path>: " . $e->getMessage());
         }
     } else {
         $migrate = true;
     }
     // compare version numbers
     $diffVersion = isset($userOptions["v"]) && $userOptions["v"] == $defaultOptions["v"] ? false : true;
     // run an upgrade and migrations if necessary
     if ($migrate || $diffVersion) {
         if ($verbose) {
             Console::writeInfo("upgrading your version of pattern lab...");
         }
         if ($migrate) {
             if (!@copy(self::$plConfigPath, self::$userConfigPath)) {
                 Console::writeError("make sure that Pattern Lab can write a new config to " . self::$userConfigPath . "...");
                 exit;
             }
         } else {
             self::$options = self::writeNewConfigFile(self::$options, $defaultOptions);
         }
     }
     // making sure the config isn't empty
     if (empty(self::$options) && $verbose) {
         Console::writeError("a set of configuration options is required to use Pattern Lab...");
         exit;
     }
     // set-up the various dirs
     self::$options["configDir"] = self::$userConfigDir;
     self::$options["configPath"] = self::$userConfigPath;
     self::$options["coreDir"] = is_dir(self::$options["baseDir"] . "_core") ? self::$options["baseDir"] . "_core" : self::$options["baseDir"] . "core";
     self::$options["exportDir"] = isset(self::$options["exportDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["exportDir"]) : self::$options["baseDir"] . "exports";
     self::$options["publicDir"] = isset(self::$options["publicDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["publicDir"]) : self::$options["baseDir"] . "public";
     self::$options["scriptsDir"] = isset(self::$options["scriptsDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["scriptsDir"]) : self::$options["baseDir"] . "scripts";
     self::$options["sourceDir"] = isset(self::$options["sourceDir"]) ? self::$options["baseDir"] . self::cleanDir(self::$options["sourceDir"]) : self::$options["baseDir"] . "source";
     self::$options["componentDir"] = isset(self::$options["componentDir"]) ? self::$options["publicDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["componentDir"]) : self::$options["publicDir"] . DIRECTORY_SEPARATOR . "patternlab-components";
     self::$options["dataDir"] = isset(self::$options["dataDir"]) ? self::$options["sourceDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["dataDir"]) : self::$options["sourceDir"] . DIRECTORY_SEPARATOR . "_data";
     self::$options["patternExportDir"] = isset(self::$options["patternExportDir"]) ? self::$options["exportDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["patternExportDir"]) : self::$options["exportDir"] . DIRECTORY_SEPARATOR . "patterns";
     self::$options["patternPublicDir"] = isset(self::$options["patternPublicDir"]) ? self::$options["publicDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["patternPublicDir"]) : self::$options["publicDir"] . DIRECTORY_SEPARATOR . "patterns";
     self::$options["patternSourceDir"] = isset(self::$options["patternSourceDir"]) ? self::$options["sourceDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["patternSourceDir"]) : self::$options["sourceDir"] . DIRECTORY_SEPARATOR . "_patterns";
     self::$options["metaDir"] = isset(self::$options["metaDir"]) ? self::$options["sourceDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["metaDir"]) : self::$options["sourceDir"] . DIRECTORY_SEPARATOR . "_meta/";
     self::$options["annotationsDir"] = isset(self::$options["annotationsDir"]) ? self::$options["sourceDir"] . DIRECTORY_SEPARATOR . self::cleanDir(self::$options["annotationsDir"]) : self::$options["sourceDir"] . DIRECTORY_SEPARATOR . "_annotations/";
     // set-up outputFileSuffixes
     self::$options["outputFileSuffixes"]["rendered"] = isset(self::$options["outputFileSuffixes"]["rendered"]) ? self::$options["outputFileSuffixes"]["rendered"] : '';
     self::$options["outputFileSuffixes"]["rawTemplate"] = isset(self::$options["outputFileSuffixes"]["rawTemplate"]) ? self::$options["outputFileSuffixes"]["rawTemplate"] : '';
     self::$options["outputFileSuffixes"]["markupOnly"] = isset(self::$options["outputFileSuffixes"]["markupOnly"]) ? self::$options["outputFileSuffixes"]["markupOnly"] : '.markup-only';
     // handle a pre-2.1.0 styleguideKitPath before saving it
     if (isset(self::$options["styleguideKitPath"])) {
         self::$options["styleguideKitPath"] = self::$options["baseDir"] . self::cleanDir(self::getStyleguideKitPath(self::$options["styleguideKitPath"]));
     }
     // double-check a few directories are real and set-up
     FileUtil::checkPathFromConfig(self::$options["sourceDir"], self::$userConfigPath, "sourceDir");
     FileUtil::checkPathFromConfig(self::$options["publicDir"], self::$userConfigPath, "publicDir");
     // make sure styleguideExcludes is set to an array even if it's empty
     if (is_string(self::$options["styleGuideExcludes"])) {
         self::$options["styleGuideExcludes"] = array();
     }
     // set the cacheBuster
     self::$options["cacheBuster"] = self::$options["cacheBusterOn"] == "false" ? 0 : time();
     // provide the default for enable CSS. performance hog so it should be run infrequently
     self::$options["enableCSS"] = false;
     // which of these should be exposed in the front-end?
     self::$options["exposedOptions"] = array();
     self::setExposedOption("cacheBuster");
     self::setExposedOption("defaultPattern");
     self::setExposedOption("defaultShowPatternInfo");
     self::setExposedOption("ishFontSize");
     self::setExposedOption("ishMaximum");
     self::setExposedOption("ishMinimum");
     self::setExposedOption("outputFileSuffixes");
     self::setExposedOption("plugins");
 }