Ejemplo n.º 1
0
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     // Display usage for `chef` along with the list of known additional topics.
     if (!isset($result->command->args['topic'])) {
         $this->parser->parent->displayUsage(false);
         echo "Additional help topics:" . PHP_EOL;
         foreach (array_keys($this->parser->helpTopics) as $topic) {
             echo "  {$topic}" . PHP_EOL;
         }
         echo PHP_EOL;
         exit(0);
     }
     $topic = $result->command->args['topic'];
     // Look for a help topic.
     if (isset($this->parser->helpTopics[$topic])) {
         $helpTopic = $this->parser->helpTopics[$topic];
         if (is_callable($helpTopic)) {
             call_user_func($helpTopic, $context);
         } else {
             echo $helpTopic;
         }
         exit(0);
     }
     // Command help.
     $parentParser = $this->parser->parent;
     if (isset($parentParser->commands[$topic])) {
         echo $parentParser->commands[$topic]->displayUsage(false);
         exit(0);
     }
     throw new PieCrustException("No such command or help topic: " . $topic);
 }
Ejemplo n.º 2
0
 public function run(ChefContext $context)
 {
     $logger = $context->getLog();
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     // Site title.
     $title = $pieCrust->getConfig()->getValue('site/title');
     if ($title == null) {
         $title = "[Unknown Website Title]";
     }
     // Compute the page count.
     $pageCount = 0;
     $callback = function ($page) use(&$pageCount) {
         $pageCount++;
     };
     PageHelper::processPages($pieCrust, $callback);
     // Compute the post count.
     $postCounts = array();
     $blogKeys = $pieCrust->getConfig()->getValueUnchecked('site/blogs');
     foreach ($blogKeys as $blogKey) {
         $postCounts[$blogKey] = count($pieCrust->getEnvironment()->getPostInfos($blogKey));
     }
     $logger->info("Stats for '{$title}':");
     $logger->info("Root  : {$pieCrust->getRootDir()}");
     $logger->info("Pages : {$pageCount}");
     foreach ($blogKeys as $blogKey) {
         $logger->info("Posts : {$postCounts[$blogKey]} (in '{$blogKey}')");
     }
     return 0;
 }
Ejemplo n.º 3
0
 public function run(ChefContext $context)
 {
     $logger = $context->getLog();
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     // Validate options.
     if ($result->command->options['order_by_name'] && $result->command->options['order_by_count']) {
         throw new PieCrustException("Can't specify both '--order-name' and '--order-count'.");
     }
     $blogKeys = $pieCrust->getConfig()->getValue('site/blogs');
     if ($result->command->args['blog']) {
         foreach ($result->command->args['blog'] as $blogKey) {
             if (!in_array($blogKey, $blogKeys)) {
                 throw new PieCrustException("No such blog in the website : {$blogKey}");
             }
         }
         $blogKeys = $result->command->args['blog'];
     }
     $categories = array();
     foreach ($blogKeys as $blogKey) {
         $callback = function ($post) use(&$categories) {
             $c = $post->getConfig()->getValue('category');
             if ($c) {
                 if (!isset($categories[$c])) {
                     $categories[$c] = 0;
                 }
                 $categories[$c] += 1;
             }
         };
         PageHelper::processPosts($context->getApp(), $blogKey, $callback);
     }
     // Only print the count?
     if ($result->command->options['count']) {
         $logger->info(count($categories));
         return 0;
     }
     // Sort appropriately.
     $reverse = $result->command->options['reverse'];
     if ($result->command->options['order_by_name']) {
         if ($reverse) {
             krsort($categories);
         } else {
             ksort($categories);
         }
     } else {
         if ($result->command->options['order_by_count']) {
             if ($reverse) {
                 array_multisort($categories, SORT_DESC);
             } else {
                 array_multisort($categories, SORT_ASC);
             }
         }
     }
     // Print the list.
     $logger->info(count($categories) . " categories.");
     foreach ($categories as $c => $count) {
         $logger->info("{$c} ({$count} posts)");
     }
 }
Ejemplo n.º 4
0
 public function run(ChefContext $context)
 {
     $logger = $context->getLog();
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     // Get some options.
     $exact = $result->command->options['exact'];
     $fullPath = $result->command->options['full_path'];
     // If no type filters are given, return all types.
     $returnAllTypes = ($result->command->options['pages'] == false and $result->command->options['posts'] == false and $result->command->options['templates'] == false);
     // Validate the argument.
     $pattern = $result->command->args['pattern'];
     if ($exact) {
         // Check we have a path to match, and get its absolute value.
         if (!$pattern) {
             throw new PieCrustException("You need to specify a path when using the `--exact` option.");
         }
         $pattern = PathHelper::getAbsolutePath($pattern);
     } else {
         // If a pattern was given, get the Regex'd version.
         if ($pattern) {
             $pattern = PathHelper::globToRegex($pattern);
         }
     }
     $result->command->args['pattern'] = $pattern;
     $foundAny = false;
     // Find pages.
     if ($returnAllTypes or $result->command->options['pages']) {
         $pages = PageHelper::getPages($pieCrust);
         $foundAny |= $this->findPages($context, $pages);
     }
     // Find posts.
     if ($returnAllTypes or $result->command->options['posts']) {
         $blogKeys = $pieCrust->getConfig()->getValue('site/blogs');
         if ($result->command->options['blog']) {
             $blogKeys = array($result->command->options['blog']);
         }
         foreach ($blogKeys as $blogKey) {
             $pages = PageHelper::getPosts($pieCrust, $blogKey);
             $pagesIterator = new \ArrayIterator($pages);
             $sorter = new DateSortIterator($pagesIterator);
             $pages = iterator_to_array($sorter);
             $foundAny |= $this->findPages($context, $pages, $blogKey);
         }
     }
     // Find templates.
     if ($returnAllTypes or $result->command->options['templates']) {
         $templatesDirs = $pieCrust->getTemplatesDirs();
         foreach ($templatesDirs as $dir) {
             $foundAny |= $this->findTemplates($context, $dir);
         }
     }
     if (!$foundAny) {
         $pattern = $result->command->args['pattern'];
         $logger->info("No match found for '{$pattern}'.");
     }
     return 0;
 }
