diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -187,7 +187,9 @@ 'ArcanistFileUploader' => 'upload/ArcanistFileUploader.php', 'ArcanistFilenameLinter' => 'lint/linter/ArcanistFilenameLinter.php', 'ArcanistFilenameLinterTestCase' => 'lint/linter/__tests__/ArcanistFilenameLinterTestCase.php', + 'ArcanistFilesystemAPI' => 'repository/api/ArcanistFilesystemAPI.php', 'ArcanistFilesystemConfigurationSource' => 'config/source/ArcanistFilesystemConfigurationSource.php', + 'ArcanistFilesystemWorkingCopy' => 'workingcopy/ArcanistFilesystemWorkingCopy.php', 'ArcanistFlagWorkflow' => 'workflow/ArcanistFlagWorkflow.php', 'ArcanistFlake8Linter' => 'lint/linter/ArcanistFlake8Linter.php', 'ArcanistFlake8LinterTestCase' => 'lint/linter/__tests__/ArcanistFlake8LinterTestCase.php', @@ -1130,7 +1132,9 @@ 'ArcanistFileUploader' => 'Phobject', 'ArcanistFilenameLinter' => 'ArcanistLinter', 'ArcanistFilenameLinterTestCase' => 'ArcanistLinterTestCase', + 'ArcanistFilesystemAPI' => 'ArcanistRepositoryAPI', 'ArcanistFilesystemConfigurationSource' => 'ArcanistDictionaryConfigurationSource', + 'ArcanistFilesystemWorkingCopy' => 'ArcanistWorkingCopy', 'ArcanistFlagWorkflow' => 'ArcanistWorkflow', 'ArcanistFlake8Linter' => 'ArcanistExternalLinter', 'ArcanistFlake8LinterTestCase' => 'ArcanistExternalLinterTestCase', diff --git a/src/repository/api/ArcanistFilesystemAPI.php b/src/repository/api/ArcanistFilesystemAPI.php new file mode 100644 --- /dev/null +++ b/src/repository/api/ArcanistFilesystemAPI.php @@ -0,0 +1,100 @@ + $root) { - $is_git = false; - $working_copy = ArcanistWorkingCopy::newFromWorkingDirectory($root); - if ($working_copy) { - $repository_api = $working_copy->newRepositoryAPI(); - if ($repository_api instanceof ArcanistGitAPI) { - $is_git = true; - } - } + + $repository_api = $working_copy->getRepositoryAPI(); + $is_git = ($repository_api instanceof ArcanistGitAPI); if (!$is_git) { throw new PhutilArgumentUsageException( diff --git a/src/workflow/ArcanistUpgradeWorkflow.php b/src/workflow/ArcanistUpgradeWorkflow.php --- a/src/workflow/ArcanistUpgradeWorkflow.php +++ b/src/workflow/ArcanistUpgradeWorkflow.php @@ -43,15 +43,10 @@ 'Preparing to upgrade "%s"...', $library)); - $is_git = false; - $working_copy = ArcanistWorkingCopy::newFromWorkingDirectory($root); - if ($working_copy) { - $repository_api = $working_copy->newRepositoryAPI(); - if ($repository_api instanceof ArcanistGitAPI) { - $is_git = true; - } - } + + $repository_api = $working_copy->getRepositoryAPI(); + $is_git = ($repository_api instanceof ArcanistGitAPI); if (!$is_git) { throw new PhutilArgumentUsageException( diff --git a/src/workingcopy/ArcanistFilesystemWorkingCopy.php b/src/workingcopy/ArcanistFilesystemWorkingCopy.php new file mode 100644 --- /dev/null +++ b/src/workingcopy/ArcanistFilesystemWorkingCopy.php @@ -0,0 +1,27 @@ +getPath()); } diff --git a/src/workingcopy/ArcanistMercurialWorkingCopy.php b/src/workingcopy/ArcanistMercurialWorkingCopy.php --- a/src/workingcopy/ArcanistMercurialWorkingCopy.php +++ b/src/workingcopy/ArcanistMercurialWorkingCopy.php @@ -18,7 +18,7 @@ return new self(); } - public function newRepositoryAPI() { + protected function newRepositoryAPI() { return new ArcanistMercurialAPI($this->getPath()); } diff --git a/src/workingcopy/ArcanistSubversionWorkingCopy.php b/src/workingcopy/ArcanistSubversionWorkingCopy.php --- a/src/workingcopy/ArcanistSubversionWorkingCopy.php +++ b/src/workingcopy/ArcanistSubversionWorkingCopy.php @@ -70,7 +70,7 @@ return head($candidates); } - public function newRepositoryAPI() { + protected function newRepositoryAPI() { return new ArcanistSubversionAPI($this->getPath()); } diff --git a/src/workingcopy/ArcanistWorkingCopy.php b/src/workingcopy/ArcanistWorkingCopy.php --- a/src/workingcopy/ArcanistWorkingCopy.php +++ b/src/workingcopy/ArcanistWorkingCopy.php @@ -5,6 +5,7 @@ private $path; private $workingDirectory; + private $repositoryAPI; public static function newFromWorkingDirectory($path) { $working_types = id(new PhutilClassMapQuery()) @@ -25,8 +26,7 @@ continue; } - $working_copy->path = $ancestor_path; - $working_copy->workingDirectory = $path; + self::configureWorkingCopy($working_copy, $ancestor_path, $path); $candidates[] = $working_copy; } @@ -50,7 +50,16 @@ return $deepest->selectFromNestedWorkingCopies($candidates); } - return null; + // If we haven't found a legitimate working copy that belongs to a + // supported version control system, return a "filesystem" working copy. + // This allows some commands to work as expected even if run outside + // of a real working copy. + + $working_copy = new ArcanistFilesystemWorkingCopy(); + + self::configureWorkingCopy($working_copy, $ancestor_path, $path); + + return $working_copy; } abstract protected function newWorkingCopyFromDirectories( @@ -110,6 +119,23 @@ return last($candidates); } - abstract public function newRepositoryAPI(); + final public function getRepositoryAPI() { + if (!$this->repositoryAPI) { + $this->repositoryAPI = $this->newRepositoryAPI(); + } + + return $this->repositoryAPI; + } + + abstract protected function newRepositoryAPI(); + + private static function configureWorkingCopy( + ArcanistWorkingCopy $working_copy, + $ancestor_path, + $path) { + + $working_copy->path = $ancestor_path; + $working_copy->workingDirectory = $path; + } }