mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
Allow arc to be run in arcanist/ or libphutil/
Summary: Currently, if you run `arc` in arcanist/ or libphutil/ and your PATH and on-disk configuration are set up so a different version of arc or libphutil are the ones that actually load, we fail with an exception like "running arcanist in a different copy of arcanist is not supported". This causes problems for Harbormaster, since we'd like to be able to run 'arc' in a copy of libphutil/ and have it execute unit tests for that copy rather than failing abruptly. So, if we detect that we're in arcanist/ or libphutil/, execute 'arc' again with the same arguments but force it to load the working copy in place of either the 'arcanist/' or the 'libphutil/' that it decided to load. This is pretty much horrible black magic. Test Plan: Ran 'arc list --trace' inside copies of libphutil/ and arcanist/ outside of the normal include chain. Saw it detect these, emit a message, and re-execute itself correctly. Reviewers: btrahan, vrana Reviewed By: vrana CC: aran Maniphest Tasks: T1049 Differential Revision: https://secure.phabricator.com/D4225
This commit is contained in:
parent
6823706c76
commit
b9fa71f7e1
2 changed files with 75 additions and 1 deletions
|
@ -40,7 +40,11 @@ function arcanist_adjust_php_include_path() {
|
|||
}
|
||||
arcanist_adjust_php_include_path();
|
||||
|
||||
@include_once 'libphutil/scripts/__init_script__.php';
|
||||
if (getenv('ARC_PHUTIL_PATH')) {
|
||||
@include_once getenv('ARC_PHUTIL_PATH').'/scripts/__init_script__.php';
|
||||
} else {
|
||||
@include_once 'libphutil/scripts/__init_script__.php';
|
||||
}
|
||||
if (!@constant('__LIBPHUTIL__')) {
|
||||
echo "ERROR: Unable to load libphutil. Put libphutil/ next to arcanist/, or ".
|
||||
"update your PHP 'include_path' to include the parent directory of ".
|
||||
|
|
|
@ -73,6 +73,11 @@ try {
|
|||
$system_config = ArcanistBaseWorkflow::readSystemArcConfig();
|
||||
$working_copy = ArcanistWorkingCopyIdentity::newFromPath($working_directory);
|
||||
|
||||
reenter_if_this_is_arcanist_or_libphutil(
|
||||
$console,
|
||||
$working_copy,
|
||||
$original_argv);
|
||||
|
||||
// Load additional libraries, which can provide new classes like configuration
|
||||
// overrides, linters and lint engines, unit test engines, etc.
|
||||
|
||||
|
@ -535,3 +540,68 @@ function arcanist_load_libraries(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: SPOOKY BLACK MAGIC
|
||||
*
|
||||
* When arc is run in a copy of arcanist other than itself, or a copy of
|
||||
* libphutil other than the one we loaded, reenter the script and force it
|
||||
* to use the current working directory instead of the default.
|
||||
*
|
||||
* In the case of execution inside arcanist/, we force execution of the local
|
||||
* arc binary.
|
||||
*
|
||||
* In the case of execution inside libphutil/, we force the local copy to load
|
||||
* instead of the one selected by default rules.
|
||||
*
|
||||
* @param PhutilConsole Console.
|
||||
* @param ArcanistWorkingCopyIdentity The current working copy.
|
||||
* @param array Original arc arguments.
|
||||
* @return void
|
||||
*/
|
||||
function reenter_if_this_is_arcanist_or_libphutil(
|
||||
PhutilConsole $console,
|
||||
ArcanistWorkingCopyIdentity $working_copy,
|
||||
array $original_argv) {
|
||||
|
||||
$project_id = $working_copy->getProjectID();
|
||||
if ($project_id != 'arcanist' && $project_id != 'libphutil') {
|
||||
// We're not in a copy of arcanist or libphutil.
|
||||
return;
|
||||
}
|
||||
|
||||
$library_names = array(
|
||||
'arcanist' => 'arcanist',
|
||||
'libphutil' => 'phutil',
|
||||
);
|
||||
|
||||
$library_root = phutil_get_library_root($library_names[$project_id]);
|
||||
$project_root = $working_copy->getProjectRoot();
|
||||
if (Filesystem::isDescendant($library_root, $project_root)) {
|
||||
// We're in a copy of arcanist or libphutil, but already loaded the correct
|
||||
// copy. Continue execution normally.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($project_id == 'libphutil') {
|
||||
$console->writeLog(
|
||||
"This is libphutil! Forcing this copy to load...\n");
|
||||
$original_argv[0] = dirname(phutil_get_library_root('arcanist')).'/bin/arc';
|
||||
$libphutil_path = $project_root;
|
||||
} else {
|
||||
$console->writeLog(
|
||||
"This is arcanist! Forcing this copy to run...\n");
|
||||
$original_argv[0] = $project_root.'/bin/arc';
|
||||
$libphutil_path = dirname(phutil_get_library_root('phutil'));
|
||||
}
|
||||
|
||||
$err = phutil_passthru(
|
||||
phutil_is_windows()
|
||||
? 'set ARC_PHUTIL_PATH=%s & %Ls'
|
||||
: 'ARC_PHUTIL_PATH=%s %Ls',
|
||||
$libphutil_path,
|
||||
$original_argv);
|
||||
|
||||
exit($err);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue