public function run()
 {
     if (version_compare(phpversion(), '5.4.0', '<')) {
         Console::writeWarning("you must have PHP 5.4.0 or greater to use this feature. you are using PHP " . phpversion() . "...");
     } else {
         // set-up defaults
         $publicDir = Config::getOption("publicDir");
         $coreDir = Config::getOption("coreDir");
         $host = Console::findCommandOptionValue("host");
         $host = $host ? $host : "localhost";
         $port = Console::findCommandOptionValue("port");
         $host = $port ? $host . ":" . $port : $host . ":8080";
         $quiet = Console::findCommandOption("quiet");
         // set-up the base command
         $command = $this->pathPHP . " -S " . $host . " " . $coreDir . "/server/router.php";
         $commands = array();
         $commands[] = array("command" => $command, "cwd" => $publicDir, "timeout" => null, "idle" => 1800);
         // get the watch command info
         if (Console::findCommandOption("with-watch")) {
             $watchCommand = new WatchCommand();
             $commands[] = array("command" => $watchCommand->build() . " --no-procs", "timeout" => null, "idle" => 1800);
         }
         Console::writeInfo("server started on http://" . $host . " - use ctrl+c to exit...");
         $processSpawner = new ProcessSpawner();
         $processSpawner->spawn($commands, $quiet);
     }
 }
 /**
  * Check that a dir from the config exists and try to build it if needed
  * @param  {String}       directory to be checked/built
  * @param  {String}       the config path
  * @param  {String}       the config option that would help them
  */
 public static function checkPathFromConfig($path, $configPath, $configOption = "")
 {
     if (!isset($path)) {
         Console::writeError("please make sure " . $configOption . " is set in <path>" . Console::getHumanReadablePath($configPath) . "</path> by adding '" . $configOption . "=some/path'. sorry, stopping pattern lab... :(");
     } else {
         if (!is_dir($path)) {
             Console::writeWarning("i can't seem to find the directory <path>" . Console::getHumanReadablePath($path) . "</path>...");
             self::makeDir($path);
             Console::writeWarning("i created <path>" . Console::getHumanReadablePath($path) . "</path> just in case. you can edit this in <path>" . Console::getHumanReadablePath($configPath) . "</path> by editing " . $configOption . "...");
         }
     }
 }
 public function run()
 {
     if (version_compare(phpversion(), '5.4.0', '<')) {
         Console::writeWarning("you must have PHP 5.4.0 or greater to use this feature. you are using PHP " . phpversion() . "...");
     } else {
         // set-up defaults
         $publicDir = Config::getOption("publicDir");
         $coreDir = Config::getOption("coreDir");
         // start-up the server with the router
         Console::writeInfo("server started on localhost:8080. use ctrl+c to exit...");
         passthru("cd " . $publicDir . " && " . $_SERVER["_"] . " -S localhost:8080 " . $coreDir . "/server/router.php");
     }
 }
 /**
  * Gather data from annotations.js and *.md files found in source/_annotations
  *
  * @return {Array}        populates Annotations::$store
  */
 public static function gather()
 {
     // set-up default var
     $sourceDir = Config::getOption("sourceDir");
     // set-up the dispatcher
     $dispatcherInstance = Dispatcher::getInstance();
     // dispatch that the data gather has started
     $dispatcherInstance->dispatch("annotations.gatherStart");
     // set-up the comments store
     self::$store["comments"] = array();
     // iterate over all of the files in the annotations dir
     if (!is_dir($sourceDir . "/_annotations")) {
         Console::writeWarning("<path>_annotations/</path><warning> doesn't exist so you won't have annotations...");
         mkdir($sourceDir . "/_annotations");
     }
     // find the markdown-based annotations
     $finder = new Finder();
     $finder->files()->name("*.md")->in($sourceDir . "/_annotations");
     $finder->sortByName();
     foreach ($finder as $name => $file) {
         $data = array();
         $data[0] = array();
         $text = file_get_contents($file->getPathname());
         $matches = strpos($text, PHP_EOL . "~*~" . PHP_EOL) !== false ? explode(PHP_EOL . "~*~" . PHP_EOL, $text) : array($text);
         foreach ($matches as $match) {
             list($yaml, $markdown) = Documentation::parse($match);
             if (isset($yaml["el"]) || isset($yaml["selector"])) {
                 $data[0]["el"] = isset($yaml["el"]) ? $yaml["el"] : $yaml["selector"];
             } else {
                 $data[0]["el"] = "#someimpossibleselector";
             }
             $data[0]["title"] = isset($yaml["title"]) ? $yaml["title"] : "";
             $data[0]["comment"] = $markdown;
             self::$store["comments"] = array_merge(self::$store["comments"], $data);
         }
     }
     // read in the old style annotations.js, modify the data and generate JSON array to merge
     if (file_exists($sourceDir . "/_annotations/annotations.js")) {
         $text = file_get_contents($sourceDir . "/_annotations/annotations.js");
         $text = str_replace("var comments = ", "", $text);
         $text = rtrim($text, ";");
         $data = json_decode($text, true);
         if ($jsonErrorMessage = JSON::hasError()) {
             JSON::lastErrorMsg("_annotations/annotations.js", $jsonErrorMessage, $data);
         }
     }
     // merge in any data from the old file
     self::$store["comments"] = array_merge(self::$store["comments"], $data["comments"]);
     $dispatcherInstance->dispatch("annotations.gatherEnd");
 }
 public function run()
 {
     // load default vars
     $patternExtension = Config::getOption("patternExtension");
     $patternSourceDir = Config::getOption("patternSourceDir");
     // load the pattern data
     $store = PatternData::get();
     // iterate to get raw data loaded into the PatternData Store
     foreach ($store as $patternStoreKey => $patternStoreData) {
         if ($patternStoreData["category"] == "pattern" && isset($patternStoreData["name"])) {
             // figure out the source path for the pattern to render
             $srcPath = isset($patternStoreData["pseudo"]) ? PatternData::getPatternOption($patternStoreData["original"], "pathName") : $patternStoreData["pathName"];
             // load the raw data so it can be modified/rendered
             $path = $patternSourceDir . DIRECTORY_SEPARATOR . $srcPath . "." . $patternExtension;
             if (file_exists($path)) {
                 PatternData::setPatternOption($patternStoreKey, "patternRaw", file_get_contents($path));
             } else {
                 Console::writeWarning($patternStoreData["partial"] . " wasn't found for loading. the given path: " . $path);
             }
         }
     }
 }
 public function run()
 {
     // set-up default vars
     $foundLineages = array();
     $patternSourceDir = Config::getOption("patternSourceDir");
     $patternExtension = Config::getOption("patternExtension");
     // check for the regular lineages in only normal patterns
     $store = PatternData::get();
     foreach ($store as $patternStoreKey => $patternStoreData) {
         if ($patternStoreData["category"] == "pattern" && !isset($patternStoreData["pseudo"])) {
             $patternLineages = array();
             $fileData = isset($patternStoreData["patternRaw"]) ? $patternStoreData["patternRaw"] : "";
             $foundLineages = $this->findLineages($fileData);
             if (!empty($foundLineages)) {
                 foreach ($foundLineages as $lineage) {
                     $lineageData = PatternData::getOption($lineage);
                     if ($lineageData) {
                         $patternLineages[] = array("lineagePattern" => $lineage, "lineagePath" => "../../patterns/" . $lineageData["pathDash"] . "/" . $lineageData["pathDash"] . ".html");
                     } else {
                         if (strpos($lineage, '/') === false) {
                             $fileName = $patternStoreData["pathName"] . "." . $patternExtension;
                             Console::writeWarning("you may have a typo in " . $fileName . ". {{> " . $lineage . " }} is not a valid pattern...");
                         }
                     }
                 }
                 // add the lineages to the PatternData::$store
                 PatternData::setPatternOption($patternStoreKey, "lineages", $patternLineages);
             }
         }
     }
     // handle all of those pseudo patterns
     $store = PatternData::get();
     foreach ($store as $patternStoreKey => $patternStoreData) {
         if ($patternStoreData["category"] == "pattern" && isset($patternStoreData["pseudo"])) {
             // add the lineages to the PatternData::$store
             $patternStoreKeyOriginal = $patternStoreData["original"];
             PatternData::setPatternOption($patternStoreKey, "lineages", PatternData::getPatternOption($patternStoreKeyOriginal, "lineages"));
         }
     }
     // check for the reverse lineages and skip pseudo patterns
     $store = PatternData::get();
     foreach ($store as $patternStoreKey => $patternStoreData) {
         if ($patternStoreData["category"] == "pattern" && !isset($patternStoreData["pseudo"])) {
             $patternLineagesR = array();
             $storeTake2 = PatternData::get();
             foreach ($storeTake2 as $haystackKey => $haystackData) {
                 if ($haystackData["category"] == "pattern" && isset($haystackData["lineages"]) && !empty($haystackData["lineages"])) {
                     foreach ($haystackData["lineages"] as $haystackLineage) {
                         if ($haystackLineage["lineagePattern"] == $patternStoreData["partial"]) {
                             $foundAlready = false;
                             foreach ($patternLineagesR as $patternCheck) {
                                 if ($patternCheck["lineagePattern"] == $patternStoreData["partial"]) {
                                     $foundAlready = true;
                                     break;
                                 }
                             }
                             if (!$foundAlready) {
                                 if (PatternData::getOption($haystackKey)) {
                                     $path = PatternData::getPatternOption($haystackKey, "pathDash");
                                     $patternLineagesR[] = array("lineagePattern" => $haystackKey, "lineagePath" => "../../patterns/" . $path . "/" . $path . ".html");
                                 }
                             }
                         }
                     }
                 }
             }
             PatternData::setPatternOption($patternStoreKey, "lineagesR", $patternLineagesR);
         }
     }
     // handle all of those pseudo patterns
     $store = PatternData::get();
     foreach ($store as $patternStoreKey => $patternStoreData) {
         if ($patternStoreData["category"] == "pattern" && isset($patternStoreData["pseudo"])) {
             // add the lineages to the PatternData::$store
             $patternStoreKeyOriginal = $patternStoreData["original"];
             PatternData::setPatternOption($patternStoreKey, "lineagesR", PatternData::getPatternOption($patternStoreKeyOriginal, "lineagesR"));
         }
     }
 }
 /**
  * Update a single config option based on a change in composer.json
  * @param  {String}       the name of the option to be changed
  * @param  {String}       the new value of the option to be changed
  */
 public static function updateConfigOption($optionName, $optionValue)
 {
     if (is_string($optionValue) && strpos($optionValue, "<prompt>") !== false) {
         // prompt for input using the supplied query
         $prompt = str_replace("</prompt>", "", str_replace("<prompt>", "", $optionValue));
         $options = "";
         $input = Console::promptInput($prompt, $options, false);
         self::writeUpdateConfigOption($optionName, $input);
         Console::writeTag("ok", "config option " . $optionName . " updated...", false, true);
     } else {
         if (!isset(self::$options[$optionName]) || self::$options["overrideConfig"] == "a") {
             // if the option isn't set or the config is always to override update the config
             self::writeUpdateConfigOption($optionName, $optionValue);
         } else {
             if (self::$options["overrideConfig"] == "q") {
                 // standardize the values for comparison
                 $currentOptionValue = is_array(self::$options[$optionName]) ? implode(", ", self::$options[$optionName]) : self::$options[$optionName];
                 $newOptionValue = is_array($optionValue) ? implode(", ", $optionValue) : $optionValue;
                 if ($currentOptionValue != $newOptionValue) {
                     // prompt for input
                     $prompt = "update the config option <desc>" . $optionName . " (" . $currentOptionValue . ")</desc> with the value <desc>" . $newOptionValue . "</desc>?";
                     $options = "Y/n";
                     $input = Console::promptInput($prompt, $options);
                     if ($input == "y") {
                         self::writeUpdateConfigOption($optionName, $optionValue);
                         Console::writeInfo("config option " . $optionName . " updated...", false, true);
                     } else {
                         Console::writeWarning("config option <desc>" . $optionName . "</desc> not  updated...", false, true);
                     }
                 }
             }
         }
     }
 }