Ejemplo n.º 5
0
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     $log = $context->getLog();
     $rootDir = $context->getApp()->getRootDir();
     $fullAddress = $result->command->args['server'];
     $matches = array();
     if (!preg_match('/^([^:]+)(\\:([^@]+))?@(.*)$/', $fullAddress, $matches)) {
         throw new PieCrustException("The given upload address was not valid. Must be of form: user:password@domain.tld");
     }
     $user = $matches[1];
     $password = $matches[3];
     $server = $matches[4];
     $remoteRootDir = $result->command->options['remote_root'];
     if (!$remoteRootDir) {
         $remoteRootDir = '/';
     }
     $remoteRootDir = rtrim($remoteRootDir, '/\\') . '/';
     $passiveMode = $result->command->options['passive'];
     $syncMode = FTP_SYNC_ALWAYS;
     switch ($result->command->options['sync_mode']) {
         case 'time':
             $syncMode = FTP_SYNC_IF_NEWER;
             break;
         case 'time_and_size':
             $syncMode = FTP_SYNC_IF_NEWER_OR_DIFFERENT_SIZE;
             break;
     }
     $simulate = $result->command->options['simulate'];
     $log->info("Uploading to '{$server}' [{$remoteRootDir}] as {$user}");
     $conn = ftp_connect($server);
     if ($conn === false) {
         throw new PieCrustException("Can't connect to FTP server '{$server}'.");
     }
     if (!isset($password) or $password == "") {
         $password = prompt_silent("Password: "******"Connected to FTP server '{$server}'.");
             if ($passiveMode) {
                 $log->info("Enabling passive mode.");
                 if (!ftp_pasv($conn, true)) {
                     throw new PieCrustException("Can't enable passive mode.");
                 }
             }
             sync_ftp($conn, $rootDir, $remoteRootDir, $syncMode, $simulate);
         } else {
             throw new PieCrustException("Couldn't connect to FTP server '{$server}', login incorrect.");
         }
     } catch (Exception $e) {
         ftp_close($conn);
         throw $e;
     }
     ftp_close($conn);
 }
Ejemplo n.º 6
0
 public function run(ChefContext $context)
 {
     $this->log = $context->getLog();
     $result = $context->getResult();
     $rootDir = $result->command->args['destination'];
     if (!$rootDir) {
         $rootDir = getcwd();
     }
     $this->initializeWebsite($rootDir, array('apache' => $result->command->options['apache'], 'iis' => $result->command->options['iis']));
 }
Ejemplo n.º 7
0
 public function run(ChefContext $context)
 {
     $cacheDir = $context->getApp()->getCacheDir();
     if (!$cacheDir) {
         throw new PieCrustException("The website seems to have caching disabled.");
     }
     if (!is_dir($cacheDir)) {
         throw new PieCrustException("The cache directory doesn't exist: {$cacheDir}");
     }
     $context->getLog()->info("Purging cache: {$cacheDir}");
     PathHelper::deleteDirectoryContents($cacheDir);
 }
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     $app = $context->getApp();
     $log = $context->getLog();
     // Create the posts directory if it doesn't exist.
     if ($app->getPostsDir() == false) {
         $postsDir = $app->getRootDir() . PieCrustDefaults::CONTENT_POSTS_DIR;
         $log->info("Creating posts directory: {$postsDir}");
         mkdir($postsDir, 0777, true);
         $app->setPostsDir($postsDir);
     }
     // Create the relative path of the new post by using the
     // path format of the website's post file-system.
     $slug = $result->command->command->args['slug'];
     $captureGroups = array('day' => date('d'), 'month' => date('m'), 'year' => date('Y'), 'slug' => $slug, 'ext' => 'html');
     // Figure out which blog to create this post for (if the website
     // is hosting several blogs).
     $blogKey = $result->command->command->options['blog'];
     $blogKeys = $app->getConfig()->getValue('site/blogs');
     if ($blogKey == null) {
         $blogKey = $blogKeys[0];
     } else {
         if (!in_array($blogKey, $blogKeys)) {
             throw new PieCrustException("Specified blog '{$blogKey}' is not one of the known blogs in this website: " . implode(', ', $blogKeys));
         }
     }
     // Create the full path.
     $fs = $app->getEnvironment()->getFileSystem();
     $pathInfo = $fs->getPostPathInfo($blogKey, $captureGroups, FileSystem::PATHINFO_CREATING);
     $fullPath = $pathInfo['path'];
     $relativePath = PieCrustHelper::getRelativePath($app, $fullPath);
     if (file_exists($fullPath)) {
         throw new PieCrustException("Post already exists: {$relativePath}");
     }
     $log->info("Creating new post: {$relativePath}");
     // Create the title and time of post.
     $title = preg_replace('/[\\-_]+/', ' ', $slug);
     $title = ucwords($title);
     $time = date('H:i:s');
     // Write the contents.
     if (!is_dir(dirname($fullPath))) {
         mkdir(dirname($fullPath), 0777, true);
     }
     $f = fopen($fullPath, 'w');
     fwrite($f, "---\n");
     fwrite($f, "title: {$title}\n");
     fwrite($f, "time: {$time}\n");
     fwrite($f, "---\n");
     fwrite($f, "My new blog post!\n");
     fclose($f);
 }
