Index: src/applications/diffusion/controller/DiffusionExternalController.php =================================================================== --- src/applications/diffusion/controller/DiffusionExternalController.php +++ src/applications/diffusion/controller/DiffusionExternalController.php @@ -33,7 +33,7 @@ if ($remote_uri->getPath() == $uri_path) { $matches[$key] = 1; } - if ($repository->getPublicRemoteURI() == $uri) { + if ($repository->getPublicCloneURI() == $uri) { $matches[$key] = 2; } if ($repository->getRemoteURI() == $uri) { Index: src/applications/diffusion/controller/DiffusionRepositoryController.php =================================================================== --- src/applications/diffusion/controller/DiffusionRepositoryController.php +++ src/applications/diffusion/controller/DiffusionRepositoryController.php @@ -174,42 +174,21 @@ } if ($repository->isHosted()) { - $serve_off = PhabricatorRepository::SERVE_OFF; - $callsign = $repository->getCallsign(); - $repo_path = '/diffusion/'.$callsign.'/'; - - $serve_ssh = $repository->getServeOverSSH(); - if ($serve_ssh !== $serve_off) { - $uri = new PhutilURI(PhabricatorEnv::getProductionURI($repo_path)); - - if ($repository->isSVN()) { - $uri->setProtocol('svn+ssh'); - } else { - $uri->setProtocol('ssh'); - } - - $ssh_user = PhabricatorEnv::getEnvConfig('diffusion.ssh-user'); - if ($ssh_user) { - $uri->setUser($ssh_user); - } - - $uri->setPort(PhabricatorEnv::getEnvConfig('diffusion.ssh-port')); - + $ssh_uri = $repository->getSSHCloneURIObject(); + if ($ssh_uri) { $clone_uri = $this->renderCloneURI( - $uri, - $serve_ssh, + $ssh_uri, + $repository->getServeOverSSH(), '/settings/panel/ssh/'); $view->addProperty(pht('Clone URI (SSH)'), $clone_uri); } - $serve_http = $repository->getServeOverHTTP(); - if ($serve_http !== $serve_off) { - $http_uri = PhabricatorEnv::getProductionURI($repo_path); - + $http_uri = $repository->getHTTPCloneURIObject(); + if ($http_uri) { $clone_uri = $this->renderCloneURI( $http_uri, - $serve_http, + $repository->getServeOverHTTP(), PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth') ? '/settings/panel/vcspassword/' : null); @@ -223,13 +202,13 @@ $view->addProperty( pht('Clone URI'), $this->renderCloneURI( - $repository->getPublicRemoteURI())); + $repository->getPublicCloneURI())); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $view->addProperty( pht('Repository Root'), $this->renderCloneURI( - $repository->getPublicRemoteURI())); + $repository->getPublicCloneURI())); break; } } Index: src/applications/harbormaster/storage/build/HarbormasterBuild.php =================================================================== --- src/applications/harbormaster/storage/build/HarbormasterBuild.php +++ src/applications/harbormaster/storage/build/HarbormasterBuild.php @@ -175,7 +175,7 @@ if ($repo) { $results['repository.callsign'] = $repo->getCallsign(); $results['repository.vcs'] = $repo->getVersionControlSystem(); - $results['repository.uri'] = $repo->getPublicRemoteURI(); + $results['repository.uri'] = $repo->getPublicCloneURI(); } $results['step.timestamp'] = time(); Index: src/applications/repository/storage/PhabricatorRepository.php =================================================================== --- src/applications/repository/storage/PhabricatorRepository.php +++ src/applications/repository/storage/PhabricatorRepository.php @@ -486,11 +486,7 @@ } public function getNormalizedPath() { - if ($this->isHosted()) { - $uri = PhabricatorEnv::getProductionURI($this->getURI()); - } else { - $uri = $this->getRemoteURI(); - } + $uri = (string)$this->getCloneURIObject(); switch ($this->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: @@ -629,6 +625,7 @@ return (bool)$this->getDetail('importing', false); } + /* -( Repository URI Management )------------------------------------------ */ @@ -675,26 +672,29 @@ /** - * Get the remote URI for this repository, without authentication information. + * Get the clone (or checkout) URI for this repository, without authentication + * information. * * @return string Repository URI. * @task uri */ - public function getPublicRemoteURI() { - $uri = $this->getRemoteURIObject(); + public function getPublicCloneURI() { + $uri = $this->getCloneURIObject(); // Make sure we don't leak anything if this repo is using HTTP Basic Auth // with the credentials in the URI or something zany like that. // If repository is not accessed over SSH we remove both username and // password. - if (!$this->shouldUseSSH()) { - $uri->setUser(null); + if (!$this->isHosted()) { + if (!$this->shouldUseSSH()) { + $uri->setUser(null); - // This might be a Git URI or a normal URI. If it's Git, there's no - // password support. - if ($uri instanceof PhutilURI) { - $uri->setPass(null); + // This might be a Git URI or a normal URI. If it's Git, there's no + // password support. + if ($uri instanceof PhutilURI) { + $uri->setPass(null); + } } } @@ -753,6 +753,94 @@ /** + * Get the "best" clone/checkout URI for this repository, on any protocol. + */ + public function getCloneURIObject() { + if (!$this->isHosted()) { + return $this->getRemoteURIObject(); + } + + // Choose the best URI: pick a read/write URI over a URI which is not + // read/write, and SSH over HTTP. + + $serve_ssh = $this->getServeOverSSH(); + $serve_http = $this->getServeOverHTTP(); + + if ($serve_ssh === self::SERVE_READWRITE) { + return $this->getSSHCloneURIObject(); + } else if ($serve_http === self::SERVE_READWRITE) { + return $this->getHTTPCloneURIObject(); + } else if ($serve_ssh !== self::SERVE_OFF) { + return $this->getSSHCloneURIObject(); + } else if ($serve_http !== self::SERVE_OFF) { + return $this->getHTTPCloneURIObject(); + } else { + return null; + } + } + + + /** + * Get the repository's SSH clone/checkout URI, if one exists. + */ + public function getSSHCloneURIObject() { + if (!$this->isHosted()) { + if ($this->shouldUseSSH()) { + return $this->getRemoteURIObject(); + } else { + return null; + } + } + + $serve_ssh = $this->getServeOverSSH(); + if ($serve_ssh === self::SERVE_OFF) { + return null; + } + + $uri = new PhutilURI(PhabricatorEnv::getProductionURI($this->getURI())); + + if ($this->isSVN()) { + $uri->setProtocol('svn+ssh'); + } else { + $uri->setProtocol('ssh'); + } + + $ssh_user = PhabricatorEnv::getEnvConfig('diffusion.ssh-user'); + if ($ssh_user) { + $uri->setUser($ssh_user); + } + + $uri->setPort(PhabricatorEnv::getEnvConfig('diffusion.ssh-port')); + + return $uri; + } + + + /** + * Get the repository's HTTP clone/checkout URI, if one exists. + */ + public function getHTTPCloneURIObject() { + if (!$this->isHosted()) { + if ($this->shouldUseHTTP()) { + return $this->getRemoteURIObject(); + } else { + return null; + } + } + + $serve_http = $this->getServeOverHTTP(); + if ($serve_http === self::SERVE_OFF) { + return null; + } + + + $uri = PhabricatorEnv::getProductionURI($this->getURI()); + + return $uri; + } + + + /** * Determine if we should connect to the remote using SSH flags and * credentials. * Index: src/applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php =================================================================== --- src/applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php +++ src/applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php @@ -38,21 +38,21 @@ $repo->setVersionControlSystem($svn); $this->assertEqual('http://example.com/', $repo->getRemoteURI()); - $this->assertEqual('http://example.com/', $repo->getPublicRemoteURI()); + $this->assertEqual('http://example.com/', $repo->getPublicCloneURI()); $this->assertEqual('http://example.com/', $repo->getRemoteURIEnvelope()->openEnvelope()); $repo->setVersionControlSystem($git); $this->assertEqual('http://example.com/', $repo->getRemoteURI()); - $this->assertEqual('http://example.com/', $repo->getPublicRemoteURI()); + $this->assertEqual('http://example.com/', $repo->getPublicCloneURI()); $this->assertEqual('http://duck:quack@example.com/', $repo->getRemoteURIEnvelope()->openEnvelope()); $repo->setVersionControlSystem($hg); $this->assertEqual('http://example.com/', $repo->getRemoteURI()); - $this->assertEqual('http://example.com/', $repo->getPublicRemoteURI()); + $this->assertEqual('http://example.com/', $repo->getPublicCloneURI()); $this->assertEqual('http://duck:quack@example.com/', $repo->getRemoteURIEnvelope()->openEnvelope()); @@ -62,21 +62,21 @@ $repo->setVersionControlSystem($svn); $this->assertEqual('ssh://example.com/', $repo->getRemoteURI()); - $this->assertEqual('ssh://example.com/', $repo->getPublicRemoteURI()); + $this->assertEqual('ssh://example.com/', $repo->getPublicCloneURI()); $this->assertEqual('ssh://example.com/', $repo->getRemoteURIEnvelope()->openEnvelope()); $repo->setVersionControlSystem($git); $this->assertEqual('ssh://example.com/', $repo->getRemoteURI()); - $this->assertEqual('ssh://example.com/', $repo->getPublicRemoteURI()); + $this->assertEqual('ssh://example.com/', $repo->getPublicCloneURI()); $this->assertEqual('ssh://example.com/', $repo->getRemoteURIEnvelope()->openEnvelope()); $repo->setVersionControlSystem($hg); $this->assertEqual('ssh://example.com/', $repo->getRemoteURI()); - $this->assertEqual('ssh://example.com/', $repo->getPublicRemoteURI()); + $this->assertEqual('ssh://example.com/', $repo->getPublicCloneURI()); $this->assertEqual('ssh://example.com/', $repo->getRemoteURIEnvelope()->openEnvelope()); @@ -86,7 +86,7 @@ $repo->setVersionControlSystem($git); $this->assertEqual('git@example.com:path.git', $repo->getRemoteURI()); - $this->assertEqual('git@example.com:path.git', $repo->getPublicRemoteURI()); + $this->assertEqual('git@example.com:path.git', $repo->getPublicCloneURI()); $this->assertEqual('git@example.com:path.git', $repo->getRemoteURIEnvelope()->openEnvelope());