Beispiel #8
0
 /**
  * Gather data from any JSON and YAML files in source/_data
  *
  * Reserved attributes:
  *    - Data::$store["listItems"] : listItems from listitems.json, duplicated into separate arrays for Data::$store["listItems"]["one"], Data::$store["listItems"]["two"]... etc.
  *    - Data::$store["link"] : the links to each pattern
  *    - Data::$store["cacheBuster"] : the cache buster value to be appended to URLs
  *    - Data::$store["patternSpecific"] : holds attributes from the pattern-specific data files
  *
  * @return {Array}        populates Data::$store
  */
 public static function gather($options = array())
 {
     // set-up the dispatcher
     $dispatcherInstance = Dispatcher::getInstance();
     // dispatch that the data gather has started
     $dispatcherInstance->dispatch("data.gatherStart");
     // default vars
     $found = false;
     $dataJSON = array();
     $dataYAML = array();
     $listItemsJSON = array();
     $listItemsYAML = array();
     $sourceDir = Config::getOption("sourceDir");
     // iterate over all of the other files in the source directory
     if (!is_dir($sourceDir . "/_data/")) {
         Console::writeWarning("<path>_data/</path> doesn't exist so you won't have dynamic data...");
         mkdir($sourceDir . "/_data/");
     }
     // find the markdown-based annotations
     $finder = new Finder();
     $finder->files()->in($sourceDir . "/_data/");
     $finder->sortByName();
     foreach ($finder as $name => $file) {
         $ext = $file->getExtension();
         $data = array();
         $fileName = $file->getFilename();
         $hidden = $fileName[0] == "_";
         $isListItems = strpos($fileName, "listitems");
         $pathName = $file->getPathname();
         $pathNameClean = str_replace($sourceDir . "/", "", $pathName);
         if (!$hidden && ($ext == "json" || $ext == "yaml")) {
             if ($isListItems === false) {
                 if ($ext == "json") {
                     $file = file_get_contents($pathName);
                     $data = json_decode($file, true);
                     if ($jsonErrorMessage = JSON::hasError()) {
                         JSON::lastErrorMsg($pathNameClean, $jsonErrorMessage, $data);
                     }
                 } else {
                     if ($ext == "yaml") {
                         $file = file_get_contents($pathName);
                         try {
                             $data = YAML::parse($file);
                         } catch (ParseException $e) {
                             printf("unable to parse " . $pathNameClean . ": %s..\n", $e->getMessage());
                         }
                         // single line of text won't throw a YAML error. returns as string
                         if (gettype($data) == "string") {
                             $data = array();
                         }
                     }
                 }
                 if (is_array($data)) {
                     self::$store = array_replace_recursive(self::$store, $data);
                 }
             } else {
                 if ($isListItems !== false) {
                     $data = $ext == "json" ? self::getListItems("_data/" . $fileName) : self::getListItems("_data/" . $fileName, "yaml");
                     if (!isset(self::$store["listItems"])) {
                         self::$store["listItems"] = array();
                     }
                     self::$store["listItems"] = array_replace_recursive(self::$store["listItems"], $data);
                 }
             }
         }
     }
     if (is_array(self::$store)) {
         foreach (self::$reservedKeys as $reservedKey) {
             if (array_key_exists($reservedKey, self::$store)) {
                 Console::writeWarning("\"" . $reservedKey . "\" is a reserved key in Pattern Lab. the data using that key will be overwritten. please choose a new key...");
             }
         }
     }
     self::$store["cacheBuster"] = Config::getOption("cacheBuster");
     self::$store["link"] = array();
     self::$store["patternSpecific"] = array();
     $dispatcherInstance->dispatch("data.gatherEnd");
 }
 protected function starterKitPathPrompt()
 {
     // need to figure this out long-term
     InstallerUtil::$isInteractive = true;
     $input = Console::promptInput("Tell me the path to the starterkit you want to watch.", "e.g. vendor/pattern-lab/starterkit-mustache-demo/dist", "baz", false);
     // set-up the full starterkit path
     $starterKitPath = Config::getOption("baseDir") . $input;
     if (!is_dir($starterKitPath)) {
         Console::writeWarning("that doesn't seem to be a real directory. let's try again...");
         $starterKitPath = $this->starterKitPathPrompt();
     }
     return $starterKitPath;
 }
 /**
  * Write a warning if a dir doesn't exist
  * @param  {String}         the dir that doesn't exist
  */
 protected static function dirNotExist($dir)
 {
     $dirHR = Console::getHumanReadablePath($dir);
     Console::writeWarning("the path <path>" . $dirHR . "</path> doesn't exist so filters won't be loaded...");
 }
 /**
  * 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...");
             }
         }
     }
 }
 /**
  * Check to see if the path already exists. If it does prompt the user to double-check it should be overwritten
  * @param  {String}    the package name
  * @param  {String}    path to be checked
  *
  * @return {Boolean}   if the path exists and should be overwritten
  */
 protected static function pathExists($packageName, $path)
 {
     $fs = new Filesystem();
     if ($fs->exists($path)) {
         // set-up a human readable prompt
         $humanReadablePath = str_replace(Config::getOption("baseDir"), "./", $path);
         // set if the prompt should fire
         $prompt = true;
         // are we checking a directory?
         if (is_dir($path)) {
             // see if the directory is essentially empty
             $files = scandir($path);
             foreach ($files as $key => $file) {
                 $ignore = array("..", ".", ".gitkeep", "README", ".DS_Store", "patternlab-components");
                 $file = explode("/", $file);
                 if (in_array($file[count($file) - 1], $ignore)) {
                     unset($files[$key]);
                 }
             }
             if (empty($files)) {
                 $prompt = false;
             }
         }
         if ($prompt) {
             // prompt for input using the supplied query
             $prompt = "the path <path>" . $humanReadablePath . "</path> already exists. merge or replace with the contents of <path>" . $packageName . "</path> package?";
             $options = "M/r";
             $input = Console::promptInput($prompt, $options, "M");
             if ($input == "m") {
                 Console::writeTag("ok", "contents of <path>" . $humanReadablePath . "</path> have been merged with the package's content...", false, true);
                 return false;
             } else {
                 Console::writeWarning("contents of <path>" . $humanReadablePath . "</path> have been replaced by the package's content...", false, true);
                 return true;
             }
         }
         return false;
     }
     return false;
 }
 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);
     }
 }
