1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 09:18:48 +02:00

Add "repository.create" and "repository.query" methods to Conduit

Summary: Primarily for @csilvers who has 92 million repositories or something. This is a touch hacky, but movitated by pragmatism.

Test Plan:
  - Ran "repository.create" to create repositories, "repository.query" to list them.
  - Tested most or maybe all of the error conditions, probably.

Reviewers: btrahan, vrana, csilvers

Reviewed By: csilvers

CC: aran

Differential Revision: https://secure.phabricator.com/D2396
This commit is contained in:
epriestley 2012-05-04 16:16:22 -07:00
parent e214536f38
commit 049048765d
8 changed files with 290 additions and 0 deletions

View file

@ -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',

View file

@ -0,0 +1,35 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
abstract class ConduitAPI_repository_Method extends ConduitAPIMethod {
protected function buildDictForRepository(PhabricatorRepository $repository) {
return array(
'name' => $repository->getName(),
'callsign' => $repository->getCallsign(),
'vcs' => $repository->getVersionControlSystem(),
'uri' => PhabricatorEnv::getProductionURI($repository->getURI()),
'remoteURI' => $repository->getPublicRemoteURI(),
'tracking' => $repository->getDetail('tracking-enabled'),
);
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/base');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_source('ConduitAPI_repository_Method.php');

View file

@ -0,0 +1,138 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
final class ConduitAPI_repository_create_Method
extends ConduitAPI_repository_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodStatusDescription() {
return "Repository methods are new and subject to change.";
}
public function getMethodDescription() {
return "Create a new repository (Admin Only).";
}
public function defineParamTypes() {
return array(
'name' => 'required string',
'vcs' => 'required enum<git, hg, svn>',
'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<string>',
'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);
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/repository/base');
phutil_require_module('phabricator', 'applications/conduit/protocol/exception');
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
phutil_require_source('ConduitAPI_repository_create_Method.php');

View file

@ -0,0 +1,61 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
final class ConduitAPI_repository_query_Method
extends ConduitAPI_repository_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodStatusDescription() {
return "Repository methods are new and subject to change.";
}
public function getMethodDescription() {
return "Query repositories.";
}
public function defineParamTypes() {
return array(
);
}
public function defineReturnType() {
return 'list<dict>';
}
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;
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/repository/base');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
phutil_require_module('phutil', 'utils');
phutil_require_source('ConduitAPI_repository_query_Method.php');

View file

@ -94,6 +94,9 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO {
public function getRemoteURI() {
$raw_uri = $this->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');
}