178 lines
5.3 KiB
PHP
178 lines
5.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Command line interface for generating autoload manifests
|
|
*
|
|
* @package Tools
|
|
* @version 1.0
|
|
* @since 1.0
|
|
*/
|
|
|
|
/**
|
|
* Command line tools
|
|
*/
|
|
require_once 'cli.php';
|
|
|
|
/**
|
|
* Prints usage
|
|
*/
|
|
function usage() {
|
|
$usage = new Usage(
|
|
'Manifest Builder 1.0',
|
|
'php ' . basename(__FIlE__),
|
|
'Builds a manifest file suitable for use by Autoloader',
|
|
'Tommy Montgomery',
|
|
'2009'
|
|
);
|
|
|
|
global $switches;
|
|
$usage->setSwitches($switches);
|
|
|
|
echo $usage;
|
|
}
|
|
|
|
if (!extension_loaded('tokenizer')) {
|
|
throw new Exception('The "tokenizer" extension must be loaded to use this script');
|
|
}
|
|
|
|
global $switches;
|
|
$switches = new CliSwitchCollection();
|
|
$switches->addSwitch(new CliSwitch('directory', 'd', true, 'dir1,dir2,...', 'Comma-delimited list of directories'))
|
|
->addSwitch(new CliSwitch('version', 'v', true, 'version_number', 'Version number for use in @version tag'))
|
|
->addSwitch(new CliSwitch('package', 'p', true, 'package_name ', 'Name of the package for use in @package tag'))
|
|
->addSwitch(new CliSwitch('output', 'o', false, 'file', 'Name of the output file, defaults to stdout if empty'))
|
|
->addSwitch(new CliSwitch('quiet', 'q', false, null, 'Do not print progress messages'))
|
|
->addSwitch(new CliSwitch('recursive', 'r', false, null, 'Recursively walk the directories'))
|
|
->addSwitch(new CliSwitch('ignore', 'i', false, 'pattern1,pattern2...', 'File patterns to ignore'))
|
|
->addSwitch(new CliSwitch('base-dir', 'b', true, 'dir', 'Base directory'));
|
|
|
|
array_shift($argv);
|
|
$args = Cli::parseArgs($argv, $switches);
|
|
$args = $args['switches']; //don't care about non-switch stuff
|
|
|
|
if (!isset($args['directory'], $args['version'], $args['package'], $args['base-dir'])) {
|
|
usage();
|
|
fwrite(STDERR, "Missing a required argument\n");
|
|
exit(1);
|
|
}
|
|
|
|
$dirs = explode(',', $args['directory']);
|
|
|
|
if (!is_dir($args['base-dir'])) {
|
|
fwrite(STDERR, $args['base-dir'] . ' is not a directory');
|
|
exit(1);
|
|
}
|
|
|
|
$args['recursive'] = array_key_exists('recursive', $args);
|
|
$args['quiet'] = array_key_exists('quiet', $args);
|
|
|
|
$date = date('Y-m-d H:i:s');
|
|
$self = basename(__FILE__);
|
|
$data = <<<ENDDATA
|
|
<?php
|
|
|
|
/**
|
|
* Autoload manifest
|
|
*
|
|
* Autogenerated by $self on $date
|
|
*
|
|
* @package $args[package]
|
|
* @version $args[version]
|
|
* @since 1.0
|
|
*/
|
|
|
|
return array(
|
|
|
|
ENDDATA;
|
|
|
|
$classes = array();
|
|
$maxClassNameLength = 0;
|
|
|
|
$ignore = array(DIRECTORY_SEPARATOR . '.');
|
|
if (isset($args['ignore']) && !empty($args['ignore'])) {
|
|
$ignore = array_merge($ignore, explode(',', $args['ignore']));
|
|
}
|
|
|
|
foreach ($dirs as $dir) {
|
|
if (!is_dir($dir)) {
|
|
fwrite(STDERR, $dir . ' is not a directory... skipping');
|
|
continue;
|
|
}
|
|
|
|
$iterator = $args['recursive'] ? new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) : new DirectoryIterator($dir);
|
|
|
|
foreach ($iterator as $file) {
|
|
if (
|
|
$file->isFile() &&
|
|
strpos($file->getPathName(), DIRECTORY_SEPARATOR . '.') === false &&
|
|
substr($file->getFileName(), -4) === '.php' &&
|
|
array_reduce($ignore, create_function('$old, $new', 'return $old && strpos(\'' . addslashes($file->getPathName()) . '\', $new) === false;'), true)
|
|
) {
|
|
if (!$args['quiet']) {
|
|
echo 'Processing ' . $file->getPathName() . "\n";
|
|
}
|
|
|
|
$tokens = token_get_all(file_get_contents($file->getPathName()));
|
|
$count = count($tokens);
|
|
for ($i = 0; $i < $count; $i++) {
|
|
if (is_array($tokens[$i])) {
|
|
if ($tokens[$i][0] === T_CLASS || $tokens[$i][0] === T_INTERFACE) {
|
|
//get class name
|
|
if (isset($tokens[$i + 2]) && is_array($tokens[$i + 2]) && $tokens[$i + 2][0] === T_STRING) {
|
|
$className = $tokens[$i + 2][1];
|
|
if (isset($classes[$className]) && !$args['quiet']) {
|
|
fwrite(STDERR, '******WARNING: FOUND DUPLICATE CLASS (' . $className . ')******' . "\n");
|
|
}
|
|
|
|
$classes[$className] = ltrim(str_replace(array($args['base-dir'], DIRECTORY_SEPARATOR), array('', '/'), $file->getPathName()), '/');
|
|
$maxClassNameLength = max($maxClassNameLength, strlen($className));
|
|
$i += 2; //loop unroll FTW!
|
|
|
|
if (!$args['quiet']) {
|
|
echo 'Added class/interface ' . $className . "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
unset($tokens);
|
|
}
|
|
}
|
|
}
|
|
|
|
echo "\n" . '# of classes: ' . count($classes) . "\n\n";
|
|
|
|
$func = create_function(
|
|
'&$value, $key',
|
|
'$value = "\t\t\'$key\'" . str_repeat(\' \', ' . $maxClassNameLength . ' - strlen($key)) . " => \'$value\'";'
|
|
);
|
|
|
|
ksort($classes);
|
|
array_walk($classes, $func);
|
|
|
|
$data .= implode(",\n", $classes) . "\n\t);\n\n?>";
|
|
if (isset($args['output']) && !is_dir(dirname($args['output'])) && !mkdir(dirname($args['output']), 0777, true)) {
|
|
fwrite(STDERR, 'Unable to mkdir(): ' . dirname($args['output']));
|
|
exit(1);
|
|
} else if (!isset($args['output'])) {
|
|
$args['output'] = 'php://stdout';
|
|
}
|
|
|
|
if (is_dir($args['output'])) {
|
|
$args['output'] .= DIRECTORY_SEPARATOR . 'manifest.php';
|
|
}
|
|
|
|
$fp = fopen($args['output'], 'w');
|
|
if (!$fp) {
|
|
fwrite(STDERR, 'Unable to open ' . $args['output'] . ' for writing');
|
|
exit(1);
|
|
}
|
|
|
|
fwrite($fp, $data);
|
|
fclose($fp);
|
|
echo 'Wrote data to ' . $args['output'] . ' (' . strlen($data) . ' bytes)' . "\n";
|
|
|
|
exit(0);
|
|
|
|
?>
|