Beispiel #14
0
 /**
  * Update a single config option based on a change in composer.json
  * @param  {String}       the name of the option to be changed
  * @param  {String}       the new value of the option to be changed
  * @param  {Boolean}      whether to force the update of the option
  */
 public static function updateConfigOption($optionName, $optionValue, $force = false)
 {
     if (is_string($optionValue) && strpos($optionValue, "<prompt>") !== false) {
         // prompt for input using the supplied query
         $options = "";
         $default = "";
         $prompt = str_replace("</prompt>", "", str_replace("<prompt>", "", $optionValue));
         if (strpos($prompt, "<default>") !== false) {
             $default = explode("<default>", $prompt);
             $default = explode("</default>", $default[1]);
             $default = $default[0];
         }
         $input = Console::promptInput($prompt, $options, $default, false);
         self::writeUpdateConfigOption($optionName, $input);
         Console::writeTag("ok", "config option " . $optionName . " updated...", false, true);
     } else {
         if (!isset(self::$options[$optionName]) || self::$options["overrideConfig"] == "a" || $force) {
             // if the option isn't set or the config is always to override update the config
             self::writeUpdateConfigOption($optionName, $optionValue);
         } else {
             if (self::$options["overrideConfig"] == "q") {
                 // standardize the values for comparison
                 $currentOption = self::getOption($optionName);
                 $currentOptionValue = $currentOption;
                 $newOptionValue = $optionValue;
                 $optionNameOutput = $optionName;
                 // dive into plugins to do a proper comparison to
                 if ($optionName == "plugins") {
                     // replace the data in anticipation of it being used
                     $optionValue = array_replace_recursive($currentOption, $newOptionValue);
                     // get the key of the plugin that is being added/updated
                     reset($newOptionValue);
                     $newOptionKey = key($newOptionValue);
                     if (!array_key_exists($newOptionKey, $currentOptionValue)) {
                         // if the key doesn't exist just write out the new config and move on
                         self::writeUpdateConfigOption($optionName, $optionValue);
                         return;
                     } else {
                         // see if the existing configs for the plugin exists. if so just return with no changes
                         if ($newOptionValue[$newOptionKey] == $currentOptionValue[$newOptionKey]) {
                             return;
                         } else {
                             $optionNameOutput = $optionName . "." . $newOptionKey;
                         }
                     }
                 }
                 if ($currentOptionValue != $newOptionValue) {
                     // prompt for input
                     if (is_array($currentOptionValue)) {
                         $prompt = "update the config option <desc>" . $optionNameOutput . "</desc> with the value from the package install?";
                     } else {
                         $prompt = "update the config option <desc>" . $optionNameOutput . " (" . $currentOptionValue . ")</desc> with the value <desc>" . $newOptionValue . "</desc>?";
                     }
                     $options = "Y/n";
                     $input = Console::promptInput($prompt, $options, "Y");
                     if ($input == "y") {
                         // update the config option
                         self::writeUpdateConfigOption($optionName, $optionValue);
                         Console::writeInfo("config option " . $optionNameOutput . " updated...", false, true);
                     } else {
                         Console::writeWarning("config option <desc>" . $optionNameOutput . "</desc> not  updated...", false, true);
                     }
                 }
             }
         }
     }
 }