2 namespace Robo\Task\ApiGen;
4 use Robo\Contract\CommandInterface;
5 use Robo\Exception\TaskException;
6 use Robo\Task\BaseTask;
10 * Executes ApiGen command to generate documentation
15 * $this->taskApiGen('./vendor/apigen/apigen.phar')
16 * ->config('./apigen.neon')
17 * ->templateConfig('vendor/apigen/apigen/templates/bootstrap/config.neon')
23 class ApiGen extends BaseTask implements CommandInterface
25 use \Robo\Common\ExecOneCommand;
28 const BOOL_YES = 'yes';
34 protected $operation = 'generate';
37 * @param null|string $pathToApiGen
39 * @throws \Robo\Exception\TaskException
41 public function __construct($pathToApiGen = null)
43 $this->command = $pathToApiGen;
45 preg_match('/((?:.+)?apigen(?:\.phar)?) ?( \w+)? ?(.+)?/', $this->command, $command_parts);
46 if (count($command_parts) === 3) {
47 list(, $this->command, $this->operation) = $command_parts;
49 if (count($command_parts) === 4) {
50 list(, $this->command, $this->operation, $arg) = $command_parts;
53 if (!$this->command) {
54 $this->command = $this->findExecutablePhar('apigen');
56 if (!$this->command) {
57 throw new TaskException(__CLASS__, "No apigen installation found");
62 * Pass methods parameters as arguments to executable. Argument values
63 * are automatically escaped.
65 * @param string|string[] $args
69 public function args($args)
71 if (!is_array($args)) {
72 $args = func_get_args();
74 $args = array_map(function ($arg) {
75 if (preg_match('/^\w+$/', trim($arg)) === 1) {
76 $this->operation = $arg;
81 $args = array_filter($args);
82 $this->arguments .= ' ' . implode(' ', array_map('static::escape', $args));
87 * @param array|Traversable|string $arg a single object or something traversable
89 * @return array|Traversable the provided argument if it was already traversable, or the given
90 * argument returned as a one-element array
92 protected static function forceTraversable($arg)
95 if (!is_array($traversable) && !($traversable instanceof \Traversable)) {
96 $traversable = array($traversable);
102 * @param array|string $arg a single argument or an array of multiple string values
104 * @return string a comma-separated string of all of the provided arguments, suitable
105 * as a command-line "list" type argument for ApiGen
107 protected static function asList($arg)
109 $normalized = is_array($arg) ? $arg : array($arg);
110 return implode(',', $normalized);
114 * @param bool|string $val an argument to be normalized
115 * @param string $default one of self::BOOL_YES or self::BOOK_NO if the provided
116 * value could not deterministically be converted to a
119 * @return string the given value as a command-line "yes|no" type of argument for ApiGen,
120 * or the default value if none could be determined
122 protected static function asTextBool($val, $default)
124 if ($val === self::BOOL_YES || $val === self::BOOL_NO) {
128 return self::BOOL_NO;
131 return self::BOOL_YES;
133 if (is_numeric($val) && $val != 0) {
134 return self::BOOL_YES;
136 if (strcasecmp($val[0], 'y') === 0) {
137 return self::BOOL_YES;
139 if (strcasecmp($val[0], 'n') === 0) {
140 return self::BOOL_NO;
142 // meh, good enough, let apigen sort it out
147 * @param string $config
151 public function config($config)
153 $this->option('config', $config);
158 * @param array|string|Traversable $src one or more source values
162 public function source($src)
164 foreach (self::forceTraversable($src) as $source) {
165 $this->option('source', $source);
171 * @param string $dest
175 public function destination($dest)
177 $this->option('destination', $dest);
182 * @param array|string $exts one or more extensions
186 public function extensions($exts)
188 $this->option('extensions', self::asList($exts));
193 * @param array|string $exclude one or more exclusions
197 public function exclude($exclude)
199 foreach (self::forceTraversable($exclude) as $excl) {
200 $this->option('exclude', $excl);
206 * @param array|string|Traversable $path one or more skip-doc-path values
210 public function skipDocPath($path)
212 foreach (self::forceTraversable($path) as $skip) {
213 $this->option('skip-doc-path', $skip);
219 * @param array|string|Traversable $prefix one or more skip-doc-prefix values
223 public function skipDocPrefix($prefix)
225 foreach (self::forceTraversable($prefix) as $skip) {
226 $this->option('skip-doc-prefix', $skip);
232 * @param array|string $charset one or more charsets
236 public function charset($charset)
238 $this->option('charset', self::asList($charset));
243 * @param string $name
247 public function mainProjectNamePrefix($name)
249 $this->option('main', $name);
254 * @param string $title
258 public function title($title)
260 $this->option('title', $title);
265 * @param string $baseUrl
269 public function baseUrl($baseUrl)
271 $this->option('base-url', $baseUrl);
280 public function googleCseId($id)
282 $this->option('google-cse-id', $id);
287 * @param string $trackingCode
291 public function googleAnalytics($trackingCode)
293 $this->option('google-analytics', $trackingCode);
298 * @param mixed $templateConfig
302 public function templateConfig($templateConfig)
304 $this->option('template-config', $templateConfig);
309 * @param array|string $tags one or more supported html tags
313 public function allowedHtml($tags)
315 $this->option('allowed-html', self::asList($tags));
320 * @param string $groups
324 public function groups($groups)
326 $this->option('groups', $groups);
331 * @param array|string $types or more supported autocomplete types
335 public function autocomplete($types)
337 $this->option('autocomplete', self::asList($types));
342 * @param array|string $levels one or more access levels
346 public function accessLevels($levels)
348 $this->option('access-levels', self::asList($levels));
353 * @param boolean|string $internal 'yes' or true if internal, 'no' or false if not
357 public function internal($internal)
359 $this->option('internal', self::asTextBool($internal, self::BOOL_NO));
364 * @param boolean|string $php 'yes' or true to generate documentation for internal php classes,
365 * 'no' or false otherwise
369 public function php($php)
371 $this->option('php', self::asTextBool($php, self::BOOL_YES));
376 * @param bool|string $tree 'yes' or true to generate a tree view of classes, 'no' or false otherwise
380 public function tree($tree)
382 $this->option('tree', self::asTextBool($tree, self::BOOL_YES));
387 * @param bool|string $dep 'yes' or true to generate documentation for deprecated classes, 'no' or false otherwise
391 public function deprecated($dep)
393 $this->option('deprecated', self::asTextBool($dep, self::BOOL_NO));
398 * @param bool|string $todo 'yes' or true to document tasks, 'no' or false otherwise
402 public function todo($todo)
404 $this->option('todo', self::asTextBool($todo, self::BOOL_NO));
409 * @param bool|string $src 'yes' or true to generate highlighted source code, 'no' or false otherwise
413 public function sourceCode($src)
415 $this->option('source-code', self::asTextBool($src, self::BOOL_YES));
420 * @param bool|string $zipped 'yes' or true to generate downloadable documentation, 'no' or false otherwise
424 public function download($zipped)
426 $this->option('download', self::asTextBool($zipped, self::BOOL_NO));
430 public function report($path)
432 $this->option('report', $path);
437 * @param bool|string $wipeout 'yes' or true to clear out the destination directory, 'no' or false otherwise
441 public function wipeout($wipeout)
443 $this->option('wipeout', self::asTextBool($wipeout, self::BOOL_YES));
448 * @param bool|string $quiet 'yes' or true for quiet, 'no' or false otherwise
452 public function quiet($quiet)
454 $this->option('quiet', self::asTextBool($quiet, self::BOOL_NO));
459 * @param bool|string $bar 'yes' or true to display a progress bar, 'no' or false otherwise
463 public function progressbar($bar)
465 $this->option('progressbar', self::asTextBool($bar, self::BOOL_YES));
470 * @param bool|string $colors 'yes' or true colorize the output, 'no' or false otherwise
474 public function colors($colors)
476 $this->option('colors', self::asTextBool($colors, self::BOOL_YES));
481 * @param bool|string $check 'yes' or true to check for updates, 'no' or false otherwise
485 public function updateCheck($check)
487 $this->option('update-check', self::asTextBool($check, self::BOOL_YES));
492 * @param bool|string $debug 'yes' or true to enable debug mode, 'no' or false otherwise
496 public function debug($debug)
498 $this->option('debug', self::asTextBool($debug, self::BOOL_NO));
505 public function getCommand()
507 return "$this->command $this->operation$this->arguments";
513 public function run()
515 $this->printTaskInfo('Running ApiGen {args}', ['args' => $this->arguments]);
516 return $this->executeCommand($this->getCommand());