woocommerce/apigen/apigen.php

254 lines
8.4 KiB
PHP

#!/usr/bin/env php
<?php
/**
* ApiGen 2.8.0 - API documentation generator for PHP 5.3+
*
* Copyright (c) 2010-2011 David Grudl (http://davidgrudl.com)
* Copyright (c) 2011-2012 Jaroslav Hanslík (https://github.com/kukulich)
* Copyright (c) 2011-2012 Ondřej Nešpor (https://github.com/Andrewsville)
*
* For the full copyright and license information, please view
* the file LICENSE.md that was distributed with this source code.
*/
namespace ApiGen;
use Nette\Diagnostics\Debugger;
use TokenReflection;
// Safe locale and timezone
setlocale(LC_ALL, 'C');
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}
if (false === strpos('@php_dir@', '@php_dir')) {
// PEAR package
@include '@php_dir@/Nette/loader.php';
@include '@php_dir@/Texy/texy.php';
} else {
// Downloaded package
set_include_path(
__DIR__ . PATH_SEPARATOR .
__DIR__ . '/libs/FSHL' . PATH_SEPARATOR .
__DIR__ . '/libs/TokenReflection' . PATH_SEPARATOR .
get_include_path()
);
@include __DIR__ . '/libs/Nette/Nette/loader.php';
@include __DIR__ . '/libs/Texy/texy/texy.php';
}
// Autoload
spl_autoload_register(function($class) {
$class = trim($class, '\\');
require sprintf('%s.php', str_replace('\\', DIRECTORY_SEPARATOR, $class));
});
try {
// Check dependencies
foreach (array('json', 'iconv', 'mbstring', 'tokenizer') as $extension) {
if (!extension_loaded($extension)) {
printf("Required extension missing: %s\n", $extension);
die(1);
}
}
if (!class_exists('Nette\\Diagnostics\\Debugger')) {
echo "Required dependency missing: Nette Framework\n";
die(1);
}
if (!class_exists('Texy')) {
echo "Required dependency missing: Texy library\n";
die(1);
}
if (!class_exists('FSHL\\Highlighter')) {
echo "Required dependency missing: FSHL library\n";
die(1);
}
if (!class_exists('TokenReflection\\Broker')) {
echo "Required dependency missing: TokenReflection library\n";
die(1);
}
Debugger::$strictMode = true;
Debugger::$onFatalError[] = function() {
echo "\nFor more information turn on the debug mode using the --debug option.\n";
};
Debugger::enable(Debugger::PRODUCTION, false);
$start = new \DateTime();
$options = $_SERVER['argv'];
array_shift($options);
$config = new Config();
$config->processCliOptions($options);
$generator = new Generator($config);
// Help
if ($config->isHelpRequested()) {
echo $generator->colorize($generator->getHeader());
echo $generator->colorize($config->getHelp());
die();
}
// Prepare configuration
$config->prepare();
if ($config->debug) {
Debugger::$onFatalError = array();
Debugger::enable(Debugger::DEVELOPMENT, false);
}
$generator->output($generator->getHeader());
// Check for update (only in production mode)
if ($config->updateCheck && !$config->debug) {
ini_set('default_socket_timeout', 5);
$latestVersion = @file_get_contents('http://pear.apigen.org/rest/r/apigen/latest.txt');
if (false !== $latestVersion && version_compare(trim($latestVersion), Generator::VERSION, '>')) {
$generator->output(sprintf("New version @header@%s@c available\n\n", $latestVersion));
}
}
// Scan
if (count($config->source) > 1) {
$generator->output(sprintf("Scanning\n @value@%s@c\n", implode("\n ", $config->source)));
} else {
$generator->output(sprintf("Scanning @value@%s@c\n", $config->source[0]));
}
if (count($config->exclude) > 1) {
$generator->output(sprintf("Excluding\n @value@%s@c\n", implode("\n ", $config->exclude)));
} elseif (!empty($config->exclude)) {
$generator->output(sprintf("Excluding @value@%s@c\n", $config->exclude[0]));
}
$parsed = $generator->parse();
if (count($parsed->errors) > 1) {
$generator->output(sprintf("@error@Found %d errors@c\n\n", count($parsed->errors)));
$no = 1;
foreach ($parsed->errors as $e) {
if ($e instanceof TokenReflection\Exception\ParseException) {
$generator->output(sprintf("@error@%d.@c The TokenReflection library threw an exception while parsing the file @value@%s@c.\n", $no, $e->getFileName()));
if ($config->debug) {
$generator->output("\nThis can have two reasons: a) the source code in the file is not valid or b) you have just found a bug in the TokenReflection library.\n\n");
$generator->output("If the license allows it please send the whole file or at least the following fragment describing where exacly is the problem along with the backtrace to apigen@apigen.org. Thank you!\n\n");
$token = $e->getToken();
$sender = $e->getSender();
if (!empty($token)) {
$generator->output(
sprintf(
"The cause of the exception \"%s\" was the @value@%s@c token (line @count@%d@c) in following part of %s source code:\n\n",
$e->getMessage(),
$e->getTokenName(),
$e->getExceptionLine(),
$sender && $sender->getName() ? '@value@' . $sender->getPrettyName() . '@c' : 'the'
)
);
} else {
$generator->output(
sprintf(
"The exception \"%s\" was thrown when processing %s source code:\n\n",
$e->getMessage(),
$sender && $sender->getName() ? '@value@' . $sender->getPrettyName() . '@c' : 'the'
)
);
}
$generator->output($e->getSourcePart(true) . "\n\nThe exception backtrace is following:\n\n" . $e->getTraceAsString() . "\n\n");
}
} elseif ($e instanceof TokenReflection\Exception\FileProcessingException) {
$generator->output(sprintf("@error@%d.@c %s\n", $no, $e->getMessage()));
if ($config->debug) {
$generator->output("\n" . $e->getDetail() . "\n\n");
}
} else {
$generator->output(sprintf("@error@%d.@c %s\n", $no, $e->getMessage()));
if ($config->debug) {
$trace = $e->getTraceAsString();
while ($e = $e->getPrevious()) {
$generator->output(sprintf("\n%s", $e->getMessage()));
$trace = $e->getTraceAsString();
}
$generator->output(sprintf("\n%s\n\n", $trace));
}
}
$no++;
}
if (!$config->debug) {
$generator->output("\nEnable the debug mode (@option@--debug@c) to see more details.\n\n");
}
}
$generator->output(sprintf("Found @count@%d@c classes, @count@%d@c constants, @count@%d@c functions and other @count@%d@c used PHP internal classes\n", $parsed->classes, $parsed->constants, $parsed->functions, $parsed->internalClasses));
$generator->output(sprintf("Documentation for @count@%d@c classes, @count@%d@c constants, @count@%d@c functions and other @count@%d@c used PHP internal classes will be generated\n", $parsed->documentedClasses, $parsed->documentedConstants, $parsed->documentedFunctions, $parsed->documentedInternalClasses));
// Generating
$generator->output(sprintf("Using template config file @value@%s@c\n", $config->templateConfig));
if ($config->wipeout && is_dir($config->destination)) {
$generator->output("Wiping out destination directory\n");
if (!$generator->wipeOutDestination()) {
throw new \RuntimeException('Cannot wipe out destination directory');
}
}
$generator->output(sprintf("Generating to directory @value@%s@c\n", $config->destination));
$skipping = array_merge($config->skipDocPath, $config->skipDocPrefix);
if (count($skipping) > 1) {
$generator->output(sprintf("Will not generate documentation for\n @value@%s@c\n", implode("\n ", $skipping)));
} elseif (!empty($skipping)) {
$generator->output(sprintf("Will not generate documentation for @value@%s@c\n", $skipping[0]));
}
$generator->generate();
// End
$end = new \DateTime();
$interval = $end->diff($start);
$parts = array();
if ($interval->h > 0) {
$parts[] = sprintf('@count@%d@c hours', $interval->h);
}
if ($interval->i > 0) {
$parts[] = sprintf('@count@%d@c min', $interval->i);
}
if ($interval->s > 0) {
$parts[] = sprintf('@count@%d@c sec', $interval->s);
}
if (empty($parts)) {
$parts[] = sprintf('@count@%d@c sec', 1);
}
$duration = implode(' ', $parts);
$generator->output(sprintf("Done. Total time: %s, used: @count@%d@c MB RAM\n", $duration, round(memory_get_peak_usage(true) / 1024 / 1024)));
} catch (ConfigException $e) {
// Configuration error
echo $generator->colorize($generator->getHeader() . sprintf("\n@error@%s@c\n\n", $e->getMessage()) . $config->getHelp());
die(2);
} catch (\Exception $e) {
// Everything else
if ($config->debug) {
do {
echo $generator->colorize(sprintf("\n%s(%d): @error@%s@c", $e->getFile(), $e->getLine(), $e->getMessage()));
$trace = $e->getTraceAsString();
} while ($e = $e->getPrevious());
printf("\n\n%s\n", $trace);
} else {
echo $generator->colorize(sprintf("\n@error@%s@c\n", $e->getMessage()));
}
die(1);
}