1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 06:42:41 +01:00

Allow 'arc' to run without '.arcconfig'

Summary:
This is mostly an onboarding thing, but also allows "arc upload", "arc download", and "arc paste" to work anywhere on the system.

  - Try to read the Phabricator install URI from arc global config if we can't find ".arcconfig".
  - Build a WorkingCopy anyway if we can't find ".arcconfig", as long as we can find ".svn", ".git", or ".hg".
  - Make all the workflows handle "no project ID" at least somewhat gracefully.

Test Plan:
  - Ran "arc diff" in .arcconfig-less Mercurial, Git, and Subversion working copies.
  - Ran "arc upload" and "arc download" from my desktop.
  - Ran "arc paste" from somewhere random.
  - Cleared my config and hit the error, got useful instructions.

Reviewers: btrahan, csilvers

Reviewed By: csilvers

CC: aran

Differential Revision: https://secure.phabricator.com/D2424
This commit is contained in:
epriestley 2012-05-07 15:24:58 -07:00
parent 9063cfbdba
commit 5c684594d4
7 changed files with 68 additions and 25 deletions

View file

@ -146,6 +146,7 @@ try {
} }
$user_config = ArcanistBaseWorkflow::readUserConfigurationFile(); $user_config = ArcanistBaseWorkflow::readUserConfigurationFile();
$global_config = ArcanistBaseWorkflow::readGlobalArcConfig();
$config = $working_copy->getConfig('arcanist_configuration'); $config = $working_copy->getConfig('arcanist_configuration');
if ($config) { if ($config) {
@ -200,24 +201,25 @@ try {
$need_conduit = $need_conduit || $need_conduit = $need_conduit ||
$need_auth; $need_auth;
$need_working_copy = $need_working_copy || $need_working_copy = $need_working_copy ||
$need_conduit ||
$need_repository_api; $need_repository_api;
if ($need_working_copy) { if ($need_working_copy) {
if (!$working_copy->getProjectRoot()) { if (!$working_copy->getProjectRoot()) {
throw new ArcanistUsageException( throw new ArcanistUsageException(
"There is no '.arcconfig' file in this directory or any parent ". "This command must be run in a Git, Mercurial or Subversion working ".
"directory. Create a '.arcconfig' file to configure this project ". "copy.");
"for use with Arcanist.");
} }
$workflow->setWorkingCopy($working_copy); $workflow->setWorkingCopy($working_copy);
} }
if ($force_conduit) { if ($force_conduit) {
$conduit_uri = $force_conduit; $conduit_uri = $force_conduit;
} else { } else {
$conduit_uri = $working_copy->getConduitURI(); if ($working_copy->getConduitURI()) {
$conduit_uri = $working_copy->getConduitURI();
} else {
$conduit_uri = idx($global_config, 'default');
}
} }
if ($conduit_uri) { if ($conduit_uri) {
// Set the URI path to '/api/'. TODO: Originally, I contemplated letting // Set the URI path to '/api/'. TODO: Originally, I contemplated letting
@ -233,9 +235,17 @@ try {
if ($need_conduit) { if ($need_conduit) {
if (!$conduit_uri) { if (!$conduit_uri) {
throw new ArcanistUsageException(
"No Conduit URI is specified in the .arcconfig file for this project. ". $message = phutil_console_format(
"Specify the Conduit URI for the host Differential is running on."); "This command requires arc to connect to a Phabricator install, but ".
"no Phabricator installation is configured. To configure a ".
"Phabricator URI:\n\n".
" - set a default location with `arc set-config default <uri>`; or\n".
" - specify '--conduit-uri=uri' explicitly; or\n".
" - run 'arc' in a working copy with an '.arcconfig'.\n");
$message = phutil_console_wrap($message);
throw new ArcanistUsageException($message);
} }
$workflow->establishConduit(); $workflow->establishConduit();
} }

View file

@ -537,6 +537,10 @@ EODIFF;
// this directory and belong to the same project. // this directory and belong to the same project.
$project = $this->getWorkingCopyIdentity()->getProjectID(); $project = $this->getWorkingCopyIdentity()->getProjectID();
if (!$project) {
return array();
}
$results = $conduit->callMethodSynchronous( $results = $conduit->callMethodSynchronous(
'differential.query', 'differential.query',
$query + array( $query + array(

View file

@ -927,11 +927,11 @@ abstract class ArcanistBaseWorkflow {
} }
} }
protected function readGlobalArcConfig() { public static function readGlobalArcConfig() {
return idx(self::readUserConfigurationFile(), 'config', array()); return idx(self::readUserConfigurationFile(), 'config', array());
} }
protected function writeGlobalArcConfig(array $options) { public static function writeGlobalArcConfig(array $options) {
$config = self::readUserConfigurationFile(); $config = self::readUserConfigurationFile();
$config['config'] = $options; $config['config'] = $options;
self::writeUserConfigurationFile($config); self::writeUserConfigurationFile($config);
@ -1102,12 +1102,21 @@ abstract class ArcanistBaseWorkflow {
return $this->repositoryEncoding; return $this->repositoryEncoding;
} }
$default = 'UTF-8';
$project_id = $this->getWorkingCopy()->getProjectID();
if (!$project_id) {
return $default;
}
$project_info = $this->getConduit()->callMethodSynchronous( $project_info = $this->getConduit()->callMethodSynchronous(
'arcanist.projectinfo', 'arcanist.projectinfo',
array( array(
'name' => $this->getWorkingCopy()->getProjectID(), 'name' => $project_id,
)); ));
$this->repositoryEncoding = nonempty($project_info['encoding'], 'UTF-8');
$this->repositoryEncoding = nonempty($project_info['encoding'], $default);
return $this->repositoryEncoding; return $this->repositoryEncoding;
} }

View file

@ -127,14 +127,17 @@ EOTEXT
$actually_close = true; $actually_close = true;
if ($is_finalize) { if ($is_finalize) {
$project_info = $conduit->callMethodSynchronous( $project_id = $this->getWorkingCopy()->getProjectID();
'arcanist.projectinfo', if ($project_id) {
array( $project_info = $conduit->callMethodSynchronous(
'name' => $this->getWorkingCopy()->getProjectID(), 'arcanist.projectinfo',
)); array(
if ($project_info['tracked'] || 'name' => $project_id,
$revision['status'] != $status_accepted) { ));
$actually_close = false; if ($project_info['tracked'] ||
$revision['status'] != $status_accepted) {
$actually_close = false;
}
} }
} }
if ($actually_close) { if ($actually_close) {

View file

@ -48,7 +48,7 @@ EOTEXT
public function run() { public function run() {
$argv = $this->getArgument('argv'); $argv = $this->getArgument('argv');
$config = $this->readGlobalArcConfig(); $config = self::readGlobalArcConfig();
if ($argv) { if ($argv) {
$keys = $argv; $keys = $argv;
} else { } else {

View file

@ -53,7 +53,7 @@ EOTEXT
throw new ArcanistUsageException("Specify a key and a value."); throw new ArcanistUsageException("Specify a key and a value.");
} }
$config = $this->readGlobalArcConfig(); $config = self::readGlobalArcConfig();
$key = $argv[0]; $key = $argv[0];
$val = $argv[1]; $val = $argv[1];
@ -65,7 +65,7 @@ EOTEXT
if (!strlen($val)) { if (!strlen($val)) {
unset($config[$key]); unset($config[$key]);
$this->writeGlobalArcConfig($config); self::writeGlobalArcConfig($config);
if ($old === null) { if ($old === null) {
echo "Deleted key '{$key}'.\n"; echo "Deleted key '{$key}'.\n";
@ -74,7 +74,7 @@ EOTEXT
} }
} else { } else {
$config[$key] = $val; $config[$key] = $val;
$this->writeGlobalArcConfig($config); self::writeGlobalArcConfig($config);
if ($old === null) { if ($old === null) {
echo "Set key '{$key}' = '{$val}'.\n"; echo "Set key '{$key}' = '{$val}'.\n";

View file

@ -40,6 +40,23 @@ final class ArcanistWorkingCopyIdentity {
$project_root = $dir; $project_root = $dir;
break; break;
} }
if (!$project_root) {
foreach (Filesystem::walkToRoot($path) as $dir) {
$try = array(
$dir.'/.svn',
$dir.'/.hg',
$dir.'/.git',
);
foreach ($try as $trydir) {
if (Filesystem::pathExists($trydir)) {
$project_root = $dir;
break 2;
}
}
}
}
return new ArcanistWorkingCopyIdentity($project_root, $config); return new ArcanistWorkingCopyIdentity($project_root, $config);
} }