mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 10:00:55 +01:00
(stable) Promote 2017 Week 42
This commit is contained in:
commit
24ff632612
10 changed files with 288 additions and 87 deletions
|
@ -444,6 +444,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialDiffTransactionQuery' => 'applications/differential/query/DifferentialDiffTransactionQuery.php',
|
'DifferentialDiffTransactionQuery' => 'applications/differential/query/DifferentialDiffTransactionQuery.php',
|
||||||
'DifferentialDiffViewController' => 'applications/differential/controller/DifferentialDiffViewController.php',
|
'DifferentialDiffViewController' => 'applications/differential/controller/DifferentialDiffViewController.php',
|
||||||
'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'applications/differential/doorkeeper/DifferentialDoorkeeperRevisionFeedStoryPublisher.php',
|
'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'applications/differential/doorkeeper/DifferentialDoorkeeperRevisionFeedStoryPublisher.php',
|
||||||
|
'DifferentialDraftField' => 'applications/differential/customfield/DifferentialDraftField.php',
|
||||||
'DifferentialExactUserFunctionDatasource' => 'applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php',
|
'DifferentialExactUserFunctionDatasource' => 'applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php',
|
||||||
'DifferentialFieldParseException' => 'applications/differential/exception/DifferentialFieldParseException.php',
|
'DifferentialFieldParseException' => 'applications/differential/exception/DifferentialFieldParseException.php',
|
||||||
'DifferentialFieldValidationException' => 'applications/differential/exception/DifferentialFieldValidationException.php',
|
'DifferentialFieldValidationException' => 'applications/differential/exception/DifferentialFieldValidationException.php',
|
||||||
|
@ -5451,6 +5452,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialDiffTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'DifferentialDiffTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'DifferentialDiffViewController' => 'DifferentialController',
|
'DifferentialDiffViewController' => 'DifferentialController',
|
||||||
'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher',
|
'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher',
|
||||||
|
'DifferentialDraftField' => 'DifferentialCoreCustomField',
|
||||||
'DifferentialExactUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
'DifferentialExactUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||||
'DifferentialFieldParseException' => 'Exception',
|
'DifferentialFieldParseException' => 'Exception',
|
||||||
'DifferentialFieldValidationException' => 'Exception',
|
'DifferentialFieldValidationException' => 'Exception',
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DifferentialDraftField
|
||||||
|
extends DifferentialCoreCustomField {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'differential:draft';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFieldName() {
|
||||||
|
return pht('Draft');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFieldDescription() {
|
||||||
|
return pht('Show a warning about draft revisions.');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function readValueFromRevision(
|
||||||
|
DifferentialRevision $revision) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldAppearInPropertyView() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderPropertyViewValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWarningsForRevisionHeader(array $handles) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$revision = $this->getObject();
|
||||||
|
|
||||||
|
if (!$revision->isDraft()) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$warnings = array();
|
||||||
|
|
||||||
|
$blocking_map = array(
|
||||||
|
HarbormasterBuildStatus::STATUS_FAILED,
|
||||||
|
HarbormasterBuildStatus::STATUS_ABORTED,
|
||||||
|
HarbormasterBuildStatus::STATUS_ERROR,
|
||||||
|
HarbormasterBuildStatus::STATUS_PAUSED,
|
||||||
|
HarbormasterBuildStatus::STATUS_DEADLOCKED,
|
||||||
|
);
|
||||||
|
$blocking_map = array_fuse($blocking_map);
|
||||||
|
|
||||||
|
$builds = $revision->loadActiveBuilds($viewer);
|
||||||
|
|
||||||
|
$waiting = array();
|
||||||
|
$blocking = array();
|
||||||
|
foreach ($builds as $build) {
|
||||||
|
if (isset($blocking_map[$build->getBuildStatus()])) {
|
||||||
|
$blocking[] = $build;
|
||||||
|
} else {
|
||||||
|
$waiting[] = $build;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$blocking_list = $viewer->renderHandleList(mpull($blocking, 'getPHID'))
|
||||||
|
->setAsInline(true);
|
||||||
|
$waiting_list = $viewer->renderHandleList(mpull($waiting, 'getPHID'))
|
||||||
|
->setAsInline(true);
|
||||||
|
|
||||||
|
if ($blocking) {
|
||||||
|
$warnings[] = pht(
|
||||||
|
'This draft revision will not be submitted for review because %s '.
|
||||||
|
'build(s) failed: %s.',
|
||||||
|
phutil_count($blocking),
|
||||||
|
$blocking_list);
|
||||||
|
$warnings[] = pht(
|
||||||
|
'Fix build failures and update the revision.');
|
||||||
|
} else if ($waiting) {
|
||||||
|
$warnings[] = pht(
|
||||||
|
'This draft revision will be sent for review once %s '.
|
||||||
|
'build(s) pass: %s.',
|
||||||
|
phutil_count($waiting),
|
||||||
|
$waiting_list);
|
||||||
|
} else {
|
||||||
|
$warnings[] = pht(
|
||||||
|
'This is a draft revision that has not yet been submitted for '.
|
||||||
|
'review.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $warnings;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1570,58 +1570,12 @@ final class DifferentialTransactionEditor
|
||||||
|
|
||||||
private function hasActiveBuilds($object) {
|
private function hasActiveBuilds($object) {
|
||||||
$viewer = $this->requireActor();
|
$viewer = $this->requireActor();
|
||||||
$diff = $object->getActiveDiff();
|
|
||||||
|
|
||||||
$buildables = id(new HarbormasterBuildableQuery())
|
$builds = $object->loadActiveBuilds($viewer);
|
||||||
->setViewer($viewer)
|
|
||||||
->withContainerPHIDs(array($object->getPHID()))
|
|
||||||
->withBuildablePHIDs(array($diff->getPHID()))
|
|
||||||
->withManualBuildables(false)
|
|
||||||
->execute();
|
|
||||||
if (!$buildables) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$builds = id(new HarbormasterBuildQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withBuildablePHIDs(mpull($buildables, 'getPHID'))
|
|
||||||
->withBuildStatuses(
|
|
||||||
array(
|
|
||||||
HarbormasterBuildStatus::STATUS_INACTIVE,
|
|
||||||
HarbormasterBuildStatus::STATUS_PENDING,
|
|
||||||
HarbormasterBuildStatus::STATUS_BUILDING,
|
|
||||||
HarbormasterBuildStatus::STATUS_FAILED,
|
|
||||||
HarbormasterBuildStatus::STATUS_ABORTED,
|
|
||||||
HarbormasterBuildStatus::STATUS_ERROR,
|
|
||||||
HarbormasterBuildStatus::STATUS_PAUSED,
|
|
||||||
HarbormasterBuildStatus::STATUS_DEADLOCKED,
|
|
||||||
))
|
|
||||||
->needBuildTargets(true)
|
|
||||||
->execute();
|
|
||||||
if (!$builds) {
|
if (!$builds) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$active = array();
|
|
||||||
foreach ($builds as $key => $build) {
|
|
||||||
foreach ($build->getBuildTargets() as $target) {
|
|
||||||
if ($target->isAutotarget()) {
|
|
||||||
// Ignore autotargets when looking for active of failed builds. If
|
|
||||||
// local tests fail and you continue anyway, you don't need to
|
|
||||||
// double-confirm them.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This build has at least one real target that's doing something.
|
|
||||||
$active[$key] = $build;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$active) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,20 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
|
|
||||||
$column_width = 4;
|
$column_width = 4;
|
||||||
|
|
||||||
|
$aural_minus = javelin_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'aural' => true,
|
||||||
|
),
|
||||||
|
'- ');
|
||||||
|
|
||||||
|
$aural_plus = javelin_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'aural' => true,
|
||||||
|
),
|
||||||
|
'+ ');
|
||||||
|
|
||||||
$out = array();
|
$out = array();
|
||||||
foreach ($primitives as $k => $p) {
|
foreach ($primitives as $k => $p) {
|
||||||
$type = $p['type'];
|
$type = $p['type'];
|
||||||
|
@ -55,8 +69,10 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
if ($is_old) {
|
if ($is_old) {
|
||||||
if ($p['htype']) {
|
if ($p['htype']) {
|
||||||
$class = 'left old';
|
$class = 'left old';
|
||||||
|
$aural = $aural_minus;
|
||||||
} else {
|
} else {
|
||||||
$class = 'left';
|
$class = 'left';
|
||||||
|
$aural = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type == 'old-file') {
|
if ($type == 'old-file') {
|
||||||
|
@ -79,14 +95,20 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
),
|
),
|
||||||
$line);
|
$line);
|
||||||
|
|
||||||
|
$render = $p['render'];
|
||||||
|
if ($aural !== null) {
|
||||||
|
$render = array($aural, $render);
|
||||||
|
}
|
||||||
|
|
||||||
$cells[] = phutil_tag('th', array('class' => $class));
|
$cells[] = phutil_tag('th', array('class' => $class));
|
||||||
$cells[] = $no_copy;
|
$cells[] = $no_copy;
|
||||||
$cells[] = phutil_tag('td', array('class' => $class), $p['render']);
|
$cells[] = phutil_tag('td', array('class' => $class), $render);
|
||||||
$cells[] = $no_coverage;
|
$cells[] = $no_coverage;
|
||||||
} else {
|
} else {
|
||||||
if ($p['htype']) {
|
if ($p['htype']) {
|
||||||
$class = 'right new';
|
$class = 'right new';
|
||||||
$cells[] = phutil_tag('th', array('class' => $class));
|
$cells[] = phutil_tag('th', array('class' => $class));
|
||||||
|
$aural = $aural_plus;
|
||||||
} else {
|
} else {
|
||||||
$class = 'right';
|
$class = 'right';
|
||||||
if ($left_prefix) {
|
if ($left_prefix) {
|
||||||
|
@ -98,6 +120,7 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
$oline = $p['oline'];
|
$oline = $p['oline'];
|
||||||
|
|
||||||
$cells[] = phutil_tag('th', array('id' => $left_id), $oline);
|
$cells[] = phutil_tag('th', array('id' => $left_id), $oline);
|
||||||
|
$aural = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type == 'new-file') {
|
if ($type == 'new-file') {
|
||||||
|
@ -120,8 +143,13 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
),
|
),
|
||||||
$line);
|
$line);
|
||||||
|
|
||||||
|
$render = $p['render'];
|
||||||
|
if ($aural !== null) {
|
||||||
|
$render = array($aural, $render);
|
||||||
|
}
|
||||||
|
|
||||||
$cells[] = $no_copy;
|
$cells[] = $no_copy;
|
||||||
$cells[] = phutil_tag('td', array('class' => $class), $p['render']);
|
$cells[] = phutil_tag('td', array('class' => $class), $render);
|
||||||
$cells[] = $no_coverage;
|
$cells[] = $no_coverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,13 +67,19 @@ final class DifferentialRevision extends DifferentialDAO
|
||||||
$view_policy = $app->getPolicy(
|
$view_policy = $app->getPolicy(
|
||||||
DifferentialDefaultViewCapability::CAPABILITY);
|
DifferentialDefaultViewCapability::CAPABILITY);
|
||||||
|
|
||||||
|
if (PhabricatorEnv::getEnvConfig('phabricator.show-prototypes')) {
|
||||||
|
$initial_state = DifferentialRevisionStatus::DRAFT;
|
||||||
|
} else {
|
||||||
|
$initial_state = DifferentialRevisionStatus::NEEDS_REVIEW;
|
||||||
|
}
|
||||||
|
|
||||||
return id(new DifferentialRevision())
|
return id(new DifferentialRevision())
|
||||||
->setViewPolicy($view_policy)
|
->setViewPolicy($view_policy)
|
||||||
->setAuthorPHID($actor->getPHID())
|
->setAuthorPHID($actor->getPHID())
|
||||||
->attachRepository(null)
|
->attachRepository(null)
|
||||||
->attachActiveDiff(null)
|
->attachActiveDiff(null)
|
||||||
->attachReviewers(array())
|
->attachReviewers(array())
|
||||||
->setModernRevisionStatus(DifferentialRevisionStatus::NEEDS_REVIEW);
|
->setModernRevisionStatus($initial_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
|
@ -702,6 +708,58 @@ final class DifferentialRevision extends DifferentialDAO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadActiveBuilds(PhabricatorUser $viewer) {
|
||||||
|
$diff = $this->getActiveDiff();
|
||||||
|
|
||||||
|
$buildables = id(new HarbormasterBuildableQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withContainerPHIDs(array($this->getPHID()))
|
||||||
|
->withBuildablePHIDs(array($diff->getPHID()))
|
||||||
|
->withManualBuildables(false)
|
||||||
|
->execute();
|
||||||
|
if (!$buildables) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$builds = id(new HarbormasterBuildQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withBuildablePHIDs(mpull($buildables, 'getPHID'))
|
||||||
|
->withBuildStatuses(
|
||||||
|
array(
|
||||||
|
HarbormasterBuildStatus::STATUS_INACTIVE,
|
||||||
|
HarbormasterBuildStatus::STATUS_PENDING,
|
||||||
|
HarbormasterBuildStatus::STATUS_BUILDING,
|
||||||
|
HarbormasterBuildStatus::STATUS_FAILED,
|
||||||
|
HarbormasterBuildStatus::STATUS_ABORTED,
|
||||||
|
HarbormasterBuildStatus::STATUS_ERROR,
|
||||||
|
HarbormasterBuildStatus::STATUS_PAUSED,
|
||||||
|
HarbormasterBuildStatus::STATUS_DEADLOCKED,
|
||||||
|
))
|
||||||
|
->needBuildTargets(true)
|
||||||
|
->execute();
|
||||||
|
if (!$builds) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$active = array();
|
||||||
|
foreach ($builds as $key => $build) {
|
||||||
|
foreach ($build->getBuildTargets() as $target) {
|
||||||
|
if ($target->isAutotarget()) {
|
||||||
|
// Ignore autotargets when looking for active of failed builds. If
|
||||||
|
// local tests fail and you continue anyway, you don't need to
|
||||||
|
// double-confirm them.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This build has at least one real target that's doing something.
|
||||||
|
$active[$key] = $build;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $active;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( HarbormasterBuildableInterface )------------------------------------- */
|
/* -( HarbormasterBuildableInterface )------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,66 @@ final class DiffusionLowLevelResolveRefsQuery
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If some of the refs look like hashes, try to bulk resolve them. This
|
||||||
|
// workflow happens via RefEngine and bulk resolution is dramatically
|
||||||
|
// faster than individual resolution. See PHI158.
|
||||||
|
|
||||||
|
$hashlike = array();
|
||||||
|
foreach ($unresolved as $key => $ref) {
|
||||||
|
if (preg_match('/^[a-f0-9]{40}\z/', $ref)) {
|
||||||
|
$hashlike[$key] = $ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($hashlike) > 1) {
|
||||||
|
$hashlike_map = array();
|
||||||
|
|
||||||
|
$hashlike_groups = array_chunk($hashlike, 64, true);
|
||||||
|
foreach ($hashlike_groups as $hashlike_group) {
|
||||||
|
$hashlike_arg = array();
|
||||||
|
foreach ($hashlike_group as $hashlike_ref) {
|
||||||
|
$hashlike_arg[] = hgsprintf('%s', $hashlike_ref);
|
||||||
|
}
|
||||||
|
$hashlike_arg = '('.implode(' or ', $hashlike_arg).')';
|
||||||
|
|
||||||
|
list($err, $refs) = $repository->execLocalCommand(
|
||||||
|
'log --template=%s --rev %s',
|
||||||
|
'{node}\n',
|
||||||
|
$hashlike_arg);
|
||||||
|
if ($err) {
|
||||||
|
// NOTE: If any ref fails to resolve, Mercurial will exit with an
|
||||||
|
// error. We just give up on the whole group and resolve it
|
||||||
|
// individually below. In theory, we could split it into subgroups
|
||||||
|
// but the pathway where this bulk resolution matters rarely tries
|
||||||
|
// to resolve missing refs (see PHI158).
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$refs = phutil_split_lines($refs, false);
|
||||||
|
|
||||||
|
foreach ($refs as $ref) {
|
||||||
|
$hashlike_map[$ref] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($unresolved as $key => $ref) {
|
||||||
|
if (!isset($hashlike_map[$ref])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[$ref][] = array(
|
||||||
|
'type' => 'commit',
|
||||||
|
'identifier' => $ref,
|
||||||
|
);
|
||||||
|
|
||||||
|
unset($unresolved[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$unresolved) {
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
// If we still have unresolved refs (which might be things like "tip"),
|
// If we still have unresolved refs (which might be things like "tip"),
|
||||||
// try to resolve them individually.
|
// try to resolve them individually.
|
||||||
|
|
||||||
|
|
|
@ -15,4 +15,8 @@ final class PhabricatorOwnersPackageTransaction
|
||||||
return 'PhabricatorOwnersPackageTransactionType';
|
return 'PhabricatorOwnersPackageTransactionType';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionCommentObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,49 @@ final class PhabricatorSearchManagementNgramsWorkflow
|
||||||
'name' => 'reset',
|
'name' => 'reset',
|
||||||
'help' => pht('Reset all common ngram records.'),
|
'help' => pht('Reset all common ngram records.'),
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'threshold',
|
||||||
|
'param' => 'threshold',
|
||||||
|
'help' => pht(
|
||||||
|
'Prune ngrams present in more than this fraction of '.
|
||||||
|
'documents. Provide a value between 0.0 and 1.0.'),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute(PhutilArgumentParser $args) {
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$min_documents = 4096;
|
||||||
|
|
||||||
$is_reset = $args->getArg('reset');
|
$is_reset = $args->getArg('reset');
|
||||||
|
$threshold = $args->getArg('threshold');
|
||||||
|
|
||||||
|
if ($is_reset && $threshold !== null) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('Specify either --reset or --threshold, not both.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$is_reset && $threshold === null) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('Specify either --reset or --threshold.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$is_reset) {
|
||||||
|
if (!is_numeric($threshold)) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('Specify a numeric threshold between 0 and 1.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$threshold = (double)$threshold;
|
||||||
|
if ($threshold <= 0 || $threshold >= 1) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('Threshold must be greater than 0.0 and less than 1.0.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$all_objects = id(new PhutilClassMapQuery())
|
$all_objects = id(new PhutilClassMapQuery())
|
||||||
->setAncestorClass('PhabricatorFerretInterface')
|
->setAncestorClass('PhabricatorFerretInterface')
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$min_documents = 4096;
|
|
||||||
$threshold = 0.15;
|
|
||||||
|
|
||||||
foreach ($all_objects as $object) {
|
foreach ($all_objects as $object) {
|
||||||
$engine = $object->newFerretEngine();
|
$engine = $object->newFerretEngine();
|
||||||
$conn = $object->establishConnection('w');
|
$conn = $object->establishConnection('w');
|
||||||
|
|
|
@ -9,8 +9,6 @@ Overview
|
||||||
Phabricator includes //prototype applications//, which are applications in an
|
Phabricator includes //prototype applications//, which are applications in an
|
||||||
early stage of development.
|
early stage of development.
|
||||||
|
|
||||||
IMPORTANT: The upstream does not offer support for these applications.
|
|
||||||
|
|
||||||
When we begin working on a new application, we usually implement it as a
|
When we begin working on a new application, we usually implement it as a
|
||||||
prototype first. This allows us to get a better sense of how the application
|
prototype first. This allows us to get a better sense of how the application
|
||||||
might work and integrate with other applications, and what technical and product
|
might work and integrate with other applications, and what technical and product
|
||||||
|
@ -32,34 +30,3 @@ on hold indefinitely if we're less excited about it after we begin building it.
|
||||||
|
|
||||||
If you're interested in previewing upcoming applications, you can use the
|
If you're interested in previewing upcoming applications, you can use the
|
||||||
`phabricator.show-prototypes` configuration setting to enable prototypes.
|
`phabricator.show-prototypes` configuration setting to enable prototypes.
|
||||||
|
|
||||||
Feedback on Prototypes
|
|
||||||
======================
|
|
||||||
|
|
||||||
We're usually interested in this sort of feedback on prototypes:
|
|
||||||
|
|
||||||
- {icon check, color=green} **Use Cases**: If we're building something that
|
|
||||||
you think you'd use, we'd love to hear about your use cases for it. This can
|
|
||||||
help us figure out what features to add and how users may think about, use,
|
|
||||||
and integrate the application.
|
|
||||||
- {icon check, color=green} **General Interest**: Is an application something
|
|
||||||
you're looking forward to? Knowing which applications users are interested
|
|
||||||
in can help us set priorities.
|
|
||||||
|
|
||||||
We're usually **not** interested in this sort of feedback on prototypes:
|
|
||||||
|
|
||||||
- {icon times, color=red} **Support Requests**: We do not support these
|
|
||||||
applications. Use them at your own risk, or wait for them to leave the
|
|
||||||
prototype phase.
|
|
||||||
- {icon times, color=red} **Bug Reports**: We know these applications don't
|
|
||||||
work well yet, and usually know about most of the open bugs. Even if we
|
|
||||||
don't, whatever isn't working yet may change completely before the
|
|
||||||
application leaves the prototype phase.
|
|
||||||
- {icon times, color=red} **Contributions / Pull Requests**: These
|
|
||||||
applications are usually in too early a state to accept contributions. Let
|
|
||||||
us know about your use case, but wait for release to send code.
|
|
||||||
|
|
||||||
Overall, using prototypes makes it easier for us to explore and develop
|
|
||||||
application ideas, and to share a preview of what's coming in the future with
|
|
||||||
users, but prototypes are not yet full applications and we do not provide
|
|
||||||
support until applications leave the prototype phase.
|
|
||||||
|
|
|
@ -35,7 +35,15 @@ final class PhabricatorClientRateLimit
|
||||||
// If the user was logged in, let them make more requests.
|
// If the user was logged in, let them make more requests.
|
||||||
if (isset($request_state['viewer'])) {
|
if (isset($request_state['viewer'])) {
|
||||||
$viewer = $request_state['viewer'];
|
$viewer = $request_state['viewer'];
|
||||||
if ($viewer->isLoggedIn()) {
|
if ($viewer->isOmnipotent()) {
|
||||||
|
// If the viewer was omnipotent, this was an intracluster request or
|
||||||
|
// some other kind of special request, so don't give it any points
|
||||||
|
// toward rate limiting.
|
||||||
|
$score = 0;
|
||||||
|
} else if ($viewer->isLoggedIn()) {
|
||||||
|
// If the viewer was logged in, give them fewer points than if they
|
||||||
|
// were logged out, since this traffic is much more likely to be
|
||||||
|
// legitimate.
|
||||||
$score = 0.25;
|
$score = 0.25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue