diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 12d766e370..ec14cd164a 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -176,6 +176,9 @@ phutil_register_library_map(array( 'ConduitAPI_project_Method' => 'applications/conduit/method/project/base', 'ConduitAPI_project_query_Method' => 'applications/conduit/method/project/query', 'ConduitAPI_remarkup_process_Method' => 'applications/conduit/method/remarkup/process', + 'ConduitAPI_repository_Method' => 'applications/conduit/method/repository/base', + 'ConduitAPI_repository_create_Method' => 'applications/conduit/method/repository/create', + 'ConduitAPI_repository_query_Method' => 'applications/conduit/method/repository/query', 'ConduitAPI_slowvote_info_Method' => 'applications/conduit/method/slowvote/info', 'ConduitAPI_user_Method' => 'applications/conduit/method/user/base', 'ConduitAPI_user_addstatus_Method' => 'applications/conduit/method/user/addstatus', @@ -1198,6 +1201,9 @@ phutil_register_library_map(array( 'ConduitAPI_project_Method' => 'ConduitAPIMethod', 'ConduitAPI_project_query_Method' => 'ConduitAPI_project_Method', 'ConduitAPI_remarkup_process_Method' => 'ConduitAPIMethod', + 'ConduitAPI_repository_Method' => 'ConduitAPIMethod', + 'ConduitAPI_repository_create_Method' => 'ConduitAPI_repository_Method', + 'ConduitAPI_repository_query_Method' => 'ConduitAPI_repository_Method', 'ConduitAPI_slowvote_info_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_addstatus_Method' => 'ConduitAPI_user_Method', diff --git a/src/applications/conduit/method/repository/base/ConduitAPI_repository_Method.php b/src/applications/conduit/method/repository/base/ConduitAPI_repository_Method.php new file mode 100644 index 0000000000..11d2f6dba4 --- /dev/null +++ b/src/applications/conduit/method/repository/base/ConduitAPI_repository_Method.php @@ -0,0 +1,35 @@ + $repository->getName(), + 'callsign' => $repository->getCallsign(), + 'vcs' => $repository->getVersionControlSystem(), + 'uri' => PhabricatorEnv::getProductionURI($repository->getURI()), + 'remoteURI' => $repository->getPublicRemoteURI(), + 'tracking' => $repository->getDetail('tracking-enabled'), + ); + } + +} diff --git a/src/applications/conduit/method/repository/base/__init__.php b/src/applications/conduit/method/repository/base/__init__.php new file mode 100644 index 0000000000..ce8ba4a8be --- /dev/null +++ b/src/applications/conduit/method/repository/base/__init__.php @@ -0,0 +1,13 @@ + 'required string', + 'vcs' => 'required enum', + 'callsign' => 'required string', + 'encoding' => 'optional string', + 'tracking' => 'optional bool', + 'uri' => 'optional string', + 'sshUser' => 'optional string', + 'sshKey' => 'optional string', + 'sshKeyFile' => 'optional string', + 'httpUser' => 'optional string', + 'httpPassword' => 'optional string', + 'localPath' => 'optional string', + 'svnSubpath' => 'optional string', + 'branchFilter' => 'optional list', + 'pullFrequency' => 'optional int', + 'defaultBranch' => 'optional string', + 'heraldEnabled' => 'optional bool', + 'svnUUID' => 'optional string', + ); + } + + public function defineReturnType() { + return 'nonempty dict'; + } + + public function defineErrorTypes() { + return array( + 'ERR-PERMISSIONS' => + 'You do not have the authority to call this method.', + 'ERR-DUPLICATE' => + 'Duplicate repository callsign.', + 'ERR-BAD-CALLSIGN' => + 'Callsign is required and must be ALL UPPERCASE LETTERS.', + 'ERR-UNKNOWN-REPOSITORY-VCS' => + 'Unknown repository VCS type.', + ); + } + + protected function execute(ConduitAPIRequest $request) { + if (!$request->getUser()->getIsAdmin()) { + throw new ConduitException('ERR-PERMISSIONS'); + } + + // TODO: This has some duplication with (and lacks some of the validation + // of) the web workflow; refactor things so they can share more code as this + // stabilizes. + + $repository = new PhabricatorRepository(); + $repository->setName($request->getValue('name')); + + $callsign = $request->getValue('callsign'); + if (!preg_match('/[A-Z]+$/', $callsign)) { + throw new ConduitException('ERR-BAD-CALLSIGN'); + } + $repository->setCallsign($callsign); + + $vcs = $request->getValue('vcs'); + + $map = array( + 'git' => PhabricatorRepositoryType::REPOSITORY_TYPE_GIT, + 'hg' => PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL, + 'svn' => PhabricatorRepositoryType::REPOSITORY_TYPE_SVN, + ); + if (empty($map[$vcs])) { + throw new ConduitException('ERR-UNKNOWN-REPOSITORY-VCS'); + } + $repository->setVersionControlSystem($map[$vcs]); + + $details = array( + 'encoding' => $request->getValue('encoding'), + 'tracking-enabled' => (bool)$request->getValue('tracking', true), + 'remote-uri' => $request->getValue('uri'), + 'local-path' => $request->getValue('localPath'), + 'branch-filter' => array_fill_keys( + $request->getValue('branchFilter', array()), + true), + 'pull-frequency' => $request->getValue('pullFrequency'), + 'default-branch' => $request->getValue('defaultBranch'), + 'ssh-login' => $request->getValue('sshUser'), + 'ssh-key' => $request->getValue('sshKey'), + 'ssh-keyfile' => $request->getValue('sshKeyFile'), + 'herald-disabled' => !$request->getValue('heraldEnabled', true), + 'svn-subpath' => $request->getValue('svnSubpath'), + ); + + foreach ($details as $key => $value) { + $repository->setDetail($key, $value); + } + + try { + $repository->save(); + } catch (AphrontQueryDuplicateKeyException $ex) { + throw new ConduitException('ERR-DUPLICATE'); + } + + return $this->buildDictForRepository($repository); + } + + +} diff --git a/src/applications/conduit/method/repository/create/__init__.php b/src/applications/conduit/method/repository/create/__init__.php new file mode 100644 index 0000000000..4717ed72f2 --- /dev/null +++ b/src/applications/conduit/method/repository/create/__init__.php @@ -0,0 +1,15 @@ +'; + } + + public function defineErrorTypes() { + return array( + ); + } + + protected function execute(ConduitAPIRequest $request) { + $repositories = id(new PhabricatorRepository())->loadAll(); + + $results = array(); + foreach ($repositories as $repository) { + $results[] = $this->buildDictForRepository($repository); + } + + return $results; + } +} diff --git a/src/applications/conduit/method/repository/query/__init__.php b/src/applications/conduit/method/repository/query/__init__.php new file mode 100644 index 0000000000..fb932fc36e --- /dev/null +++ b/src/applications/conduit/method/repository/query/__init__.php @@ -0,0 +1,15 @@ +getDetail('remote-uri'); + if (!$raw_uri) { + return null; + } $vcs = $this->getVersionControlSystem(); $is_git = ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT); @@ -328,6 +331,10 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO { return $uri; } + public function getURI() { + return '/diffusion/'.$this->getCallsign().'/'; + } + private function isSSHProtocol($protocol) { return ($protocol == 'ssh' || $protocol == 'svn+ssh'); }