Ejemplo n.º 9
0
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     // Validate arguments.
     $format = $result->command->args['format'];
     $source = $result->command->args['source'];
     if (!$format or !$source) {
         // Warning for the old syntax.
         throw new PieCrustException("The syntax for this command has changed: specify the format and the source as arguments. See `chef import -h` for help.");
     }
     // Start importing!
     $importer = new PieCrustImporter($context->getApp(), $context->getLog());
     $importer->import($format, $source, $result->command->options);
 }
Ejemplo n.º 10
0
 public function run(ChefContext $context)
 {
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     $outputDir = $result->command->options['output'];
     // Warn about deprecated stuff.
     if ($result->command->options['file_urls']) {
         $context->getLog()->warning("The `--fileurls` option has been deprecated. Please use `--portable` instead.");
         $result->command->options['portable_urls'] = true;
     }
     if ($result->command->options['pretty_urls_old']) {
         $context->getLog()->err("The `--prettyurls` option has been deprecated. Please use a config variant instead.");
         return;
     }
     if ($result->command->options['root_url_old']) {
         $context->getLog()->err("The `--rooturl` option has been deprecated. Please use a config variant instead.");
         return;
     }
     // Set-up the app and the baker.
     $bakerParameters = array('smart' => !$result->command->options['force'], 'clean_cache' => $result->command->options['force'], 'info_only' => $result->command->options['info_only'], 'config_variant' => $result->command->options['config_variant']);
     $baker = new PieCrustBaker($pieCrust, $bakerParameters, $context->getLog());
     if ($outputDir) {
         $baker->setBakeDir($outputDir);
     }
     if ($result->command->options['portable_urls']) {
         $pieCrust->getConfig()->setValue('baker/portable_urls', true);
         // Also disable pretty URLs because it doesn't make much sense
         // when there's no web server handling default documents.
         $pieCrust->getConfig()->setValue('site/pretty_urls', false);
     }
     // Start baking!
     $baker->bake();
 }
Ejemplo n.º 11
0
 protected function installThemes(ChefContext $context)
 {
     $app = $context->getApp();
     $log = $context->getLog();
     $result = $context->getResult();
     $sources = $this->getSources($app, $log);
     $themeName = $result->command->command->args['name'];
     $themes = $this->getThemeMetadata($app, $sources, $themeName, true, $log);
     if (count($themes) != 1) {
         throw new PieCrustException("Can't find a single theme named: {$themeName}");
     }
     $theme = $themes[0];
     $log->debug("Installing '{$theme['name']}' from: {$theme['source']}");
     $className = $theme['repository_class'];
     $repository = new $className();
     $context = new ThemeInstallContext($app, $log);
     $repository->installTheme($theme, $context);
     $log->info("Theme {$theme['name']} is now installed.");
 }
Ejemplo n.º 12
0
 protected function installPlugins(ChefContext $context)
 {
     $app = $context->getApp();
     $log = $context->getLog();
     $result = $context->getResult();
     $sources = $this->getSources($app, $log);
     $pluginName = $result->command->command->args['name'];
     $plugins = $this->getPluginMetadata($app, $sources, $pluginName, true, $log);
     if (count($plugins) != 1) {
         throw new PieCrustException("Can't find a single plugin named: {$pluginName}");
     }
     $plugin = $plugins[0];
     $log->debug("Installing '{$plugin['name']}' from: {$plugin['source']}");
     $className = $plugin['repository_class'];
     $repository = new $className();
     $context = new PluginInstallContext($app, $log);
     $repository->installPlugin($plugin, $context);
     $log->info("Plugin {$plugin['name']} is now installed.");
 }
Ejemplo n.º 13
0
 public function run(ChefContext $context)
 {
     $app = $context->getApp();
     $result = $context->getResult();
     $log = $context->getLog();
     $environment = $app->getEnvironment();
     if (!$environment instanceof ChefEnvironment) {
         throw new PieCrustException("Can't run the `prepare` command without a Chef environment.");
     }
     $extensionName = $result->command->command_name;
     $extensions = $environment->getCommandExtensions($this->getName());
     foreach ($extensions as $ext) {
         if ($ext->getName() == $extensionName) {
             $ext->run($context);
             return;
         }
     }
     throw new PieCrustException("No such extension for the `prepare` command: " . $extensionName);
 }
Ejemplo n.º 14
0
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     // Warn about deprecated stuff.
     if ($result->command->options['run_browser_old']) {
         $context->getLog()->warning("The `--nobrowser` option has been renamed to `--no-browser`.");
         $result->command->options['run_browser'] = false;
     }
     $rootDir = $context->getApp()->getRootDir();
     $port = intval($result->command->options['port']);
     $address = $result->command->options['address'];
     $runBrowser = $result->command->options['run_browser'];
     $logFile = $result->command->options['log_file'];
     $debug = $result->command->options['debug'];
     $nocache = $result->command->options['no_cache'];
     // Start serving!
     $server = new PieCrustServer($rootDir, array('port' => $port, 'address' => $address, 'log_file' => $logFile, 'debug' => $debug, 'cache' => !$nocache), $context->getLog());
     $server->run(array('list_directories' => false, 'run_browser' => $runBrowser));
 }
