Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/audit/conduit/ConduitAPI_audit_query_Method.php b/src/applications/audit/conduit/ConduitAPI_audit_query_Method.php
index 556c45e28e..796e744ef4 100644
--- a/src/applications/audit/conduit/ConduitAPI_audit_query_Method.php
+++ b/src/applications/audit/conduit/ConduitAPI_audit_query_Method.php
@@ -1,75 +1,80 @@
<?php
/**
* @group conduit
*/
final class ConduitAPI_audit_query_Method extends ConduitAPI_audit_Method {
public function getMethodDescription() {
return "Query audit requests.";
}
public function defineParamTypes() {
+ $statuses = array(
+ 'status-any',
+ 'status-open',
+ );
+ $status_const = $this->formatStringConstants($statuses);
+
return array(
'auditorPHIDs' => 'optional list<phid>',
'commitPHIDs' => 'optional list<phid>',
- 'status' => 'optional enum<"status-any", "status-open"> '.
- '(default = "status-any")',
+ 'status' => 'optional '.$status_const.' (default = "status-any")',
'offset' => 'optional int',
'limit' => 'optional int (default = 100)',
);
}
public function defineReturnType() {
return 'list<dict>';
}
public function defineErrorTypes() {
return array(
);
}
protected function execute(ConduitAPIRequest $request) {
$query = id(new DiffusionCommitQuery())
->setViewer($request->getUser());
$auditor_phids = $request->getValue('auditorPHIDs', array());
if ($auditor_phids) {
$query->withAuditorPHIDs($auditor_phids);
}
$commit_phids = $request->getValue('commitPHIDs', array());
if ($commit_phids) {
$query->withPHIDs($commit_phids);
}
$status = $request->getValue(
'status',
DiffusionCommitQuery::AUDIT_STATUS_ANY);
$query->withAuditStatus($status);
$query->setOffset($request->getValue('offset', 0));
$query->setLimit($request->getValue('limit', 100));
$commits = $query->execute();
$results = array();
foreach ($commits as $commit) {
$requests = $commit->getAudits();
foreach ($requests as $request) {
$results[] = array(
'id' => $request->getID(),
'commitPHID' => $request->getCommitPHID(),
'auditorPHID' => $request->getAuditorPHID(),
'reasons' => $request->getAuditReasons(),
'status' => $request->getAuditStatus(),
);
}
}
return $results;
}
}
diff --git a/src/applications/conduit/method/ConduitAPIMethod.php b/src/applications/conduit/method/ConduitAPIMethod.php
index 906681e9cf..764f8f5737 100644
--- a/src/applications/conduit/method/ConduitAPIMethod.php
+++ b/src/applications/conduit/method/ConduitAPIMethod.php
@@ -1,264 +1,273 @@
<?php
/**
* @task status Method Status
* @task pager Paging Results
*/
abstract class ConduitAPIMethod
extends Phobject
implements PhabricatorPolicyInterface {
const METHOD_STATUS_STABLE = 'stable';
const METHOD_STATUS_UNSTABLE = 'unstable';
const METHOD_STATUS_DEPRECATED = 'deprecated';
abstract public function getMethodDescription();
abstract public function defineParamTypes();
abstract public function defineReturnType();
abstract public function defineErrorTypes();
abstract protected function execute(ConduitAPIRequest $request);
public function __construct() {
}
/**
* This is mostly for compatibility with
* @{class:PhabricatorCursorPagedPolicyAwareQuery}.
*/
public function getID() {
return $this->getAPIMethodName();
}
/**
* Get the status for this method (e.g., stable, unstable or deprecated).
* Should return a METHOD_STATUS_* constant. By default, methods are
* "stable".
*
* @return const METHOD_STATUS_* constant.
* @task status
*/
public function getMethodStatus() {
return self::METHOD_STATUS_STABLE;
}
/**
* Optional description to supplement the method status. In particular, if
* a method is deprecated, you can return a string here describing the reason
* for deprecation and stable alternatives.
*
* @return string|null Description of the method status, if available.
* @task status
*/
public function getMethodStatusDescription() {
return null;
}
public function getErrorDescription($error_code) {
return idx($this->defineErrorTypes(), $error_code, 'Unknown Error');
}
public function getRequiredScope() {
// by default, conduit methods are not accessible via OAuth
return PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE;
}
public function executeMethod(ConduitAPIRequest $request) {
return $this->execute($request);
}
public function getAPIMethodName() {
return self::getAPIMethodNameFromClassName(get_class($this));
}
/**
* Return a key which sorts methods by application name, then method status,
* then method name.
*/
public function getSortOrder() {
$name = $this->getAPIMethodName();
$map = array(
ConduitAPIMethod::METHOD_STATUS_STABLE => 0,
ConduitAPIMethod::METHOD_STATUS_UNSTABLE => 1,
ConduitAPIMethod::METHOD_STATUS_DEPRECATED => 2,
);
$ord = idx($map, $this->getMethodStatus(), 0);
list($head, $tail) = explode('.', $name, 2);
return "{$head}.{$ord}.{$tail}";
}
public function getApplicationName() {
return head(explode('.', $this->getAPIMethodName(), 2));
}
public static function getClassNameFromAPIMethodName($method_name) {
$method_fragment = str_replace('.', '_', $method_name);
return 'ConduitAPI_'.$method_fragment.'_Method';
}
public function shouldRequireAuthentication() {
return true;
}
public function shouldAllowPublic() {
return false;
}
public function shouldAllowUnguardedWrites() {
return false;
}
/**
* Optionally, return a @{class:PhabricatorApplication} which this call is
* part of. The call will be disabled when the application is uninstalled.
*
* @return PhabricatorApplication|null Related application.
*/
public function getApplication() {
return null;
}
public static function getAPIMethodNameFromClassName($class_name) {
$match = null;
$is_valid = preg_match(
'/^ConduitAPI_(.*)_Method$/',
$class_name,
$match);
if (!$is_valid) {
throw new Exception(
"Parameter '{$class_name}' is not a valid Conduit API method class.");
}
$method_fragment = $match[1];
return str_replace('_', '.', $method_fragment);
}
protected function validateHost($host) {
if (!$host) {
// If the client doesn't send a host key, don't complain. We should in
// the future, but this change isn't severe enough to bump the protocol
// version.
// TODO: Remove this once the protocol version gets bumped past 2 (i.e.,
// require the host key be present and valid).
return;
}
// NOTE: Compare domains only so we aren't sensitive to port specification
// or omission.
$host = new PhutilURI($host);
$host = $host->getDomain();
$self = new PhutilURI(PhabricatorEnv::getURI('/'));
$self = $self->getDomain();
if ($self !== $host) {
throw new Exception(
"Your client is connecting to this install as '{$host}', but it is ".
"configured as '{$self}'. The client and server must use the exact ".
"same URI to identify the install. Edit your .arcconfig or ".
"phabricator/conf so they agree on the URI for the install.");
}
}
+ protected function formatStringConstants($constants) {
+ foreach ($constants as $key => $value) {
+ $constants[$key] = '"'.$value.'"';
+ }
+ $constants = implode(', ', $constants);
+ return 'string-constant<'.$constants.'>';
+ }
+
/* -( Paging Results )----------------------------------------------------- */
/**
* @task pager
*/
protected function getPagerParamTypes() {
return array(
'before' => 'optional string',
'after' => 'optional string',
'limit' => 'optional int (default = 100)',
);
}
/**
* @task pager
*/
protected function newPager(ConduitAPIRequest $request) {
$limit = $request->getValue('limit', 100);
$limit = min(1000, $limit);
$limit = max(1, $limit);
$pager = id(new AphrontCursorPagerView())
->setPageSize($limit);
$before_id = $request->getValue('before');
if ($before_id !== null) {
$pager->setBeforeID($before_id);
}
$after_id = $request->getValue('after');
if ($after_id !== null) {
$pager->setAfterID($after_id);
}
return $pager;
}
/**
* @task pager
*/
protected function addPagerResults(
array $results,
AphrontCursorPagerView $pager) {
$results['cursor'] = array(
'limit' => $pager->getPageSize(),
'after' => $pager->getNextPageID(),
'before' => $pager->getPrevPageID(),
);
return $results;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getPHID() {
return null;
}
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
);
}
public function getPolicy($capability) {
// Application methods get application visibility; other methods get open
// visibility.
$application = $this->getApplication();
if ($application) {
return $application->getPolicy($capability);
}
return PhabricatorPolicies::getMostOpenPolicy();
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
if (!$this->shouldRequireAuthentication()) {
// Make unauthenticated methods univerally visible.
return true;
}
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
+
}
diff --git a/src/applications/differential/conduit/ConduitAPI_differential_creatediff_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_creatediff_Method.php
index 1b28b071bf..8232f14504 100644
--- a/src/applications/differential/conduit/ConduitAPI_differential_creatediff_Method.php
+++ b/src/applications/differential/conduit/ConduitAPI_differential_creatediff_Method.php
@@ -1,172 +1,188 @@
<?php
final class ConduitAPI_differential_creatediff_Method
extends ConduitAPI_differential_Method {
public function getMethodDescription() {
return "Create a new Differential diff.";
}
public function defineParamTypes() {
+
+ $vcs_const = $this->formatStringConstants(
+ array(
+ 'svn',
+ 'git',
+ 'hg',
+ ));
+
+ $status_const = $this->formatStringConstants(
+ array(
+ 'none',
+ 'skip',
+ 'okay',
+ 'warn',
+ 'fail',
+ 'postponed',
+ ));
+
return array(
'changes' => 'required list<dict>',
'sourceMachine' => 'required string',
'sourcePath' => 'required string',
'branch' => 'required string',
'bookmark' => 'optional string',
- 'sourceControlSystem' => 'required enum<svn, git, hg>',
+ 'sourceControlSystem' => 'required '.$vcs_const,
'sourceControlPath' => 'required string',
'sourceControlBaseRevision' => 'required string',
'creationMethod' => 'optional string',
'arcanistProject' => 'optional string',
- 'lintStatus' =>
- 'required enum<none, skip, okay, warn, fail, postponed>',
- 'unitStatus' =>
- 'required enum<none, skip, okay, warn, fail, postponed>',
+ 'lintStatus' => 'required '.$status_const,
+ 'unitStatus' => 'required '.$status_const,
'repositoryPHID' => 'optional phid',
'parentRevisionID' => 'deprecated',
'authorPHID' => 'deprecated',
'repositoryUUID' => 'deprecated',
);
}
public function defineReturnType() {
return 'nonempty dict';
}
public function defineErrorTypes() {
return array(
);
}
protected function execute(ConduitAPIRequest $request) {
$viewer = $request->getUser();
$change_data = $request->getValue('changes');
$changes = array();
foreach ($change_data as $dict) {
$changes[] = ArcanistDiffChange::newFromDictionary($dict);
}
$diff = DifferentialDiff::newFromRawChanges($changes);
$diff->setSourcePath($request->getValue('sourcePath'));
$diff->setSourceMachine($request->getValue('sourceMachine'));
$diff->setBranch($request->getValue('branch'));
$diff->setCreationMethod($request->getValue('creationMethod'));
$diff->setAuthorPHID($viewer->getPHID());
$diff->setBookmark($request->getValue('bookmark'));
// TODO: Remove this eventually; for now continue writing the UUID. Note
// that we'll overwrite it below if we identify a repository, and `arc`
// no longer sends it. This stuff is retained for backward compatibility.
$diff->setRepositoryUUID($request->getValue('repositoryUUID'));
$repository_phid = $request->getValue('repositoryPHID');
if ($repository_phid) {
$repository = id(new PhabricatorRepositoryQuery())
->setViewer($viewer)
->withPHIDs(array($repository_phid))
->executeOne();
if ($repository) {
$diff->setRepositoryPHID($repository->getPHID());
$diff->setRepositoryUUID($repository->getUUID());
}
}
$system = $request->getValue('sourceControlSystem');
$diff->setSourceControlSystem($system);
$diff->setSourceControlPath($request->getValue('sourceControlPath'));
$diff->setSourceControlBaseRevision(
$request->getValue('sourceControlBaseRevision'));
$project_name = $request->getValue('arcanistProject');
$project_phid = null;
if ($project_name) {
$arcanist_project = id(new PhabricatorRepositoryArcanistProject())
->loadOneWhere(
'name = %s',
$project_name);
if (!$arcanist_project) {
$arcanist_project = new PhabricatorRepositoryArcanistProject();
$arcanist_project->setName($project_name);
$arcanist_project->save();
}
$project_phid = $arcanist_project->getPHID();
}
$diff->setArcanistProjectPHID($project_phid);
switch ($request->getValue('lintStatus')) {
case 'skip':
$diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
break;
case 'okay':
$diff->setLintStatus(DifferentialLintStatus::LINT_OKAY);
break;
case 'warn':
$diff->setLintStatus(DifferentialLintStatus::LINT_WARN);
break;
case 'fail':
$diff->setLintStatus(DifferentialLintStatus::LINT_FAIL);
break;
case 'postponed':
$diff->setLintStatus(DifferentialLintStatus::LINT_POSTPONED);
break;
case 'none':
default:
$diff->setLintStatus(DifferentialLintStatus::LINT_NONE);
break;
}
switch ($request->getValue('unitStatus')) {
case 'skip':
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP);
break;
case 'okay':
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_OKAY);
break;
case 'warn':
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_WARN);
break;
case 'fail':
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_FAIL);
break;
case 'postponed':
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_POSTPONED);
break;
case 'none':
default:
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_NONE);
break;
}
$diff->save();
// If we didn't get an explicit `repositoryPHID` (which means the client is
// old, or couldn't figure out which repository the working copy belongs
// to), apply heuristics to try to figure it out.
if (!$repository_phid) {
$repository = id(new DifferentialRepositoryLookup())
->setDiff($diff)
->setViewer($viewer)
->lookupRepository();
if ($repository) {
$diff->setRepositoryPHID($repository->getPHID());
$diff->setRepositoryUUID($repository->getUUID());
$diff->save();
}
}
$path = '/differential/diff/'.$diff->getID().'/';
$uri = PhabricatorEnv::getURI($path);
return array(
'diffid' => $diff->getID(),
'uri' => $uri,
);
}
}
diff --git a/src/applications/differential/conduit/ConduitAPI_differential_find_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_find_Method.php
index bda9a513b4..2275845c78 100644
--- a/src/applications/differential/conduit/ConduitAPI_differential_find_Method.php
+++ b/src/applications/differential/conduit/ConduitAPI_differential_find_Method.php
@@ -1,104 +1,102 @@
<?php
final class ConduitAPI_differential_find_Method
extends ConduitAPI_differential_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_DEPRECATED;
}
public function getMethodStatusDescription() {
return "Replaced by 'differential.query'.";
}
public function getMethodDescription() {
return "Query Differential revisions which match certain criteria.";
}
public function defineParamTypes() {
$types = array(
'open',
'committable',
'revision-ids',
'phids',
);
- $types = implode(', ', $types);
-
return array(
- 'query' => 'required enum<'.$types.'>',
+ 'query' => 'required '.$this->formatStringConstants($types),
'guids' => 'required nonempty list<guids>',
);
}
public function defineReturnType() {
return 'nonempty list<dict>';
}
public function defineErrorTypes() {
return array(
);
}
protected function execute(ConduitAPIRequest $request) {
$type = $request->getValue('query');
$guids = $request->getValue('guids');
$results = array();
if (!$guids) {
return $results;
}
$query = id(new DifferentialRevisionQuery())
->setViewer($request->getUser());
switch ($type) {
case 'open':
$query
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
->withAuthors($guids);
break;
case 'committable':
$query
->withStatus(DifferentialRevisionQuery::STATUS_ACCEPTED)
->withAuthors($guids);
break;
case 'revision-ids':
$query
->withIDs($guids);
break;
case 'owned':
$query->withAuthors($guids);
break;
case 'phids':
$query
->withPHIDs($guids);
break;
}
$revisions = $query->execute();
foreach ($revisions as $revision) {
$diff = $revision->loadActiveDiff();
if (!$diff) {
continue;
}
$id = $revision->getID();
$results[] = array(
'id' => $id,
'phid' => $revision->getPHID(),
'name' => $revision->getTitle(),
'uri' => PhabricatorEnv::getProductionURI('/D'.$id),
'dateCreated' => $revision->getDateCreated(),
'authorPHID' => $revision->getAuthorPHID(),
'statusName' =>
ArcanistDifferentialRevisionStatus::getNameForRevisionStatus(
$revision->getStatus()),
'sourcePath' => $diff->getSourcePath(),
);
}
return $results;
}
}
diff --git a/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php
index 7fdde3332a..505570305f 100644
--- a/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php
+++ b/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php
@@ -1,192 +1,194 @@
<?php
final class ConduitAPI_differential_getcommitmessage_Method
extends ConduitAPI_differential_Method {
public function getMethodDescription() {
return "Retrieve Differential commit messages or message templates.";
}
public function defineParamTypes() {
+ $edit_types = array('edit', 'create');
+
return array(
'revision_id' => 'optional revision_id',
'fields' => 'optional dict<string, wild>',
- 'edit' => 'optional enum<"edit", "create">',
+ 'edit' => 'optional '.$this->formatStringConstants($edit_types),
);
}
public function defineReturnType() {
return 'nonempty string';
}
public function defineErrorTypes() {
return array(
'ERR_NOT_FOUND' => 'Revision was not found.',
);
}
protected function execute(ConduitAPIRequest $request) {
$id = $request->getValue('revision_id');
$viewer = $request->getUser();
if ($id) {
$revision = id(new DifferentialRevisionQuery())
->withIDs(array($id))
->setViewer($viewer)
->needReviewerStatus(true)
->needActiveDiffs(true)
->executeOne();
if (!$revision) {
throw new ConduitException('ERR_NOT_FOUND');
}
} else {
$revision = DifferentialRevision::initializeNewRevision($viewer);
$revision->attachReviewerStatus(array());
$revision->attachActiveDiff(null);
}
$is_edit = $request->getValue('edit');
$is_create = ($is_edit == 'create');
$field_list = PhabricatorCustomField::getObjectFields(
$revision,
($is_edit
? DifferentialCustomField::ROLE_COMMITMESSAGEEDIT
: DifferentialCustomField::ROLE_COMMITMESSAGE));
$field_list
->setViewer($viewer)
->readFieldsFromStorage($revision);
$field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit');
if ($is_edit) {
$fields = $request->getValue('fields', array());
foreach ($fields as $field => $value) {
$custom_field = idx($field_map, $field);
if (!$custom_field) {
// Just ignore this, these workflows don't make strong distictions
// about field editability on the client side.
continue;
}
if ($is_create ||
$custom_field->shouldOverwriteWhenCommitMessageIsEdited()) {
$custom_field->readValueFromCommitMessage($value);
}
}
}
$phids = array();
foreach ($field_list->getFields() as $key => $field) {
$field_phids = $field->getRequiredHandlePHIDsForCommitMessage();
if (!is_array($field_phids)) {
throw new Exception(
pht(
'Custom field "%s" was expected to return an array of handle '.
'PHIDs required for commit message rendering, but returned "%s" '.
'instead.',
$field->getFieldKey(),
gettype($field_phids)));
}
$phids[$key] = $field_phids;
}
$all_phids = array_mergev($phids);
if ($all_phids) {
$all_handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs($all_phids)
->execute();
} else {
$all_handles = array();
}
$key_title = id(new DifferentialTitleField())->getFieldKey();
$default_title = DifferentialTitleField::getDefaultTitle();
$commit_message = array();
foreach ($field_list->getFields() as $key => $field) {
$handles = array_select_keys($all_handles, $phids[$key]);
$label = $field->renderCommitMessageLabel();
$value = $field->renderCommitMessageValue($handles);
if (!is_string($value) && !is_null($value)) {
throw new Exception(
pht(
'Custom field "%s" was expected to render a string or null value, '.
'but rendered a "%s" instead.',
$field->getFieldKey(),
gettype($value)));
}
$is_title = ($key == $key_title);
if (!strlen($value)) {
if ($is_title) {
$commit_message[] = $default_title;
} else {
if ($is_edit && $field->shouldAppearInCommitMessageTemplate()) {
$commit_message[] = $label.': ';
}
}
} else {
if ($is_title) {
$commit_message[] = $value;
} else {
$value = str_replace(
array("\r\n", "\r"),
array("\n", "\n"),
$value);
if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') {
$commit_message[] = "{$label}:\n{$value}";
} else {
$commit_message[] = "{$label}: {$value}";
}
}
}
}
if ($is_edit) {
$tip = $this->getProTip($field_list);
if ($tip !== null) {
$commit_message[] = "\n".$tip;
}
}
$commit_message = implode("\n\n", $commit_message);
return $commit_message;
}
private function getProTip() {
// Any field can provide tips, whether it normally appears on commit
// messages or not.
$field_list = PhabricatorCustomField::getObjectFields(
new DifferentialRevision(),
PhabricatorCustomField::ROLE_DEFAULT);
$tips = array();
foreach ($field_list->getFields() as $key => $field) {
$tips[] = $field->getProTips();
}
$tips = array_mergev($tips);
if (!$tips) {
return null;
}
shuffle($tips);
$tip = pht('Tip: %s', head($tips));
$tip = wordwrap($tip, 78, "\n", true);
$lines = explode("\n", $tip);
foreach ($lines as $key => $line) {
$lines[$key] = "# ".$line;
}
return implode("\n", $lines);
}
}
diff --git a/src/applications/differential/conduit/ConduitAPI_differential_query_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_query_Method.php
index 4d61b7863b..af979dbfac 100644
--- a/src/applications/differential/conduit/ConduitAPI_differential_query_Method.php
+++ b/src/applications/differential/conduit/ConduitAPI_differential_query_Method.php
@@ -1,243 +1,242 @@
<?php
final class ConduitAPI_differential_query_Method
extends ConduitAPI_differential_Method {
public function getMethodDescription() {
return "Query Differential revisions which match certain criteria.";
}
public function defineParamTypes() {
$hash_types = ArcanistDifferentialRevisionHash::getTypes();
- $hash_types = implode(', ', $hash_types);
+ $hash_const = $this->formatStringConstants($hash_types);
$status_types = array(
DifferentialRevisionQuery::STATUS_ANY,
DifferentialRevisionQuery::STATUS_OPEN,
DifferentialRevisionQuery::STATUS_ACCEPTED,
DifferentialRevisionQuery::STATUS_CLOSED,
);
- $status_types = implode(', ', $status_types);
+ $status_const = $this->formatStringConstants($status_types);
$order_types = array(
DifferentialRevisionQuery::ORDER_MODIFIED,
DifferentialRevisionQuery::ORDER_CREATED,
);
- $order_types = implode(', ', $order_types);
+ $order_const = $this->formatStringConstants($order_types);
return array(
'authors' => 'optional list<phid>',
'ccs' => 'optional list<phid>',
'reviewers' => 'optional list<phid>',
'paths' => 'optional list<pair<callsign, path>>',
- 'commitHashes' => 'optional list<pair<enum<'.
- $hash_types.'>, string>>',
- 'status' => 'optional enum<'.$status_types.'>',
- 'order' => 'optional enum<'.$order_types.'>',
+ 'commitHashes' => 'optional list<pair<'.$hash_const.', string>>',
+ 'status' => 'optional '.$status_const,
+ 'order' => 'optional '.$order_const,
'limit' => 'optional uint',
'offset' => 'optional uint',
'ids' => 'optional list<uint>',
'phids' => 'optional list<phid>',
'subscribers' => 'optional list<phid>',
'responsibleUsers' => 'optional list<phid>',
'branches' => 'optional list<string>',
'arcanistProjects' => 'optional list<string>',
);
}
public function defineReturnType() {
return 'list<dict>';
}
public function defineErrorTypes() {
return array(
'ERR-INVALID-PARAMETER' => 'Missing or malformed parameter.',
);
}
protected function execute(ConduitAPIRequest $request) {
$authors = $request->getValue('authors');
$ccs = $request->getValue('ccs');
$reviewers = $request->getValue('reviewers');
$status = $request->getValue('status');
$order = $request->getValue('order');
$path_pairs = $request->getValue('paths');
$commit_hashes = $request->getValue('commitHashes');
$limit = $request->getValue('limit');
$offset = $request->getValue('offset');
$ids = $request->getValue('ids');
$phids = $request->getValue('phids');
$subscribers = $request->getValue('subscribers');
$responsible_users = $request->getValue('responsibleUsers');
$branches = $request->getValue('branches');
$arc_projects = $request->getValue('arcanistProjects');
$query = id(new DifferentialRevisionQuery())
->setViewer($request->getUser());
if ($authors) {
$query->withAuthors($authors);
}
if ($ccs) {
$query->withCCs($ccs);
}
if ($reviewers) {
$query->withReviewers($reviewers);
}
if ($path_pairs) {
$paths = array();
foreach ($path_pairs as $pair) {
list($callsign, $path) = $pair;
$paths[] = $path;
}
$path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs();
if (count($path_map) != count($paths)) {
$unknown_paths = array();
foreach ($paths as $p) {
if (!idx($path_map, $p)) {
$unknown_paths[] = $p;
}
}
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
->setErrorDescription(
'Unknown paths: '.implode(', ', $unknown_paths));
}
$repos = array();
foreach ($path_pairs as $pair) {
list($callsign, $path) = $pair;
if (!idx($repos, $callsign)) {
$repos[$callsign] = id(new PhabricatorRepositoryQuery())
->setViewer($request->getUser())
->withCallsigns(array($callsign))
->executeOne();
if (!$repos[$callsign]) {
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
->setErrorDescription(
'Unknown repo callsign: '.$callsign);
}
}
$repo = $repos[$callsign];
$query->withPath($repo->getID(), idx($path_map, $path));
}
}
if ($commit_hashes) {
$hash_types = ArcanistDifferentialRevisionHash::getTypes();
foreach ($commit_hashes as $info) {
list($type, $hash) = $info;
if (empty($type) ||
!in_array($type, $hash_types) ||
empty($hash)) {
throw new ConduitException('ERR-INVALID-PARAMETER');
}
}
$query->withCommitHashes($commit_hashes);
}
if ($status) {
$query->withStatus($status);
}
if ($order) {
$query->setOrder($order);
}
if ($limit) {
$query->setLimit($limit);
}
if ($offset) {
$query->setOffset($offset);
}
if ($ids) {
$query->withIDs($ids);
}
if ($phids) {
$query->withPHIDs($phids);
}
if ($responsible_users) {
$query->withResponsibleUsers($responsible_users);
}
if ($subscribers) {
$query->withCCs($subscribers);
}
if ($branches) {
$query->withBranches($branches);
}
if ($arc_projects) {
// This is sort of special-cased, but don't make arc do an extra round
// trip.
$projects = id(new PhabricatorRepositoryArcanistProject())
->loadAllWhere(
'name in (%Ls)',
$arc_projects);
if (!$projects) {
return array();
}
$query->withArcanistProjectPHIDs(mpull($projects, 'getPHID'));
}
$query->needRelationships(true);
$query->needCommitPHIDs(true);
$query->needDiffIDs(true);
$query->needActiveDiffs(true);
$query->needHashes(true);
$revisions = $query->execute();
$field_data = $this->loadCustomFieldsForRevisions(
$request->getUser(),
$revisions);
$results = array();
foreach ($revisions as $revision) {
$diff = $revision->getActiveDiff();
if (!$diff) {
continue;
}
$id = $revision->getID();
$phid = $revision->getPHID();
$result = array(
'id' => $id,
'phid' => $phid,
'title' => $revision->getTitle(),
'uri' => PhabricatorEnv::getProductionURI('/D'.$id),
'dateCreated' => $revision->getDateCreated(),
'dateModified' => $revision->getDateModified(),
'authorPHID' => $revision->getAuthorPHID(),
'status' => $revision->getStatus(),
'statusName' =>
ArcanistDifferentialRevisionStatus::getNameForRevisionStatus(
$revision->getStatus()),
'branch' => $diff->getBranch(),
'summary' => $revision->getSummary(),
'testPlan' => $revision->getTestPlan(),
'lineCount' => $revision->getLineCount(),
'activeDiffPHID' => $diff->getPHID(),
'diffs' => $revision->getDiffIDs(),
'commits' => $revision->getCommitPHIDs(),
'reviewers' => array_values($revision->getReviewers()),
'ccs' => array_values($revision->getCCPHIDs()),
'hashes' => $revision->getHashes(),
'auxiliary' => idx($field_data, $phid, array()),
'arcanistProjectPHID' => $diff->getArcanistProjectPHID()
);
// TODO: This is a hacky way to put permissions on this field until we
// have first-class support, see T838.
if ($revision->getAuthorPHID() == $request->getUser()->getPHID()) {
$result['sourcePath'] = $diff->getSourcePath();
}
$results[] = $result;
}
return $results;
}
}
diff --git a/src/applications/harbormaster/conduit/ConduitAPI_harbormaster_sendmessage_Method.php b/src/applications/harbormaster/conduit/ConduitAPI_harbormaster_sendmessage_Method.php
index 9664290e65..67274d767d 100644
--- a/src/applications/harbormaster/conduit/ConduitAPI_harbormaster_sendmessage_Method.php
+++ b/src/applications/harbormaster/conduit/ConduitAPI_harbormaster_sendmessage_Method.php
@@ -1,57 +1,59 @@
<?php
final class ConduitAPI_harbormaster_sendmessage_Method
extends ConduitAPI_harbormaster_Method {
public function getMethodDescription() {
return pht(
'Send a message to a build target, notifying it of results in an '.
'external system.');
}
public function defineParamTypes() {
+ $type_const = $this->formatStringConstants(array('pass', 'fail'));
+
return array(
- 'buildTargetPHID' => 'phid',
- 'type' => 'enum<pass, fail>',
+ 'buildTargetPHID' => 'required phid',
+ 'type' => 'required '.$type_const,
);
}
public function defineReturnType() {
return 'void';
}
public function defineErrorTypes() {
return array();
}
protected function execute(ConduitAPIRequest $request) {
$viewer = $request->getUser();
$build_target_phid = $request->getValue('buildTargetPHID');
$message_type = $request->getValue('type');
$build_target = id(new HarbormasterBuildTargetQuery())
->setViewer($viewer)
->withPHIDs(array($build_target_phid))
->executeOne();
if (!$build_target) {
throw new Exception(pht('No such build target!'));
}
$message = HarbormasterBuildMessage::initializeNewMessage($viewer)
->setBuildTargetPHID($build_target->getPHID())
->setType($message_type)
->save();
// If the build has completely paused because all steps are blocked on
// waiting targets, this will resume it.
PhabricatorWorker::scheduleTask(
'HarbormasterBuildWorker',
array(
'buildID' => $build_target->getBuild()->getID(),
));
return null;
}
}
diff --git a/src/applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php b/src/applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php
index 7ad32d03e9..6ad94356bc 100644
--- a/src/applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php
+++ b/src/applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php
@@ -1,129 +1,129 @@
<?php
/**
* @group conduit
*
* TODO: Remove maniphest.find, then make this final.
*
* @concrete-extensible
*/
class ConduitAPI_maniphest_query_Method
extends ConduitAPI_maniphest_Method {
public function getMethodDescription() {
return "Execute complex searches for Maniphest tasks.";
}
public function defineParamTypes() {
$statuses = array(
ManiphestTaskQuery::STATUS_ANY,
ManiphestTaskQuery::STATUS_OPEN,
ManiphestTaskQuery::STATUS_CLOSED,
ManiphestTaskQuery::STATUS_RESOLVED,
ManiphestTaskQuery::STATUS_WONTFIX,
ManiphestTaskQuery::STATUS_INVALID,
ManiphestTaskQuery::STATUS_SPITE,
ManiphestTaskQuery::STATUS_DUPLICATE,
);
- $statuses = implode(', ', $statuses);
+ $status_const = $this->formatStringConstants($statuses);
$orders = array(
ManiphestTaskQuery::ORDER_PRIORITY,
ManiphestTaskQuery::ORDER_CREATED,
ManiphestTaskQuery::ORDER_MODIFIED,
);
- $orders = implode(', ', $orders);
+ $order_const = $this->formatStringConstants($orders);
return array(
'ids' => 'optional list<uint>',
'phids' => 'optional list<phid>',
'ownerPHIDs' => 'optional list<phid>',
'authorPHIDs' => 'optional list<phid>',
'projectPHIDs' => 'optional list<phid>',
'ccPHIDs' => 'optional list<phid>',
'fullText' => 'optional string',
- 'status' => 'optional enum<'.$statuses.'>',
- 'order' => 'optional enum<'.$orders.'>',
+ 'status' => 'optional '.$status_const,
+ 'order' => 'optional '.$order_const,
'limit' => 'optional int',
'offset' => 'optional int',
);
}
public function defineReturnType() {
return 'list';
}
public function defineErrorTypes() {
return array(
);
}
protected function execute(ConduitAPIRequest $request) {
$query = new ManiphestTaskQuery();
$query->setViewer($request->getUser());
$task_ids = $request->getValue('ids');
if ($task_ids) {
$query->withIDs($task_ids);
}
$task_phids = $request->getValue('phids');
if ($task_phids) {
$query->withPHIDs($task_phids);
}
$owners = $request->getValue('ownerPHIDs');
if ($owners) {
$query->withOwners($owners);
}
$authors = $request->getValue('authorPHIDs');
if ($authors) {
$query->withAuthors($authors);
}
$projects = $request->getValue('projectPHIDs');
if ($projects) {
$query->withAllProjects($projects);
}
$ccs = $request->getValue('ccPHIDs');
if ($ccs) {
$query->withSubscribers($ccs);
}
$full_text = $request->getValue('fullText');
if ($full_text) {
$query->withFullTextSearch($full_text);
}
$status = $request->getValue('status');
if ($status) {
$query->withStatus($status);
}
$order = $request->getValue('order');
if ($order) {
$query->setOrderBy($order);
}
$limit = $request->getValue('limit');
if ($limit) {
$query->setLimit($limit);
}
$offset = $request->getValue('offset');
if ($offset) {
$query->setOffset($offset);
}
$results = $query->execute();
return $this->buildTaskInfoDictionaries($results);
}
}
diff --git a/src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php b/src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php
index 224609e7ee..75b394b2ac 100644
--- a/src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php
+++ b/src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php
@@ -1,61 +1,63 @@
<?php
final class ConduitAPI_user_addstatus_Method
extends ConduitAPI_user_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_DEPRECATED;
}
public function getMethodDescription() {
return pht("Add status information to the logged-in user.");
}
public function getMethodStatusDescription() {
return pht(
'Statuses are becoming full-fledged events as part of the '.
'Calendar application.');
}
public function defineParamTypes() {
+ $status_const = $this->formatStringConstants(array('away', 'sporadic'));
+
return array(
'fromEpoch' => 'required int',
'toEpoch' => 'required int',
- 'status' => 'required enum<away, sporadic>',
+ 'status' => 'required '.$status_const,
'description' => 'optional string',
);
}
public function defineReturnType() {
return 'void';
}
public function defineErrorTypes() {
return array(
'ERR-BAD-EPOCH' => "'toEpoch' must be bigger than 'fromEpoch'.",
'ERR-OVERLAP' =>
'There must be no status in any part of the specified epoch.',
);
}
protected function execute(ConduitAPIRequest $request) {
$user_phid = $request->getUser()->getPHID();
$from = $request->getValue('fromEpoch');
$to = $request->getValue('toEpoch');
$status = $request->getValue('status');
$description = $request->getValue('description', '');
try {
id(new PhabricatorCalendarEvent())
->setUserPHID($user_phid)
->setDateFrom($from)
->setDateTo($to)
->setTextStatus($status)
->setDescription($description)
->save();
} catch (PhabricatorCalendarEventInvalidEpochException $e) {
throw new ConduitException('ERR-BAD-EPOCH');
}
}
}
diff --git a/src/applications/project/conduit/ConduitAPI_project_query_Method.php b/src/applications/project/conduit/ConduitAPI_project_query_Method.php
index f0d35bd410..b433741401 100644
--- a/src/applications/project/conduit/ConduitAPI_project_query_Method.php
+++ b/src/applications/project/conduit/ConduitAPI_project_query_Method.php
@@ -1,82 +1,84 @@
<?php
/**
* @group conduit
*/
final class ConduitAPI_project_query_Method extends ConduitAPI_project_Method {
public function getMethodDescription() {
return "Execute searches for Projects.";
}
public function defineParamTypes() {
$statuses = array(
PhabricatorProjectQuery::STATUS_ANY,
PhabricatorProjectQuery::STATUS_OPEN,
PhabricatorProjectQuery::STATUS_CLOSED,
PhabricatorProjectQuery::STATUS_ACTIVE,
PhabricatorProjectQuery::STATUS_ARCHIVED,
);
+ $status_const = $this->formatStringConstants($statuses);
+
return array(
'ids' => 'optional list<int>',
'phids' => 'optional list<phid>',
- 'status' => 'optional enum<'.implode(', ', $statuses).'>',
+ 'status' => 'optional '.$status_const,
'members' => 'optional list<phid>',
'limit' => 'optional int',
'offset' => 'optional int',
);
}
public function defineReturnType() {
return 'list';
}
public function defineErrorTypes() {
return array(
);
}
protected function execute(ConduitAPIRequest $request) {
$query = new PhabricatorProjectQuery();
$query->setViewer($request->getUser());
$query->needMembers(true);
$ids = $request->getValue('ids');
if ($ids) {
$query->withIDs($ids);
}
$status = $request->getValue('status');
if ($status) {
$query->withStatus($status);
}
$phids = $request->getValue('phids');
if ($phids) {
$query->withPHIDs($phids);
}
$members = $request->getValue('members');
if ($members) {
$query->withMemberPHIDs($members);
}
$limit = $request->getValue('limit');
if ($limit) {
$query->setLimit($limit);
}
$offset = $request->getValue('offset');
if ($offset) {
$query->setOffset($offset);
}
$results = $query->execute();
return $this->buildProjectInfoDictionaries($results);
}
}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
index 3bdf941c8d..632af4b8b7 100644
--- a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
@@ -1,94 +1,96 @@
<?php
final class ConduitAPI_releephwork_getcommitmessage_Method
extends ConduitAPI_releeph_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodDescription() {
return
"Get commit message components for building ".
"a ReleephRequest commit message.";
}
public function defineParamTypes() {
+ $action_const = $this->formatStringConstants(array('pick', 'revert'));
+
return array(
'requestPHID' => 'required string',
- 'action' => 'required enum<"pick", "revert">',
+ 'action' => 'required '.$action_const,
);
}
public function defineReturnType() {
return 'dict<string, string>';
}
public function defineErrorTypes() {
return array();
}
protected function execute(ConduitAPIRequest $request) {
$viewer = $request->getUser();
$releeph_request = id(new ReleephRequestQuery())
->setViewer($viewer)
->withPHIDs(array($request->getValue('requestPHID')))
->executeOne();
$action = $request->getValue('action');
$title = $releeph_request->getSummaryForDisplay();
$commit_message = array();
$branch = $releeph_request->getBranch();
$project = $branch->getProduct();
$selector = $project->getReleephFieldSelector();
$fields = $selector->getFieldSpecifications();
$fields = $selector->sortFieldsForCommitMessage($fields);
foreach ($fields as $field) {
$field
->setUser($request->getUser())
->setReleephProject($project)
->setReleephBranch($branch)
->setReleephRequest($releeph_request);
$label = null;
$value = null;
switch ($action) {
case 'pick':
if ($field->shouldAppearOnCommitMessage()) {
$label = $field->renderLabelForCommitMessage();
$value = $field->renderValueForCommitMessage();
}
break;
case 'revert':
if ($field->shouldAppearOnRevertMessage()) {
$label = $field->renderLabelForRevertMessage();
$value = $field->renderValueForRevertMessage();
}
break;
}
if ($label && $value) {
if (strpos($value, "\n") !== false ||
substr($value, 0, 2) === ' ') {
$commit_message[] = "{$label}:\n{$value}";
} else {
$commit_message[] = "{$label}: {$value}";
}
}
}
return array(
'title' => $title,
'body' => implode("\n\n", $commit_message),
);
}
}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
index 626ddb41d1..61f0362940 100644
--- a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
@@ -1,69 +1,75 @@
<?php
final class ConduitAPI_releephwork_record_Method
extends ConduitAPI_releeph_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
/**
* Record that a request was committed locally, and is about to be pushed to
* the remote repository.
*
* This lets us mark a ReleephRequest as being in a branch in real time so
* that no one else tries to pick it.
*
* When the daemons discover this commit in the repository with
* DifferentialReleephRequestFieldSpecification, we'll be able to record the
* commit's PHID as well. That process is slow though, and we don't want to
* wait a whole minute before marking something as cleanly picked or
* reverted.
*/
public function getMethodDescription() {
return "Record whether we committed a pick or revert ".
"to the upstream repository.";
}
public function defineParamTypes() {
+ $action_const = $this->formatStringConstants(
+ array(
+ 'pick',
+ 'revert',
+ ));
+
return array(
'requestPHID' => 'required string',
- 'action' => 'required enum<"pick", "revert">',
+ 'action' => 'required '.$action_const,
'commitIdentifier' => 'required string',
);
}
public function defineReturnType() {
return 'void';
}
public function defineErrorTypes() {
return array();
}
protected function execute(ConduitAPIRequest $request) {
$action = $request->getValue('action');
$new_commit_id = $request->getValue('commitIdentifier');
$releeph_request = id(new ReleephRequest())
->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
$xactions = array();
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_COMMIT)
->setMetadataValue('action', $action)
->setNewValue($new_commit_id);
$editor = id(new ReleephRequestTransactionalEditor())
->setActor($request->getUser())
->setContinueOnNoEffect(true)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_CONDUIT,
array()));
$editor->applyTransactions($releeph_request, $xactions);
}
}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
index 9b515b8d39..f351fd107d 100644
--- a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
@@ -1,77 +1,83 @@
<?php
final class ConduitAPI_releephwork_recordpickstatus_Method
extends ConduitAPI_releeph_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodDescription() {
return "Record whether a pick or revert was successful or not.";
}
public function defineParamTypes() {
+ $action_const = $this->formatStringConstants(
+ array(
+ 'pick',
+ 'revert',
+ ));
+
return array(
'requestPHID' => 'required string',
- 'action' => 'required enum<"pick", "revert">',
+ 'action' => 'required '.$action_const,
'ok' => 'required bool',
'dryRun' => 'optional bool',
'details' => 'optional dict<string, wild>',
);
}
public function defineReturnType() {
return '';
}
public function defineErrorTypes() {
return array();
}
protected function execute(ConduitAPIRequest $request) {
$action = $request->getValue('action');
$ok = $request->getValue('ok');
$dry_run = $request->getValue('dryRun');
$details = $request->getValue('details', array());
switch ($request->getValue('action')) {
case 'pick':
$pick_status = $ok
? ReleephRequest::PICK_OK
: ReleephRequest::PICK_FAILED;
break;
case 'revert':
$pick_status = $ok
? ReleephRequest::REVERT_OK
: ReleephRequest::REVERT_FAILED;
break;
default:
throw new Exception("Unknown action {$action}!");
}
$releeph_request = id(new ReleephRequest())
->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
$editor = id(new ReleephRequestTransactionalEditor())
->setActor($request->getUser())
->setContinueOnNoEffect(true)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_CONDUIT,
array()));
$xactions = array();
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_PICK_STATUS)
->setMetadataValue('dryRun', $dry_run)
->setMetadataValue('details', $details)
->setNewValue($pick_status);
$editor->applyTransactions($releeph_request, $xactions);
}
}
diff --git a/src/applications/remarkup/conduit/ConduitAPI_remarkup_process_Method.php b/src/applications/remarkup/conduit/ConduitAPI_remarkup_process_Method.php
index 8944c6e3c8..45a62bb64c 100644
--- a/src/applications/remarkup/conduit/ConduitAPI_remarkup_process_Method.php
+++ b/src/applications/remarkup/conduit/ConduitAPI_remarkup_process_Method.php
@@ -1,71 +1,71 @@
<?php
final class ConduitAPI_remarkup_process_Method extends ConduitAPIMethod {
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodDescription() {
return 'Process text through remarkup in phabricator context.';
}
public function defineReturnType() {
return 'nonempty dict';
}
public function defineErrorTypes() {
return array(
'ERR-NO-CONTENT' => 'Content may not be empty.',
'ERR-INVALID-ENGINE' => 'Invalid markup engine.',
);
}
public function defineParamTypes() {
$available_contexts = array_keys($this->getEngineContexts());
- $available_contexts = implode(', ', $available_contexts);
+ $available_const = $this->formatStringConstants($available_contexts);
return array(
- 'context' => 'required enum<'.$available_contexts.'>',
+ 'context' => 'required '.$available_const,
'contents' => 'required list<string>',
);
}
protected function execute(ConduitAPIRequest $request) {
$contents = $request->getValue('contents');
$context = $request->getValue('context');
$engine_class = idx($this->getEngineContexts(), $context);
if (!$engine_class) {
throw new ConduitException('ERR-INVALID_ENGINE');
}
$engine = PhabricatorMarkupEngine::$engine_class();
$engine->setConfig('viewer', $request->getUser());
$results = array();
foreach ($contents as $content) {
$text = $engine->markupText($content);
if ($text) {
$content = hsprintf('%s', $text)->getHTMLContent();
} else {
$content = '';
}
$results[] = array(
'content' => $content,
);
}
return $results;
}
private function getEngineContexts() {
return array(
'phriction' => 'newPhrictionMarkupEngine',
'maniphest' => 'newManiphestMarkupEngine',
'differential' => 'newDifferentialMarkupEngine',
'phame' => 'newPhameMarkupEngine',
'feed' => 'newFeedMarkupEngine',
'diffusion' => 'newDiffusionMarkupEngine',
);
}
}
diff --git a/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php b/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php
index 82e6ef3daf..5829351807 100644
--- a/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php
+++ b/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php
@@ -1,134 +1,136 @@
<?php
/**
* @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() {
+ $vcs_const = $this->formatStringConstants(array('git', 'hg', 'svn'));
+
return array(
'name' => 'required string',
- 'vcs' => 'required enum<git, hg, svn>',
+ 'vcs' => 'required '.$vcs_const,
'callsign' => 'required string',
'description' => 'optional string',
'encoding' => 'optional string',
'tracking' => 'optional bool',
'uri' => 'optional string',
'credentialPHID' => 'optional string',
'localPath' => 'optional string',
'svnSubpath' => 'optional string',
'branchFilter' => 'optional list<string>',
'closeCommitsFilter' => 'optional list<string>',
'pullFrequency' => 'optional int',
'defaultBranch' => 'optional string',
'heraldEnabled' => 'optional bool, default = true',
'autocloseEnabled' => 'optional bool, default = true',
'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) {
$application = id(new PhabricatorApplicationQuery())
->setViewer($request->getUser())
->withClasses(array('PhabricatorApplicationDiffusion'))
->executeOne();
PhabricatorPolicyFilter::requireCapability(
$request->getUser(),
$application,
DiffusionCapabilityCreateRepositories::CAPABILITY);
// 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. Specifically, this should move to transactions since they
// work properly now.
$repository = PhabricatorRepository::initializeNewRepository(
$request->getUser());
$repository->setName($request->getValue('name'));
$callsign = $request->getValue('callsign');
if (!preg_match('/^[A-Z]+\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]);
$repository->setCredentialPHID($request->getValue('credentialPHID'));
$details = array(
'encoding' => $request->getValue('encoding'),
'description' => $request->getValue('description'),
'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),
'close-commits-filter' => array_fill_keys(
$request->getValue('closeCommitsFilter', array()),
true),
'pull-frequency' => $request->getValue('pullFrequency'),
'default-branch' => $request->getValue('defaultBranch'),
'herald-disabled' => !$request->getValue('heraldEnabled', true),
'svn-subpath' => $request->getValue('svnSubpath'),
'disable-autoclose' => !$request->getValue('autocloseEnabled', true),
);
foreach ($details as $key => $value) {
$repository->setDetail($key, $value);
}
try {
$repository->save();
} catch (AphrontQueryDuplicateKeyException $ex) {
throw new ConduitException('ERR-DUPLICATE');
}
return $repository->toDictionary();
}
}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 21:06 (6 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128749
Default Alt Text
(60 KB)

Event Timeline