diff --git a/scripts/arcanist.php b/scripts/arcanist.php index f73fdc29..785f4f8a 100755 --- a/scripts/arcanist.php +++ b/scripts/arcanist.php @@ -146,6 +146,7 @@ try { } $user_config = ArcanistBaseWorkflow::readUserConfigurationFile(); + $global_config = ArcanistBaseWorkflow::readGlobalArcConfig(); $config = $working_copy->getConfig('arcanist_configuration'); if ($config) { @@ -200,24 +201,25 @@ try { $need_conduit = $need_conduit || $need_auth; $need_working_copy = $need_working_copy || - $need_conduit || $need_repository_api; if ($need_working_copy) { if (!$working_copy->getProjectRoot()) { throw new ArcanistUsageException( - "There is no '.arcconfig' file in this directory or any parent ". - "directory. Create a '.arcconfig' file to configure this project ". - "for use with Arcanist."); + "This command must be run in a Git, Mercurial or Subversion working ". + "copy."); } $workflow->setWorkingCopy($working_copy); } - if ($force_conduit) { $conduit_uri = $force_conduit; } 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) { // Set the URI path to '/api/'. TODO: Originally, I contemplated letting @@ -233,9 +235,17 @@ try { if ($need_conduit) { if (!$conduit_uri) { - throw new ArcanistUsageException( - "No Conduit URI is specified in the .arcconfig file for this project. ". - "Specify the Conduit URI for the host Differential is running on."); + + $message = phutil_console_format( + "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 `; 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(); } diff --git a/src/repository/api/subversion/ArcanistSubversionAPI.php b/src/repository/api/subversion/ArcanistSubversionAPI.php index 84986d14..ca987ba8 100644 --- a/src/repository/api/subversion/ArcanistSubversionAPI.php +++ b/src/repository/api/subversion/ArcanistSubversionAPI.php @@ -537,6 +537,10 @@ EODIFF; // this directory and belong to the same project. $project = $this->getWorkingCopyIdentity()->getProjectID(); + if (!$project) { + return array(); + } + $results = $conduit->callMethodSynchronous( 'differential.query', $query + array( diff --git a/src/workflow/base/ArcanistBaseWorkflow.php b/src/workflow/base/ArcanistBaseWorkflow.php index fe5ca40b..cfb5e204 100644 --- a/src/workflow/base/ArcanistBaseWorkflow.php +++ b/src/workflow/base/ArcanistBaseWorkflow.php @@ -927,11 +927,11 @@ abstract class ArcanistBaseWorkflow { } } - protected function readGlobalArcConfig() { + public static function readGlobalArcConfig() { return idx(self::readUserConfigurationFile(), 'config', array()); } - protected function writeGlobalArcConfig(array $options) { + public static function writeGlobalArcConfig(array $options) { $config = self::readUserConfigurationFile(); $config['config'] = $options; self::writeUserConfigurationFile($config); @@ -1102,12 +1102,21 @@ abstract class ArcanistBaseWorkflow { return $this->repositoryEncoding; } + $default = 'UTF-8'; + + $project_id = $this->getWorkingCopy()->getProjectID(); + if (!$project_id) { + return $default; + } + $project_info = $this->getConduit()->callMethodSynchronous( 'arcanist.projectinfo', 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; } diff --git a/src/workflow/close-revision/ArcanistCloseRevisionWorkflow.php b/src/workflow/close-revision/ArcanistCloseRevisionWorkflow.php index cb24081d..390dea10 100644 --- a/src/workflow/close-revision/ArcanistCloseRevisionWorkflow.php +++ b/src/workflow/close-revision/ArcanistCloseRevisionWorkflow.php @@ -127,14 +127,17 @@ EOTEXT $actually_close = true; if ($is_finalize) { - $project_info = $conduit->callMethodSynchronous( - 'arcanist.projectinfo', - array( - 'name' => $this->getWorkingCopy()->getProjectID(), - )); - if ($project_info['tracked'] || - $revision['status'] != $status_accepted) { - $actually_close = false; + $project_id = $this->getWorkingCopy()->getProjectID(); + if ($project_id) { + $project_info = $conduit->callMethodSynchronous( + 'arcanist.projectinfo', + array( + 'name' => $project_id, + )); + if ($project_info['tracked'] || + $revision['status'] != $status_accepted) { + $actually_close = false; + } } } if ($actually_close) { diff --git a/src/workflow/get-config/ArcanistGetConfigWorkflow.php b/src/workflow/get-config/ArcanistGetConfigWorkflow.php index 2dac758e..497fc409 100644 --- a/src/workflow/get-config/ArcanistGetConfigWorkflow.php +++ b/src/workflow/get-config/ArcanistGetConfigWorkflow.php @@ -48,7 +48,7 @@ EOTEXT public function run() { $argv = $this->getArgument('argv'); - $config = $this->readGlobalArcConfig(); + $config = self::readGlobalArcConfig(); if ($argv) { $keys = $argv; } else { diff --git a/src/workflow/set-config/ArcanistSetConfigWorkflow.php b/src/workflow/set-config/ArcanistSetConfigWorkflow.php index d6bee4bd..4effedde 100644 --- a/src/workflow/set-config/ArcanistSetConfigWorkflow.php +++ b/src/workflow/set-config/ArcanistSetConfigWorkflow.php @@ -53,7 +53,7 @@ EOTEXT throw new ArcanistUsageException("Specify a key and a value."); } - $config = $this->readGlobalArcConfig(); + $config = self::readGlobalArcConfig(); $key = $argv[0]; $val = $argv[1]; @@ -65,7 +65,7 @@ EOTEXT if (!strlen($val)) { unset($config[$key]); - $this->writeGlobalArcConfig($config); + self::writeGlobalArcConfig($config); if ($old === null) { echo "Deleted key '{$key}'.\n"; @@ -74,7 +74,7 @@ EOTEXT } } else { $config[$key] = $val; - $this->writeGlobalArcConfig($config); + self::writeGlobalArcConfig($config); if ($old === null) { echo "Set key '{$key}' = '{$val}'.\n"; diff --git a/src/workingcopyidentity/ArcanistWorkingCopyIdentity.php b/src/workingcopyidentity/ArcanistWorkingCopyIdentity.php index 0468074d..c2400404 100644 --- a/src/workingcopyidentity/ArcanistWorkingCopyIdentity.php +++ b/src/workingcopyidentity/ArcanistWorkingCopyIdentity.php @@ -40,6 +40,23 @@ final class ArcanistWorkingCopyIdentity { $project_root = $dir; 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); }