Ejemplo n.º 15
0
 public function run(ChefContext $context)
 {
     $logger = $context->getLog();
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     $path = $result->command->args['path'];
     if ($path) {
         $configToShow = $pieCrust->getConfig()->getValue($path);
     } else {
         $configToShow = $pieCrust->getConfig()->get();
     }
     if ($configToShow) {
         if (is_array($configToShow)) {
             $this->printConfig($configToShow, $logger);
         } else {
             $logger->info($configToShow);
         }
     }
 }
Ejemplo n.º 16
0
 public function run(ChefContext $context)
 {
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     // Set-up the app and the baker.
     $bakerParameters = array('smart' => !$result->command->options['force'], 'clean_cache' => $result->command->options['force'], 'config_variant' => $result->command->options['config_variant']);
     if ($result->command->options['output']) {
         $bakerParameters['output'] = $result->command->options['output'];
     }
     $baker = new PieCrustBaker($pieCrust, $bakerParameters);
     if ($result->command->options['portable_urls']) {
         $pieCrust->getConfig()->setValue('baker/portable_urls', true);
         // Also disable pretty URLs because it doesn't make much sense
         // when there's no web server handling default documents.
         $pieCrust->getConfig()->setValue('site/pretty_urls', false);
     }
     // Start baking!
     $baker->bake();
 }
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     $app = $context->getApp();
     $log = $context->getLog();
     // Create the pages directory if it doesn't exist.
     if ($app->getPagesDir() == false) {
         $pagesDir = $app->getRootDir() . PieCrustDefaults::CONTENT_PAGES_DIR;
         $log->info("Creating pages directory: {$pagesDir}");
         mkdir($pagesDir, 0777, true);
         $app->setPagesDir($pagesDir);
     }
     // Create the path of the feed.
     $slug = $result->command->command->args['url'];
     $slug = ltrim($slug, '/\\');
     $fullPath = $app->getPagesDir() . $slug;
     if (!preg_match('/\\.[a-z0-9]+$/i', $slug)) {
         $fullPath .= '.html';
     }
     $relativePath = PieCrustHelper::getRelativePath($app, $fullPath);
     if (file_exists($fullPath)) {
         throw new PieCrustException("Page already exists: {$relativePath}");
     }
     $log->info("Creating feed: {$relativePath}");
     // Get the feed template.
     $templatePath = PieCrustDefaults::RES_DIR() . 'prepare/rss.html';
     if ($result->command->command->options['use_atom']) {
         $templatePath = PieCrustDefaults::RES_DIR() . 'prepare/atom.html';
     }
     $template = file_get_contents($templatePath);
     // Write the contents.
     if (!is_dir(dirname($fullPath))) {
         mkdir(dirname($fullPath), 0777, true);
     }
     $f = fopen($fullPath, 'w');
     fwrite($f, $template);
     fclose($f);
     $fullUrl = $app->getConfig()->getValue('site/root') . $slug;
     $log->info("Don't forget to add a link into your main page's header like so:");
     $log->info("<link rel=\"alternate\" type=\"application/rss+xml\" href=\"{$fullUrl}\" />");
 }
 public function run(ChefContext $context)
 {
     $result = $context->getResult();
     $app = $context->getApp();
     $log = $context->getLog();
     // Create the pages directory if it doesn't exist.
     if ($app->getPagesDir() == false) {
         $pagesDir = $app->getRootDir() . PieCrustDefaults::CONTENT_PAGES_DIR;
         $log->info("Creating pages directory: {$pagesDir}");
         mkdir($pagesDir, 0777, true);
         $app->setPagesDir($pagesDir);
     }
     // Create the path of the new page.
     $slug = $result->command->command->args['slug'];
     $slug = ltrim($slug, '/\\');
     $fullPath = $app->getPagesDir() . $slug;
     if (!preg_match('/\\.[a-z0-9]+$/i', $slug)) {
         $fullPath .= '.html';
     }
     $relativePath = PieCrustHelper::getRelativePath($app, $fullPath);
     if (file_exists($fullPath)) {
         throw new PieCrustException("Page already exists: {$relativePath}");
     }
     $log->info("Creating new page: {$relativePath}");
     // Create the title and date/time of post.
     $title = preg_replace('/[\\-_]+/', ' ', $slug);
     $title = ucwords($title);
     $date = date('Y-m-d H:i');
     // Write the contents.
     if (!is_dir(dirname($fullPath))) {
         mkdir(dirname($fullPath), 0777, true);
     }
     $f = fopen($fullPath, 'w');
     fwrite($f, "---\n");
     fwrite($f, "title: {$title}\n");
     fwrite($f, "date: {$date}\n");
     fwrite($f, "---\n");
     fwrite($f, "A new page.\n");
     fclose($f);
 }
Ejemplo n.º 19
0
 /**
  * Runs Chef given some command-line arguments.
  */
 public function runUnsafe($userArgc = null, $userArgv = null)
 {
     // Get the arguments.
     if ($userArgc == null || $userArgv == null) {
         $getopt = new \Console_Getopt();
         $userArgv = $getopt->readPHPArgv();
         // `readPHPArgv` returns a `PEAR_Error` (or something like it) if
         // it can't figure out the CLI arguments.
         if (!is_array($userArgv)) {
             throw new PieCrustException($userArgv->getMessage());
         }
         $userArgc = count($userArgv);
     }
     // Find whether the '--root' parameter was given.
     $rootDir = null;
     foreach ($userArgv as $arg) {
         if (substr($arg, 0, strlen('--root=')) == '--root=') {
             $rootDir = substr($arg, strlen('--root='));
             break;
         }
     }
     if ($rootDir == null) {
         // No root given. Find it ourselves.
         $rootDir = PathHelper::getAppRootDir(getcwd());
     } else {
         // The root was given.
         $rootDir = PathHelper::getAbsolutePath($rootDir);
         if (!is_dir($rootDir)) {
             throw new PieCrustException("The given root directory doesn't exist: " . $rootDir);
         }
     }
     // Build the appropriate app.
     if ($rootDir == null) {
         $pieCrust = new NullPieCrust();
     } else {
         $pieCrust = new PieCrust(array('root' => $rootDir, 'cache' => !in_array('--no-cache', $userArgv)));
     }
     // Set up the command line parser.
     $parser = new \Console_CommandLine(array('name' => 'chef', 'description' => 'The PieCrust chef manages your website.', 'version' => PieCrustDefaults::VERSION));
     // Sort commands by name.
     $sortedCommands = $pieCrust->getPluginLoader()->getCommands();
     usort($sortedCommands, function ($c1, $c2) {
         return strcmp($c1->getName(), $c2->getName());
     });
     // Add commands to the parser.
     foreach ($sortedCommands as $command) {
         $commandParser = $parser->addCommand($command->getName());
         $command->setupParser($commandParser, $pieCrust);
         $this->addCommonOptionsAndArguments($commandParser);
     }
     // Parse the command line.
     try {
         $result = $parser->parse($userArgc, $userArgv);
     } catch (Exception $e) {
         $parser->displayError($e->getMessage());
         return 1;
     }
     // If no command was given, use `help`.
     if (empty($result->command_name)) {
         $result = $parser->parse(2, array('chef', 'help'));
     }
     // Create the log.
     $debugMode = $result->command->options['debug'];
     $quietMode = $result->command->options['quiet'];
     if ($debugMode && $quietMode) {
         $parser->displayError("You can't specify both --debug and --quiet.");
         return 1;
     }
     $log = \Log::singleton('console', 'Chef', '', array('lineFormat' => '%{message}'));
     // Make the log available for debugging purposes.
     $GLOBALS['__CHEF_LOG'] = $log;
     // Handle deprecated stuff.
     if ($result->command->options['no_cache_old']) {
         $log->warning("The `--nocache` option has been renamed `--no-cache`.");
         $result->command->options['no_cache'] = true;
     }
     // Run the command.
     foreach ($pieCrust->getPluginLoader()->getCommands() as $command) {
         if ($command->getName() == $result->command_name) {
             try {
                 if ($rootDir == null && $command->requiresWebsite()) {
                     $cwd = getcwd();
                     throw new PieCrustException("No PieCrust website in '{$cwd}' ('_content/config.yml' not found!).");
                 }
                 $context = new ChefContext($pieCrust, $result, $log);
                 $context->setVerbosity($debugMode ? 'debug' : ($quietMode ? 'quiet' : 'default'));
                 $command->run($context);
                 return;
             } catch (Exception $e) {
                 $log->emerg(self::getErrorMessage($e, $debugMode));
                 return 1;
             }
         }
     }
 }
Ejemplo n.º 20
0
 /**
  * Runs Chef given some command-line arguments.
  */
 public function runUnsafe($userArgc = null, $userArgv = null)
 {
     // Get the arguments.
     if ($userArgc == null || $userArgv == null) {
         $getopt = new \Console_Getopt();
         $userArgv = $getopt->readPHPArgv();
         // `readPHPArgv` returns a `PEAR_Error` (or something like it) if
         // it can't figure out the CLI arguments.
         if (!is_array($userArgv)) {
             throw new PieCrustException($userArgv->getMessage());
         }
         $userArgc = count($userArgv);
     }
     // Find if whether the `--root` or `--config` parameters were given.
     $rootDir = null;
     $isThemeSite = false;
     $configVariant = null;
     for ($i = 1; $i < count($userArgv); ++$i) {
         $arg = $userArgv[$i];
         if (substr($arg, 0, strlen('--root=')) == '--root=') {
             $rootDir = substr($arg, strlen('--root='));
             if (substr($rootDir, 0, 1) == '~') {
                 $rootDir = getenv("HOME") . substr($rootDir, 1);
             }
         } elseif ($arg == '--root') {
             $rootDir = $userArgv[$i + 1];
             ++$i;
         } elseif (substr($arg, 0, strlen('--config=')) == '--config=') {
             $configVariant = substr($arg, strlen('--config='));
         } elseif ($arg == '--config') {
             $configVariant = $userArgv[$i + 1];
             ++$i;
         } elseif ($arg == '--theme') {
             $isThemeSite = true;
         } else {
             if ($arg[0] != '-') {
                 // End of the global arguments sections. This is
                 // the command name.
                 break;
             }
         }
     }
     if ($rootDir == null) {
         // No root given. Find it ourselves.
         $rootDir = PathHelper::getAppRootDir(getcwd(), $isThemeSite);
     } else {
         // The root was given.
         $rootDir = trim($rootDir, " \"");
         if (!is_dir($rootDir)) {
             throw new PieCrustException("The given root directory doesn't exist: " . $rootDir);
         }
     }
     // Build the appropriate app.
     if ($rootDir == null) {
         $pieCrust = new NullPieCrust();
     } else {
         $environment = new ChefEnvironment();
         $pieCrust = new PieCrust(array('root' => $rootDir, 'cache' => !in_array('--no-cache', $userArgv), 'environment' => $environment, 'theme_site' => $isThemeSite));
     }
     // Pre-load the correct config variant if any was specified.
     if ($configVariant != null) {
         // You can't apply a config variant if there's no website.
         if ($rootDir == null) {
             $cwd = getcwd();
             throw new PieCrustException("No PieCrust website in '{$cwd}' ('_content/config.yml' not found!).");
         }
         $configVariant = trim($configVariant, " \"");
         $pieCrust->getConfig()->applyVariant('variants/' . $configVariant);
     }
     // Set up the command line parser.
     $parser = new \Console_CommandLine(array('name' => 'chef', 'description' => 'The PieCrust chef manages your website.', 'version' => PieCrustDefaults::VERSION));
     $parser->renderer = new ChefCommandLineRenderer($parser);
     $this->addCommonOptionsAndArguments($parser);
     // Sort commands by name.
     $sortedCommands = $pieCrust->getPluginLoader()->getCommands();
     usort($sortedCommands, function ($com1, $com2) {
         return strcmp($com1->getName(), $com2->getName());
     });
     // Add commands to the parser.
     foreach ($sortedCommands as $command) {
         $commandParser = $parser->addCommand($command->getName());
         $command->setupParser($commandParser, $pieCrust);
     }
     // Parse the command line.
     try {
         $result = $parser->parse($userArgc, $userArgv);
     } catch (Exception $e) {
         $parser->displayError($e->getMessage(), false);
         return 3;
     }
     // If no command was given, use `help`.
     if (empty($result->command_name)) {
         $result = $parser->parse(2, array('chef', 'help'));
     }
     // Create the log.
     $debugMode = $result->options['debug'];
     $quietMode = $result->options['quiet'];
     if ($debugMode && $quietMode) {
         $parser->displayError("You can't specify both --debug and --quiet.", false);
         return 1;
     }
     $log = new ChefLog('Chef');
     // Log to a file.
     if ($result->options['log']) {
         $log->addFileLog($result->options['log']);
     }
     // Make the log available to PieCrust.
     if ($rootDir != null) {
         $environment->setLog($log);
     }
     // Make the log available for debugging purposes.
     $GLOBALS['__CHEF_LOG'] = $log;
     // Run the command.
     foreach ($pieCrust->getPluginLoader()->getCommands() as $command) {
         if ($command->getName() == $result->command_name) {
             try {
                 if ($rootDir == null && $command->requiresWebsite()) {
                     $cwd = getcwd();
                     throw new PieCrustException("No PieCrust website in '{$cwd}' ('_content/config.yml' not found!).");
                 }
                 if ($debugMode) {
                     $log->debug("PieCrust v." . PieCrustDefaults::VERSION);
                     $log->debug("  Website: {$rootDir}");
                 }
                 $context = new ChefContext($pieCrust, $result, $log);
                 $context->setVerbosity($debugMode ? 'debug' : ($quietMode ? 'quiet' : 'default'));
                 $command->run($context);
                 return;
             } catch (Exception $e) {
                 $log->exception($e, $debugMode);
                 return 1;
             }
         }
     }
 }
Ejemplo n.º 21
0
 public function run(ChefContext $context)
 {
     $logger = $context->getLog();
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     // Get some options.
     $exact = $result->command->options['exact'];
     $fullPath = $result->command->options['full_path'];
     // If no type filters are given, return all types.
     $returnAllTypes = ($result->command->options['pages'] == false and $result->command->options['posts'] == false and $result->command->options['templates'] == false);
     // Validate the argument.
     $pattern = $result->command->args['pattern'];
     if ($exact) {
         // Check we have a path to match, and get its absolute value.
         if (!$pattern) {
             throw new PieCrustException("You need to specify a path when using the `--exact` option.");
         }
         $pattern = PathHelper::getAbsolutePath($pattern);
     } else {
         // If a pattern was given, get the Regex'd version.
         if ($pattern) {
             $pattern = PathHelper::globToRegex($pattern);
         }
     }
     // Get the pages and posts.
     $pages = array();
     if ($returnAllTypes or $result->command->options['pages']) {
         $pages = PageHelper::getPages($pieCrust);
     }
     if ($returnAllTypes or $result->command->options['posts']) {
         $blogKeys = $pieCrust->getConfig()->getValue('site/blogs');
         if ($result->command->options['blog']) {
             $blogKeys = array($result->command->options['blog']);
         }
         foreach ($blogKeys as $blogKey) {
             $pages = array_merge($pages, PageHelper::getPosts($pieCrust, $blogKey));
         }
     }
     // Get some other stuff.
     $returnComponents = $result->command->options['page_components'];
     // Get a regex for the posts file-naming convention.
     $fs = FileSystem::create($pieCrust);
     $pathComponentsRegex = preg_quote($fs->getPostPathFormat(), '/');
     $pathComponentsRegex = str_replace(array('%year%', '%month%', '%day%', '%slug%'), array('(\\d{4})', '(\\d{2})', '(\\d{2})', '(.+)'), $pathComponentsRegex);
     $pathComponentsRegex = '/' . $pathComponentsRegex . '/';
     // Print the matching pages.
     foreach ($pages as $page) {
         if ($result->command->options['no_special']) {
             // Skip special pages.
             if ($page->getUri() == PieCrustDefaults::CATEGORY_PAGE_NAME or $page->getUri() == PieCrustDefaults::TAG_PAGE_NAME) {
                 continue;
             }
         }
         if ($exact) {
             // Match the path exactly, or pass.
             if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $page->getPath())) {
                 continue;
             }
         } else {
             if ($pattern) {
                 // Match the regex, or pass.
                 if (!preg_match($pattern, $page->getUri())) {
                     continue;
                 }
             }
         }
         $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $page->getPath());
         if (!$fullPath) {
             $path = PieCrustHelper::getRelativePath($pieCrust, $path);
         }
         if ($returnComponents) {
             $components = array('path' => $path, 'type' => 'page', 'uri' => $page->getUri(), 'slug' => $page->getUri());
             if (PageHelper::isPost($page)) {
                 $matches = array();
                 if (preg_match($pathComponentsRegex, str_replace('\\', '/', $path), $matches) !== 1) {
                     throw new PieCrustException("Can't extract path components from path: {$path}");
                 }
                 $components['type'] = 'post';
                 $components['year'] = $matches[1];
                 $components['month'] = $matches[2];
                 $components['day'] = $matches[3];
                 $components['slug'] = $matches[4];
             }
             $str = '';
             foreach ($components as $k => $v) {
                 $str .= $k . ': ' . $v . PHP_EOL;
             }
             $logger->info($str);
         } else {
             $logger->info($path);
         }
     }
     // Get the template files and print them.
     if ($returnAllTypes or $result->command->options['templates']) {
         $templatesDirs = $pieCrust->getTemplatesDirs();
         foreach ($templatesDirs as $dir) {
             $dirIt = new \RecursiveDirectoryIterator($dir);
             $it = new \RecursiveIteratorIterator($dirIt);
             foreach ($it as $path) {
                 if ($it->isDot()) {
                     continue;
                 }
                 $relativePath = PieCrustHelper::getRelativePath($pieCrust, $path->getPathname());
                 if ($exact) {
                     // Match the path exactly, or pass.
                     if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $path->getPathname())) {
                         continue;
                     }
                 } else {
                     if ($pattern) {
                         // Match the regex, or pass.
                         if (!preg_match($pattern, $relativePath)) {
                             continue;
                         }
                     }
                 }
                 // Get the path to print.
                 $finalPath = $relativePath;
                 if ($fullPath) {
                     $finalPath = $path->getPathname();
                 }
                 $finalPath = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $finalPath);
                 // Print the information!
                 if ($returnComponents) {
                     $logger->info("path: {$finalPath}");
                     $logger->info("type: template");
                 } else {
                     $logger->info($finalPath);
                 }
             }
         }
     }
     return 0;
 }
Ejemplo n.º 22
0
 protected function installRequirements(array $theme, ChefContext $context)
 {
     if (!isset($theme['requires'])) {
         return;
     }
     $log = $context->getLog();
     $requirements = $theme['requires'];
     if (isset($requirements['plugins'])) {
         $requiredPlugins = $requirements['plugins'];
         if (!is_array($requiredPlugins)) {
             $requiredPlugins = array($requiredPlugins);
         }
         $log->info("Installing required plugins: ");
         $installer = new PluginsCommand();
         foreach ($requiredPlugins as $pluginName) {
             $log->debug("Installing {$pluginName}...");
             $installer->installPlugin($pluginName, $context);
         }
     }
 }
Ejemplo n.º 23
0
 protected function updatePlugins(ChefContext $context)
 {
     $app = $context->getApp();
     $log = $context->getLog();
     $result = $context->getResult();
     $pluginName = $result->command->command->args['name'];
     // Right now we do it the brute force way: update everything.
     // TODO: keep some metadata on the installed version so we don't overwrite with the exact same.
     $pluginLoader = $app->getPluginLoader();
     foreach ($pluginLoader->getPlugins() as $plugin) {
         $curName = $plugin->getName();
         if ($curName != '__builtin__' && ($curName == $pluginName || !$pluginName)) {
             $log->info("Updating {$curName}...");
             // First, rename the existing directory.
             $pluginMeta = $pluginLoader->getPluginMeta($curName);
             $pluginDir = $pluginMeta->directory;
             $pluginDirBackup = $pluginDir . '__backup';
             if (!rename($pluginDir, $pluginDirBackup)) {
                 throw new PieCrustException("Can't rename plugin directory: {$pluginDir}");
             }
             // Then, update.
             try {
                 $plugin = $this->installPlugin($curName, $context);
             } catch (\Exception $e) {
                 $log->debug("Error encountered, restoring backup directory.");
                 rename($pluginDirBackup, $pluginDir);
                 throw new PieCrustException("Error updating plugin '{$curName}'.", 0, $e);
             }
             // Last, cleanup backup directory.
             $log->debug("Cleaning up backup directory: {$pluginDirBackup}");
             PathHelper::deleteDirectoryContents($pluginDirBackup);
             rmdir($pluginDirBackup);
         }
     }
 }
