1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 08:12:40 +01:00
phorge-arcanist/scripts/phutil_mapper.php
2011-01-09 15:22:25 -08:00

128 lines
3.5 KiB
PHP
Executable file

#!/usr/bin/env php
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once dirname(__FILE__).'/__init_script__.php';
if ($argc != 2) {
$self = basename($argv[0]);
echo "usage: {$self} <phutil_library_root>\n";
exit(1);
}
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'future/exec');
$root = Filesystem::resolvePath($argv[1]);
if (!@file_exists($root.'/__phutil_library_init__.php')) {
throw new Exception("Provided path is not a phutil library.");
}
echo "Finding phutil modules...\n";
list($stdout) = execx(
"(cd %s && find . -type d -path '*/.*' -prune -o -type d -print0)",
$root);
$futures = array();
foreach (array_filter(explode("\0", $stdout)) as $dir) {
if ($dir == '.') {
continue;
}
$module = preg_replace('@^\\./@', '', $dir);
$futures[$module] = new ExecFuture(
'%s %s',
dirname(__FILE__).'/phutil_analyzer.php',
$root.'/'.$module);
}
echo "Analyzing ".number_format(count($futures))." modules";
$class_map = array();
$requires_class_map = array();
$requires_interface_map = array();
$function_map = array();
foreach (Futures($futures)->limit(16) as $module => $future) {
echo ".";
$spec = $future->resolveJSON();
foreach (array('class', 'interface') as $type) {
foreach ($spec['declares'][$type] as $class => $where) {
if (!empty($class_map[$class])) {
$prior = $class_map[$class];
echo "\n";
echo "Error: definition of {$type} '{$class}' in module '{$module}' ".
"duplicates prior definition in module '{$prior}'.";
echo "\n";
exit(1);
}
$class_map[$class] = $module;
}
}
if (!empty($spec['chain']['class'])) {
$requires_class_map += $spec['chain']['class'];
}
if (!empty($spec['chain']['interface'])) {
$requires_interface_map += $spec['chain']['interface'];
}
foreach ($spec['declares']['function'] as $function => $where) {
if (!empty($function_map[$function])) {
$prior = $function_map[$function];
echo "\n";
echo "Error: definition of function '{$function}' in module '{$module}' ".
"duplicates prior definition in module '{$prior}'.";
echo "\n";
exit(1);
}
$function_map[$function] = $module;
}
}
echo "\n";
ksort($class_map);
ksort($requires_class_map);
ksort($requires_interface_map);
ksort($function_map);
$library_map = array(
'class' => $class_map,
'function' => $function_map,
'requires_class' => $requires_class_map,
'requires_interface' => $requires_interface_map,
);
$library_map = var_export($library_map, $return_string = true);
$library_map = preg_replace('/\s+$/m', '', $library_map);
$library_map = preg_replace('/array \(/', 'array(', $library_map);
$at = '@';
$map_file = <<<EOPHP
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* {$at}generated
*/
phutil_register_library_map({$library_map});
EOPHP;
echo "Writing library map file...\n";
Filesystem::writeFile($root.'/__phutil_library_map__.php', $map_file);
echo "Done.\n";