diff --git a/composer.json b/composer.json index a999853..41ad4b9 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "php": ">=5.4", "league/plates": "~3.1", "guzzlehttp/guzzle": "~5.3", - "league/commonmark": "0.8.*" + "league/commonmark": "0.8.*", + "symfony/console": "~2.7" }, "autoload": { "psr-4": {"Todaymade\\Daux\\": "libs/"} diff --git a/composer.lock b/composer.lock index d2afb82..ceffecc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "a7e29fdc079b4e2a588148bff949237a", + "hash": "eda78cf80f9699aa99725c4330a8830a", "packages": [ { "name": "guzzlehttp/guzzle", @@ -321,6 +321,63 @@ ], "description": "A lightweight implementation of CommonJS Promises/A for PHP", "time": "2014-12-30 13:32:42" + }, + { + "name": "symfony/console", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "8cf484449130cabfd98dcb4694ca9945802a21ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/8cf484449130cabfd98dcb4694ca9945802a21ed", + "reference": "8cf484449130cabfd98dcb4694ca9945802a21ed", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-07-09 16:07:40" } ], "packages-dev": [], diff --git a/generate.php b/generate.php index 5099db7..89cfdd2 100644 --- a/generate.php +++ b/generate.php @@ -67,22 +67,5 @@ require_once("vendor/autoload.php"); \Todaymade\Daux\Daux::initConstants(); -$rules = [ - 'config|c-s' => 'Configuration file', - 'format|f-s' => 'Output format, html or confluence (default:html)', - - //HTML - 'destination|d-s' => 'Destination folder, relative to the working directory (default:static)', -]; - -$options = new \Todaymade\Daux\Generator\Getopt($rules, $argv); - -$default = [ - 'config' => null, - 'format' => 'html', - 'destination' => null, -]; - -$generator = new \Todaymade\Daux\Generator\Generator(); - -$generator->generate($options->getOptions() + $default); +$application = new \Todaymade\Daux\Generator\Application(); +$application->run(); diff --git a/libs/Format/Base/RunAction.php b/libs/Format/Base/RunAction.php new file mode 100644 index 0000000..1186a44 --- /dev/null +++ b/libs/Format/Base/RunAction.php @@ -0,0 +1,22 @@ +write($title); + // 8 is the length of the label + 2 let it breathe + $padding = $width - strlen($title) - 10; + try { + $response = $closure(); + } catch (\Exception $e) { + $output->writeln(str_pad(" ", $padding) . "[ FAIL ]"); + throw $e; + } + $output->writeln(str_pad(" ", $padding) . "[ OK ]"); + + return $response; + } +} diff --git a/libs/Format/Confluence/Generator.php b/libs/Format/Confluence/Generator.php index d690ce6..dfe1209 100644 --- a/libs/Format/Confluence/Generator.php +++ b/libs/Format/Confluence/Generator.php @@ -1,19 +1,23 @@ getParams()['confluence']; @@ -21,15 +25,24 @@ class Generator $params = $daux->getParams(); - echo "Generating Tree...\n"; - $tree = $this->generateRecursive($daux->tree, $params); - $tree['title'] = $this->prefix . $daux->getParams()['title']; + $tree = $this->runAction( + "Generating Tree ...", + $output, + $width, + function() use ($daux, $params) { + $tree = $this->generateRecursive($daux->tree, $params); + $tree['title'] = $this->prefix . $daux->getParams()['title']; + + return $tree; + } + ); + + $output->writeln("Start Publishing..."); - echo "Start Publishing...\n"; $publisher = new Publisher($confluence); + $publisher->output = $output; + $publisher->width = $width; $publisher->publish($tree); - - echo "Done !\n"; } private function generateRecursive(Entry $tree, Config $params, $base_url = '') diff --git a/libs/Format/Confluence/Publisher.php b/libs/Format/Confluence/Publisher.php index cb46b3c..8aa93af 100644 --- a/libs/Format/Confluence/Publisher.php +++ b/libs/Format/Confluence/Publisher.php @@ -2,10 +2,13 @@ use GuzzleHttp\Exception\BadResponseException; use GuzzleHttp\Exception\ParseException; +use Todaymade\Daux\Format\Base\RunAction; class Publisher { + use RunAction; + /** * @var Api */ @@ -21,6 +24,19 @@ class Publisher */ protected $previous_title; + /** + * @var string terminal width + */ + public $width; + + /** + * @var + */ + public $output; + + /** + * @param $confluence + */ public function __construct($confluence) { $this->confluence = $confluence; @@ -29,6 +45,14 @@ class Publisher $this->client->setSpace($confluence['space_id']); } + public function run($title, $closure) { + try { + return $this->runAction($title, $this->output, $this->width, $closure); + } catch (BadResponseException $e) { + echo " X Failed with message: " . $e->getMessage() . "\n"; + } + } + public function publish(array $tree) { echo "Finding Root Page...\n"; @@ -41,15 +65,23 @@ class Publisher } } - echo "Getting already published pages...\n"; - if ($published != null) { - $published['children'] = $this->client->getHierarchy($published['id']); - } + $this->run( + "Getting already published pages...", + function() use (&$published) { + if ($published != null) { + $published['children'] = $this->client->getHierarchy($published['id']); + } + } + ); - echo "Create placeholder pages...\n"; - $published = $this->createRecursive($this->confluence['ancestor_id'], $tree, $published); + $published = $this->run( + "Create placeholder pages...", + function() use ($tree, $published) { + return $this->createRecursive($this->confluence['ancestor_id'], $tree, $published); + } + ); - echo "Publishing updates...\n"; + $this->output->writeLn("Publishing updates..."); $this->updateRecursive($this->confluence['ancestor_id'], $tree, $published); } @@ -195,32 +227,30 @@ class Publisher echo "Updating Pages...\n"; } - echo "- " . $this->niceTitle($entry['file']->getUrl()); - - try { - if ($this->shouldUpdate($entry['page'], $published)) { - $this->client->updatePage( - $parent_id, - $published['id'], - $published['version'] + 1, - $entry['title'], - $entry['page']->getContent() - ); - echo " √\n"; - } else { - echo " √ (No update needed)\n"; - } - - if (count($entry['page']->attachments)) { - foreach ($entry['page']->attachments as $attachment) { - echo " With attachment: $attachment[filename]"; - $this->client->uploadAttachment($published['id'], $attachment); - echo " √\n"; + $this->run( + "- " . $this->niceTitle($entry['file']->getUrl()), + function() use ($entry, $published, $parent_id) { + if ($this->shouldUpdate($entry['page'], $published)) { + $this->client->updatePage( + $parent_id, + $published['id'], + $published['version'] + 1, + $entry['title'], + $entry['page']->getContent() + ); } } + ); - } catch (BadResponseException $e) { - echo " X Failed with message: " . $e->getMessage() . "\n"; + if (count($entry['page']->attachments)) { + foreach ($entry['page']->attachments as $attachment) { + $this->run( + " With attachment: $attachment[filename]", + function() use($published, $attachment) { + $this->client->uploadAttachment($published['id'], $attachment); + } + ); + } } } } diff --git a/libs/Format/HTML/Generator.php b/libs/Format/HTML/Generator.php index 32369b1..3f41f84 100644 --- a/libs/Format/HTML/Generator.php +++ b/libs/Format/HTML/Generator.php @@ -1,29 +1,38 @@ getParams(); if (is_null($destination)) { $destination = $daux->local_base . DS . 'static'; } - echo "Copying Static assets ...\n"; - Helper::copyAssets($destination, $daux->local_base); + $this->runAction( + "Copying Static assets ...", + $output, + $width, + function() use ($destination, $daux) { + Helper::copyAssets($destination, $daux->local_base); + } + ); - echo "Generating ...\n"; - $this->generateRecursive($daux->tree, $destination, $params); - echo "Done !\n"; + $output->writeLn("Generating ..."); + $this->generateRecursive($daux->tree, $destination, $params, $output, $width); } - private function generateRecursive($tree, $output_dir, $params, $base_url = '') + private function generateRecursive($tree, $output_dir, $params, $output, $width, $base_url = '') { $params['base_url'] = $params['base_page'] = $base_url; @@ -38,17 +47,29 @@ class Generator if ($node instanceof Directory) { $new_output_dir = $output_dir . DS . $key; @mkdir($new_output_dir); - $this->generateRecursive($node, $new_output_dir, $params, '../' . $base_url); + $this->generateRecursive($node, $new_output_dir, $params, $output, $width, '../' . $base_url); } elseif ($node instanceof Content) { - echo "- " . $node->getUrl() . "\n"; - $params['request'] = $node->getUrl(); - $params['file_uri'] = $node->getName(); + $this->runAction( + "- " . $node->getUrl(), + $output, + $width, + function() use ($node, $output_dir, $key, $params) { + $params['request'] = $node->getUrl(); + $params['file_uri'] = $node->getName(); - $page = MarkdownPage::fromFile($node, $params); - file_put_contents($output_dir . DS . $key, $page->getContent()); + $page = MarkdownPage::fromFile($node, $params); + file_put_contents($output_dir . DS . $key, $page->getContent()); + } + ); } else { - echo "- " . $node->getUrl() . "\n"; - copy($node->getPath(), $output_dir . DS . $key); + $this->runAction( + "- " . $node->getUrl(), + $output, + $width, + function() use ($node, $output_dir, $key) { + copy($node->getPath(), $output_dir . DS . $key); + } + ); } } } diff --git a/libs/Generator/Application.php b/libs/Generator/Application.php new file mode 100644 index 0000000..58fdc2b --- /dev/null +++ b/libs/Generator/Application.php @@ -0,0 +1,49 @@ +setArguments(); + + return $inputDefinition; + } +} diff --git a/libs/Generator/Command.php b/libs/Generator/Command.php new file mode 100644 index 0000000..69dca16 --- /dev/null +++ b/libs/Generator/Command.php @@ -0,0 +1,49 @@ +setName('generate') + ->setDescription('Generate documentation') + ->addOption('configuration', 'c', InputArgument::OPTIONAL, 'Configuration file') + ->addOption('format', 'f', InputArgument::OPTIONAL, 'Output format, html or confluence', 'html') + ->addOption('processor', 'p', InputArgument::OPTIONAL, 'Manipulations on the tree', 'none') + ->addOption('destination', 'd', InputArgument::OPTIONAL, $description, 'static'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $daux = new Daux(Daux::STATIC_MODE); + $daux->initialize($input->getOption('configuration')); + + $width = $this->getApplication()->getTerminalDimensions()[0]; + + switch(strtolower($input->getOption('processor'))) { + case 'none': + default: + //nothing + } + + switch(strtolower($input->getOption('format'))) { + case 'confluence': + (new ConfluenceGenerator())->generate($daux, $input->getOption('destination'), $output, $width); + break; + case 'html': + default: + (new HTMLGenerator())->generate($daux, $input->getOption('destination'), $output, $width); + } + } +} diff --git a/libs/Generator/Generator.php b/libs/Generator/Generator.php deleted file mode 100644 index 46dd8c8..0000000 --- a/libs/Generator/Generator.php +++ /dev/null @@ -1,23 +0,0 @@ -initialize($options['config']); - - switch(strtolower($options['format'])) { - case 'confluence': - (new ConfluenceGenerator())->generate($daux, $options['destination']); - break; - case 'html': - default: - (new HTMLGenerator())->generate($daux, $options['destination']); - } - } -} diff --git a/libs/Generator/Getopt.php b/libs/Generator/Getopt.php deleted file mode 100644 index acfb222..0000000 --- a/libs/Generator/Getopt.php +++ /dev/null @@ -1,330 +0,0 @@ -argv = $argv?: $_SERVER['argv']; - - $this->progname = $this->argv[0]; - $this->addRules($rules); - } - - /** - * Return a list of options that have been seen in the current argv. - * - * @return array - */ - public function getOptions() - { - $this->parse(); - return $this->options; - } - - /** - * Return the state of the option seen on the command line of the - * current application invocation. - * - * This function returns true, or the parameter value to the option, if any. - * If the option was not given, this function returns false. - * - * @param string $flag - * @return mixed - */ - public function getOption($flag) - { - $this->parse(); - - $flag = strtolower($flag); - - if (isset($this->ruleMap[$flag])) { - $flag = $this->ruleMap[$flag]; - if (isset($this->options[$flag])) { - return $this->options[$flag]; - } - } - return; - } - - /** - * Return a useful option reference, formatted for display in an - * error message. - * - * Note that this usage information is provided in most Exceptions - * generated by this class. - * - * @return string - */ - public function getUsageMessage() - { - $usage = "Usage: {$this->progname} [ options ]\n"; - $maxLen = 20; - $lines = array(); - foreach ($this->rules as $rule) { - if (isset($rule['isFreeformFlag'])) { - continue; - } - $flags = array(); - if (is_array($rule['alias'])) { - foreach ($rule['alias'] as $flag) { - $flags[] = (strlen($flag) == 1 ? '-' : '--') . $flag; - } - } - $linepart['name'] = implode('|', $flags); - if (isset($rule['param']) && $rule['param'] != 'none') { - $linepart['name'] .= '=""'; - switch ($rule['param']) { - case 'optional': - $linepart['name'] .= " (optional)"; - break; - case 'required': - $linepart['name'] .= " (required)"; - break; - } - } - if (strlen($linepart['name']) > $maxLen) { - $maxLen = strlen($linepart['name']); - } - $linepart['help'] = ''; - if (isset($rule['help'])) { - $linepart['help'] .= $rule['help']; - } - $lines[] = $linepart; - } - foreach ($lines as $linepart) { - $usage .= sprintf( - "%s %s\n", - str_pad($linepart['name'], $maxLen), - $linepart['help'] - ); - } - return $usage; - } - - /** - * Parse command-line arguments and find both long and short - * options. - * - * Also find option parameters, and remaining arguments after - * all options have been parsed. - * - * @return self - */ - public function parse() - { - if ($this->parsed === true) { - return $this; - } - - if (in_array('--help', $this->argv)) { - echo $this->getUsageMessage(); - exit; - } - - $this->options = array(); - - $long = []; - $short = ''; - foreach ($this->rules as $rule) { - foreach ($rule['alias'] as $alias) { - $prepared = $alias; - if ($rule['param'] == 'optional') { - $prepared .= '::'; - } elseif ($rule['param'] == 'required') { - $prepared .= ':'; - } - - if (strlen($alias) == 1) { - $short .= $prepared; - } else { - $long[] = $prepared; - } - } - } - - $result = getopt($short, $long); - - foreach ($result as $key => $value) { - $this->options[$this->ruleMap[$key]] = $value; - } - - $this->parsed = true; - - return $this; - } - - /** - * Define legal options using the Zend-style format. - * - * @param array $rules - * @throws InvalidArgumentException - */ - protected function addRules($rules) - { - foreach ($rules as $ruleCode => $helpMessage) { - // this may have to translate the long parm type if there - // are any complaints that =string will not work (even though that use - // case is not documented) - if (in_array(substr($ruleCode, -2, 1), array('-', '='))) { - $flagList = substr($ruleCode, 0, -2); - $delimiter = substr($ruleCode, -2, 1); - } else { - $flagList = $ruleCode; - $delimiter = $paramType = null; - } - - $flagList = strtolower($flagList); - - $flags = explode('|', $flagList); - $rule = array(); - $mainFlag = $flags[0]; - foreach ($flags as $flag) { - if (empty($flag)) { - throw new InvalidArgumentException("Blank flag not allowed in rule \"$ruleCode\"."); - } - - if (isset($this->ruleMap[$flag]) || (strlen($flag) != 1 && isset($this->rules[$flag]))) { - throw new InvalidArgumentException("Option \"-$flag\" is being defined more than once."); - } - - $this->ruleMap[$flag] = $mainFlag; - $rule['alias'][] = $flag; - } - $rule['param'] = 'none'; - if (isset($delimiter)) { - $rule['param'] = $delimiter == self::PARAM_REQUIRED? 'required' : 'optional'; - } - - $rule['help'] = $helpMessage; - $this->rules[$mainFlag] = $rule; - } - } -} diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 27c0cb8..34988f8 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,5 +7,7 @@ $baseDir = dirname($vendorDir); return array( 'Todaymade\\Daux\\' => array($baseDir . '/libs'), + 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), + 'React\\Promise\\' => array($vendorDir . '/react/promise/src'), 'League\\Plates\\' => array($vendorDir . '/league/plates/src'), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 038a10c..065a379 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -93,5 +93,64 @@ "templating", "views" ] + }, + { + "name": "symfony/console", + "version": "v2.7.2", + "version_normalized": "2.7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "8cf484449130cabfd98dcb4694ca9945802a21ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/8cf484449130cabfd98dcb4694ca9945802a21ed", + "reference": "8cf484449130cabfd98dcb4694ca9945802a21ed", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "time": "2015-07-09 16:07:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com" } ]