Ejemplo n.º 24
0
 public function run(ChefContext $context)
 {
     $app = $context->getApp();
     $result = $context->getResult();
     $log = $context->getLog();
     $matches = array();
     $dryRun = false;
     $requirePhar = true;
     $fromVersion = PieCrustDefaults::VERSION;
     $targetVersion = $result->command->args['target'];
     if (substr($targetVersion, 0, 1) == ':' && preg_match("#" . "(\\:from\\:([^:]+))?" . "(\\:to\\:([^:]+))?" . "(\\:dry)?" . "#", $targetVersion, $matches)) {
         // Secret syntax to debug this whole shit.
         $fromVersion = $matches[2];
         $targetVersion = $matches[4];
         $dryRun = (bool) $matches[5];
         $requirePhar = false;
         if ($fromVersion) {
             $log->info("OVERRIDE: from = {$fromVersion}");
         }
         if ($targetVersion) {
             $log->info("OVERRIDE: to = {$targetVersion}");
         }
         if ($dryRun) {
             $log->info("OVERRIDE: dry run");
         }
     }
     if (!$targetVersion) {
         $targetVersion = $this->getNextVersion($fromVersion, $requirePhar, $log);
     }
     if (!$targetVersion) {
         $log->info("PieCrust is already up-to-date.");
         return 0;
     }
     $log->info("Updating to version {$targetVersion}...");
     if ($targetVersion == 'master' or $targetVersion == 'dev') {
         // Aliases for the `default` Mercurial branch.
         $targetVersion = 'default';
     }
     $thisPath = Phar::running(false);
     if (!$requirePhar and !$thisPath) {
         $thisPath = getcwd() . '/piecrust.phar';
     }
     if (!$thisPath) {
         throw new PieCrustException("The self-update command can only be run from an installed PieCrust.");
     }
     $tempPath = $thisPath . '.downloading';
     if (!is_writable(dirname($thisPath))) {
         throw new PieCrustException("PieCrust binary directory is not writable.");
     }
     if (is_file($thisPath) and !is_writable($thisPath)) {
         throw new PieCrustException("PieCrust binary is not writable.");
     }
     $pharUrl = "http://backend.bolt80.com/piecrust/{$targetVersion}/piecrust.phar";
     $log->debug("Downloading: {$pharUrl}");
     if ($dryRun) {
         return 0;
     }
     // Download the file.
     $fout = fopen($tempPath, 'wb');
     if ($fout === false) {
         throw new PieCrustException("Can't write to temporary file: {$tempPath}");
     }
     $fin = fopen($pharUrl, 'rb');
     if ($fin === false) {
         throw new PieCrustException("Can't download binary file: {$pharUrl}");
     }
     while (!feof($fin)) {
         $data = fread($fin, 8192);
         fwrite($fout, $data);
     }
     fclose($fin);
     fclose($fout);
     // Test the downloaded file.
     $log->debug("Checking downloaded file: {$tempPath}");
     try {
         chmod($tempPath, 0777 & ~umask());
         $phar = new \Phar($tempPath);
         // Free the variable to unlock the file.
         unset($phar);
     } catch (\Exception $e) {
         @unlink($tempPath);
         if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
             throw $e;
         }
         $log->err("The downloaded binary seems to be corrupted: {$e->getMessage()}");
         $log->err("Please try running the self update command again.");
         return 1;
     }
     // Replace the current binary with the download.
     $log->debug("Replacing running binary with downloaded file.");
     rename($tempPath, $thisPath);
 }
Ejemplo n.º 25
0
 public function run(ChefContext $context)
 {
     $logger = $context->getLog();
     $pieCrust = $context->getApp();
     $result = $context->getResult();
     // Warn about deprecated stuff.
     if ($result->command->options['order_by_name_old']) {
         $context->getLog()->warning("The `--orderbyname` option has been renamed to `--order-name`.");
         $result->command->options['order_by_name'] = true;
     }
     if ($result->command->options['order_by_count_old']) {
         $context->getLog()->warning("The `--orderbycount` option has been renamed to `--order-count`.");
         $result->command->options['order_by_count'] = true;
     }
     // Validate options.
     if ($result->command->options['order_by_name'] && $result->command->options['order_by_count']) {
         throw new PieCrustException("Can't specify both '--order-name' and '--order-count'.");
     }
     $blogKeys = $pieCrust->getConfig()->getValue('site/blogs');
     if ($result->command->args['blog']) {
         foreach ($result->command->args['blog'] as $blogKey) {
             if (!in_array($blogKey, $blogKeys)) {
                 throw new PieCrustException("No such blog in the website : {$blogKey}");
             }
         }
         $blogKeys = $result->command->args['blog'];
     }
     $tags = array();
     foreach ($blogKeys as $blogKey) {
         $callback = function ($post) use(&$tags) {
             $postTags = $post->getConfig()->getValue('tags');
             if ($postTags) {
                 if (!is_array($postTags)) {
                     $postTags = array($postTags);
                 }
                 foreach ($postTags as $t) {
                     if (!isset($tags[$t])) {
                         $tags[$t] = 0;
                     }
                     $tags[$t] += 1;
                 }
             }
         };
         PageHelper::processPosts($pieCrust, $blogKey, $callback);
     }
     // Only print the count?
     if ($result->command->options['count']) {
         $logger->info(count($tags));
         return 0;
     }
     // Sort appropriately.
     $reverse = $result->command->options['reverse'];
     if ($result->command->options['order_by_name']) {
         if ($reverse) {
             krsort($tags);
         } else {
             ksort($tags);
         }
     } else {
         if ($result->command->options['order_by_count']) {
             if ($reverse) {
                 array_multisort($tags, SORT_DESC);
             } else {
                 array_multisort($tags, SORT_ASC);
             }
         }
     }
     // Print the list.
     $logger->info(count($tags) . " tags.");
     foreach ($tags as $t => $count) {
         $logger->info("{$t} ({$count} posts)");
     }
 }
Ejemplo n.º 26
0
 public function run(ChefContext $context)
 {
     // Don't use the context logger because we want this to be the "pure" value
     // so it can be re-used in other shell commands.
     echo rtrim($context->getApp()->getRootDir(), '/\\') . PHP_EOL;
 }