mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Add Herald support for blocking ref changes
Summary: Ref T4195. Allows users to write Herald rules which block ref changes. For example, you can write a rule like `alincoln can not create branches`, or `no one can push to the branch "frozen"`. Test Plan: This covers a lot of ground. I created and pushed a bunch of rules, then looked at transcripts, in general. Here are some bits in detail: Here's a hook-based reject message: >>> orbital ~/repos/POEMS $ git push Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 274 bytes, done. Total 3 (delta 2), reused 0 (delta 0) remote: +---------------------------------------------------------------+ remote: | * * * PUSH REJECTED BY EVIL DRAGON BUREAUCRATS * * * | remote: +---------------------------------------------------------------+ remote: \ remote: \ ^ /^ remote: \ / \ // \ remote: \ |\___/| / \// .\ remote: \ /V V \__ / // | \ \ *----* remote: / / \/_/ // | \ \ \ | remote: @___@` \/_ // | \ \ \/\ \ remote: 0/0/| \/_ // | \ \ \ \ remote: 0/0/0/0/| \/// | \ \ | | remote: 0/0/0/0/0/_|_ / ( // | \ _\ | / remote: 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / remote: ,-} _ *-.|.-~-. .~ ~ remote: \ \__/ `/\ / ~-. _ .-~ / remote: \____(Oo) *. } { / remote: ( (--) .----~-.\ \-` .~ remote: //__\\ \ DENIED! ///.----..< \ _ -~ remote: // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ remote: remote: remote: This commit was rejected by Herald pre-commit rule H24. remote: Rule: No Branches Called Blarp remote: Reason: "blarp" is a bad branch name remote: To ssh://dweller@localhost/diffusion/POEMS/ ! [remote rejected] blarp -> blarp (pre-receive hook declined) error: failed to push some refs to 'ssh://dweller@localhost/diffusion/POEMS/' Here's a transcript, showing that all the field values populate sensibly: {F90453} Here's a rule: {F90454} Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4195 Differential Revision: https://secure.phabricator.com/D7782
This commit is contained in:
parent
baa756a027
commit
3386920971
11 changed files with 341 additions and 17 deletions
|
@ -1211,7 +1211,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'herald-rule-editor' =>
|
||||
array(
|
||||
'uri' => '/res/928275b4/rsrc/js/application/herald/HeraldRuleEditor.js',
|
||||
'uri' => '/res/92c05b75/rsrc/js/application/herald/HeraldRuleEditor.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
|
|
@ -756,6 +756,7 @@ phutil_register_library_map(array(
|
|||
'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php',
|
||||
'HeraldPHIDTypeRule' => 'applications/herald/phid/HeraldPHIDTypeRule.php',
|
||||
'HeraldPholioMockAdapter' => 'applications/herald/adapter/HeraldPholioMockAdapter.php',
|
||||
'HeraldPreCommitRefAdapter' => 'applications/diffusion/herald/HeraldPreCommitRefAdapter.php',
|
||||
'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php',
|
||||
'HeraldRepetitionPolicyConfig' => 'applications/herald/config/HeraldRepetitionPolicyConfig.php',
|
||||
'HeraldRule' => 'applications/herald/storage/HeraldRule.php',
|
||||
|
@ -3177,6 +3178,7 @@ phutil_register_library_map(array(
|
|||
'HeraldNewController' => 'HeraldController',
|
||||
'HeraldPHIDTypeRule' => 'PhabricatorPHIDType',
|
||||
'HeraldPholioMockAdapter' => 'HeraldAdapter',
|
||||
'HeraldPreCommitRefAdapter' => 'HeraldAdapter',
|
||||
'HeraldRecursiveConditionsException' => 'Exception',
|
||||
'HeraldRule' =>
|
||||
array(
|
||||
|
|
|
@ -26,6 +26,8 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
private $transactionKey;
|
||||
private $mercurialHook;
|
||||
|
||||
private $heraldViewerProjects;
|
||||
|
||||
|
||||
/* -( Config )------------------------------------------------------------- */
|
||||
|
||||
|
@ -130,7 +132,7 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
throw $ex;
|
||||
}
|
||||
|
||||
// TODO: Fire ref herald rules.
|
||||
$this->applyHeraldRefRules($ref_updates);
|
||||
|
||||
$content_updates = $this->findContentUpdates($ref_updates);
|
||||
$all_updates = array_merge($all_updates, $content_updates);
|
||||
|
@ -221,6 +223,84 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
}
|
||||
|
||||
|
||||
/* -( Herald )------------------------------------------------------------- */
|
||||
|
||||
|
||||
private function applyHeraldRefRules(array $ref_updates) {
|
||||
if (!$ref_updates) {
|
||||
return;
|
||||
}
|
||||
|
||||
$engine = new HeraldEngine();
|
||||
$rules = null;
|
||||
$blocking_effect = null;
|
||||
foreach ($ref_updates as $ref_update) {
|
||||
$adapter = id(new HeraldPreCommitRefAdapter())
|
||||
->setPushLog($ref_update)
|
||||
->setHookEngine($this);
|
||||
|
||||
if ($rules === null) {
|
||||
$rules = $engine->loadRulesForAdapter($adapter);
|
||||
}
|
||||
|
||||
$effects = $engine->applyRules($rules, $adapter);
|
||||
$engine->applyEffects($effects, $adapter, $rules);
|
||||
$xscript = $engine->getTranscript();
|
||||
|
||||
if ($blocking_effect === null) {
|
||||
foreach ($effects as $effect) {
|
||||
if ($effect->getAction() == HeraldAdapter::ACTION_BLOCK) {
|
||||
$blocking_effect = $effect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($blocking_effect) {
|
||||
foreach ($ref_updates as $ref_update) {
|
||||
$ref_update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_HERALD);
|
||||
$ref_update->setRejectDetails($blocking_effect->getRulePHID());
|
||||
}
|
||||
|
||||
$message = $blocking_effect->getTarget();
|
||||
if (!strlen($message)) {
|
||||
$message = pht('(None.)');
|
||||
}
|
||||
|
||||
$rules = mpull($rules, null, 'getID');
|
||||
$rule = idx($rules, $effect->getRuleID());
|
||||
if ($rule && strlen($rule->getName())) {
|
||||
$rule_name = $rule->getName();
|
||||
} else {
|
||||
$rule_name = pht('Unnamed Herald Rule');
|
||||
}
|
||||
|
||||
throw new DiffusionCommitHookRejectException(
|
||||
pht(
|
||||
"This commit was rejected by Herald pre-commit rule %s.\n".
|
||||
"Rule: %s\n".
|
||||
"Reason: %s",
|
||||
'H'.$blocking_effect->getRuleID(),
|
||||
$rule_name,
|
||||
$message));
|
||||
}
|
||||
}
|
||||
|
||||
public function loadViewerProjectPHIDsForHerald() {
|
||||
// This just caches the viewer's projects so we don't need to load them
|
||||
// over and over again when applying Herald rules.
|
||||
if ($this->heraldViewerProjects === null) {
|
||||
$this->heraldViewerProjects = id(new PhabricatorProjectQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withMemberPHIDs(array($this->getViewer()->getPHID()))
|
||||
->execute();
|
||||
}
|
||||
|
||||
return mpull($this->heraldViewerProjects, 'getPHID');
|
||||
}
|
||||
|
||||
|
||||
/* -( Git )---------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
@ -246,8 +326,10 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
|
||||
if (preg_match('(^refs/heads/)', $ref_raw)) {
|
||||
$ref_type = PhabricatorRepositoryPushLog::REFTYPE_BRANCH;
|
||||
$ref_raw = substr($ref_raw, strlen('refs/heads/'));
|
||||
} else if (preg_match('(^refs/tags/)', $ref_raw)) {
|
||||
$ref_type = PhabricatorRepositoryPushLog::REFTYPE_TAG;
|
||||
$ref_raw = substr($ref_raw, strlen('refs/tags/'));
|
||||
} else {
|
||||
throw new Exception(
|
||||
pht(
|
||||
|
@ -764,7 +846,12 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
// code. This indicates a broken hook, and covers the case where we
|
||||
// encounter some unexpected exception and consequently reject the changes.
|
||||
|
||||
// NOTE: We generate PHIDs up front so the Herald transcripts can pick them
|
||||
// up.
|
||||
$phid = id(new PhabricatorRepositoryPushLog())->generatePHID();
|
||||
|
||||
return PhabricatorRepositoryPushLog::initializeNewLog($this->getViewer())
|
||||
->setPHID($phid)
|
||||
->attachRepository($this->getRepository())
|
||||
->setRepositoryPHID($this->getRepository()->getPHID())
|
||||
->setEpoch(time())
|
||||
|
|
163
src/applications/diffusion/herald/HeraldPreCommitRefAdapter.php
Normal file
163
src/applications/diffusion/herald/HeraldPreCommitRefAdapter.php
Normal file
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
|
||||
final class HeraldPreCommitRefAdapter extends HeraldAdapter {
|
||||
|
||||
private $log;
|
||||
private $hookEngine;
|
||||
|
||||
const FIELD_REF_TYPE = 'ref-type';
|
||||
const FIELD_REF_NAME = 'ref-name';
|
||||
const FIELD_REF_CHANGE = 'ref-change';
|
||||
|
||||
const VALUE_REF_TYPE = 'value-ref-type';
|
||||
const VALUE_REF_CHANGE = 'value-ref-change';
|
||||
|
||||
public function setPushLog(PhabricatorRepositoryPushLog $log) {
|
||||
$this->log = $log;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHookEngine(DiffusionCommitHookEngine $engine) {
|
||||
$this->hookEngine = $engine;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAdapterApplicationClass() {
|
||||
return 'PhabricatorApplicationDiffusion';
|
||||
}
|
||||
|
||||
public function getObject() {
|
||||
return $this->log;
|
||||
}
|
||||
|
||||
public function getAdapterContentName() {
|
||||
return pht('Commit Hook: Branches/Tags/Bookmarks');
|
||||
}
|
||||
|
||||
public function getFieldNameMap() {
|
||||
return array(
|
||||
self::FIELD_REF_TYPE => pht('Ref type'),
|
||||
self::FIELD_REF_NAME => pht('Ref name'),
|
||||
self::FIELD_REF_CHANGE => pht('Ref change type'),
|
||||
) + parent::getFieldNameMap();
|
||||
}
|
||||
|
||||
public function getFields() {
|
||||
return array_merge(
|
||||
array(
|
||||
self::FIELD_REF_TYPE,
|
||||
self::FIELD_REF_NAME,
|
||||
self::FIELD_REF_CHANGE,
|
||||
self::FIELD_REPOSITORY,
|
||||
self::FIELD_PUSHER,
|
||||
self::FIELD_PUSHER_PROJECTS,
|
||||
self::FIELD_RULE,
|
||||
),
|
||||
parent::getFields());
|
||||
}
|
||||
|
||||
public function getConditionsForField($field) {
|
||||
switch ($field) {
|
||||
case self::FIELD_REF_NAME:
|
||||
return array(
|
||||
self::CONDITION_IS,
|
||||
self::CONDITION_IS_NOT,
|
||||
self::CONDITION_CONTAINS,
|
||||
self::CONDITION_REGEXP,
|
||||
);
|
||||
case self::FIELD_REF_TYPE:
|
||||
return array(
|
||||
self::CONDITION_IS,
|
||||
self::CONDITION_IS_NOT,
|
||||
);
|
||||
case self::FIELD_REF_CHANGE:
|
||||
return array(
|
||||
self::CONDITION_HAS_BIT,
|
||||
self::CONDITION_NOT_BIT,
|
||||
);
|
||||
}
|
||||
return parent::getConditionsForField($field);
|
||||
}
|
||||
|
||||
public function getActions($rule_type) {
|
||||
switch ($rule_type) {
|
||||
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
|
||||
return array(
|
||||
self::ACTION_BLOCK,
|
||||
self::ACTION_NOTHING
|
||||
);
|
||||
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
|
||||
return array(
|
||||
self::ACTION_NOTHING,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function getValueTypeForFieldAndCondition($field, $condition) {
|
||||
switch ($field) {
|
||||
case self::FIELD_REF_TYPE:
|
||||
return self::VALUE_REF_TYPE;
|
||||
case self::FIELD_REF_CHANGE:
|
||||
return self::VALUE_REF_CHANGE;
|
||||
}
|
||||
|
||||
return parent::getValueTypeForFieldAndCondition($field, $condition);
|
||||
}
|
||||
|
||||
public function getPHID() {
|
||||
return $this->getObject()->getPHID();
|
||||
}
|
||||
|
||||
public function getHeraldName() {
|
||||
return pht('Push Log');
|
||||
}
|
||||
|
||||
public function getHeraldField($field) {
|
||||
$log = $this->getObject();
|
||||
switch ($field) {
|
||||
case self::FIELD_REF_TYPE:
|
||||
return $log->getRefType();
|
||||
case self::FIELD_REF_NAME:
|
||||
return $log->getRefName();
|
||||
case self::FIELD_REF_CHANGE:
|
||||
return $log->getChangeFlags();
|
||||
case self::FIELD_REPOSITORY:
|
||||
return $this->hookEngine->getRepository()->getPHID();
|
||||
case self::FIELD_PUSHER:
|
||||
return $this->hookEngine->getViewer()->getPHID();
|
||||
case self::FIELD_PUSHER_PROJECTS:
|
||||
return $this->hookEngine->loadViewerProjectPHIDsForHerald();
|
||||
}
|
||||
|
||||
return parent::getHeraldField($field);
|
||||
}
|
||||
|
||||
|
||||
public function applyHeraldEffects(array $effects) {
|
||||
assert_instances_of($effects, 'HeraldEffect');
|
||||
|
||||
$result = array();
|
||||
foreach ($effects as $effect) {
|
||||
$action = $effect->getAction();
|
||||
switch ($action) {
|
||||
case self::ACTION_NOTHING:
|
||||
$result[] = new HeraldApplyTranscript(
|
||||
$effect,
|
||||
true,
|
||||
pht('Did nothing.'));
|
||||
break;
|
||||
case self::ACTION_BLOCK:
|
||||
$result[] = new HeraldApplyTranscript(
|
||||
$effect,
|
||||
true,
|
||||
pht('Blocked push.'));
|
||||
break;
|
||||
default:
|
||||
throw new Exception(pht('No rules to handle action "%s"!', $action));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
|
@ -25,6 +25,8 @@ abstract class HeraldAdapter {
|
|||
const FIELD_ALWAYS = 'always';
|
||||
const FIELD_AUTHOR_PROJECTS = 'authorprojects';
|
||||
const FIELD_PROJECTS = 'projects';
|
||||
const FIELD_PUSHER = 'pusher';
|
||||
const FIELD_PUSHER_PROJECTS = 'pusher-projects';
|
||||
|
||||
const CONDITION_CONTAINS = 'contains';
|
||||
const CONDITION_NOT_CONTAINS = '!contains';
|
||||
|
@ -44,6 +46,8 @@ abstract class HeraldAdapter {
|
|||
const CONDITION_NOT_EXISTS = '!exists';
|
||||
const CONDITION_UNCONDITIONALLY = 'unconditionally';
|
||||
const CONDITION_REGEXP_PAIR = 'regexp-pair';
|
||||
const CONDITION_HAS_BIT = 'bit';
|
||||
const CONDITION_NOT_BIT = '!bit';
|
||||
|
||||
const ACTION_ADD_CC = 'addcc';
|
||||
const ACTION_REMOVE_CC = 'remcc';
|
||||
|
@ -56,6 +60,7 @@ abstract class HeraldAdapter {
|
|||
const ACTION_ADD_REVIEWERS = 'addreviewers';
|
||||
const ACTION_ADD_BLOCKING_REVIEWERS = 'addblockingreviewers';
|
||||
const ACTION_APPLY_BUILD_PLANS = 'applybuildplans';
|
||||
const ACTION_BLOCK = 'block';
|
||||
|
||||
const VALUE_TEXT = 'text';
|
||||
const VALUE_NONE = 'none';
|
||||
|
@ -156,6 +161,8 @@ abstract class HeraldAdapter {
|
|||
self::FIELD_ALWAYS => pht('Always'),
|
||||
self::FIELD_AUTHOR_PROJECTS => pht("Author's projects"),
|
||||
self::FIELD_PROJECTS => pht("Projects"),
|
||||
self::FIELD_PUSHER => pht('Pusher'),
|
||||
self::FIELD_PUSHER_PROJECTS => pht("Pusher's projects"),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -183,6 +190,8 @@ abstract class HeraldAdapter {
|
|||
self::CONDITION_NOT_EXISTS => pht('does not exist'),
|
||||
self::CONDITION_UNCONDITIONALLY => '', // don't show anything!
|
||||
self::CONDITION_REGEXP_PAIR => pht('matches regexp pair'),
|
||||
self::CONDITION_HAS_BIT => pht('has bit'),
|
||||
self::CONDITION_NOT_BIT => pht('lacks bit'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -200,6 +209,7 @@ abstract class HeraldAdapter {
|
|||
case self::FIELD_AUTHOR:
|
||||
case self::FIELD_COMMITTER:
|
||||
case self::FIELD_REVIEWER:
|
||||
case self::FIELD_PUSHER:
|
||||
return array(
|
||||
self::CONDITION_IS_ANY,
|
||||
self::CONDITION_IS_NOT_ANY,
|
||||
|
@ -218,6 +228,7 @@ abstract class HeraldAdapter {
|
|||
case self::FIELD_PROJECTS:
|
||||
case self::FIELD_AFFECTED_PACKAGE:
|
||||
case self::FIELD_AFFECTED_PACKAGE_OWNER:
|
||||
case self::FIELD_PUSHER_PROJECTS:
|
||||
return array(
|
||||
self::CONDITION_INCLUDE_ALL,
|
||||
self::CONDITION_INCLUDE_ANY,
|
||||
|
@ -392,6 +403,10 @@ abstract class HeraldAdapter {
|
|||
$result = !$result;
|
||||
}
|
||||
return $result;
|
||||
case self::CONDITION_HAS_BIT:
|
||||
return (($condition_value & $field_value) === $condition_value);
|
||||
case self::CONDITION_NOT_BIT:
|
||||
return (($condition_value & $field_value) !== $condition_value);
|
||||
default:
|
||||
throw new HeraldInvalidConditionException(
|
||||
"Unknown condition '{$condition_type}'.");
|
||||
|
@ -469,6 +484,8 @@ abstract class HeraldAdapter {
|
|||
case self::CONDITION_EXISTS:
|
||||
case self::CONDITION_NOT_EXISTS:
|
||||
case self::CONDITION_UNCONDITIONALLY:
|
||||
case self::CONDITION_HAS_BIT:
|
||||
case self::CONDITION_NOT_BIT:
|
||||
// No explicit validation for these types, although there probably
|
||||
// should be in some cases.
|
||||
break;
|
||||
|
@ -500,6 +517,7 @@ abstract class HeraldAdapter {
|
|||
self::ACTION_ADD_REVIEWERS => pht('Add reviewers'),
|
||||
self::ACTION_ADD_BLOCKING_REVIEWERS => pht('Add blocking reviewers'),
|
||||
self::ACTION_APPLY_BUILD_PLANS => pht('Apply build plans'),
|
||||
self::ACTION_BLOCK => pht('Block change with message'),
|
||||
);
|
||||
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
|
||||
return array(
|
||||
|
@ -551,6 +569,7 @@ abstract class HeraldAdapter {
|
|||
$target = PhabricatorFlagColor::COLOR_BLUE;
|
||||
}
|
||||
break;
|
||||
case self::ACTION_BLOCK:
|
||||
case self::ACTION_NOTHING:
|
||||
break;
|
||||
default:
|
||||
|
@ -607,6 +626,7 @@ abstract class HeraldAdapter {
|
|||
case self::FIELD_AFFECTED_PACKAGE:
|
||||
return self::VALUE_OWNERS_PACKAGE;
|
||||
case self::FIELD_AUTHOR_PROJECTS:
|
||||
case self::FIELD_PUSHER_PROJECTS:
|
||||
case self::FIELD_PROJECTS:
|
||||
return self::VALUE_PROJECT;
|
||||
case self::FIELD_REVIEWERS:
|
||||
|
@ -670,6 +690,8 @@ abstract class HeraldAdapter {
|
|||
return self::VALUE_USER_OR_PROJECT;
|
||||
case self::ACTION_APPLY_BUILD_PLANS:
|
||||
return self::VALUE_BUILD_PLAN;
|
||||
case self::ACTION_BLOCK:
|
||||
return self::VALUE_TEXT;
|
||||
default:
|
||||
throw new Exception("Unknown or invalid action '{$action}'.");
|
||||
}
|
||||
|
|
|
@ -349,6 +349,7 @@ final class HeraldRuleController extends HeraldController {
|
|||
|
||||
switch ($action->getAction()) {
|
||||
case HeraldAdapter::ACTION_FLAG:
|
||||
case HeraldAdapter::ACTION_BLOCK:
|
||||
$current_value = $action->getTarget();
|
||||
break;
|
||||
default:
|
||||
|
@ -414,12 +415,42 @@ final class HeraldRuleController extends HeraldController {
|
|||
'root' => 'herald-rule-edit-form',
|
||||
'conditions' => (object)$serial_conditions,
|
||||
'actions' => (object)$serial_actions,
|
||||
'select' => array(
|
||||
HeraldAdapter::VALUE_CONTENT_SOURCE => array(
|
||||
'options' => PhabricatorContentSource::getSourceNameMap(),
|
||||
'default' => PhabricatorContentSource::SOURCE_WEB,
|
||||
),
|
||||
HeraldAdapter::VALUE_FLAG_COLOR => array(
|
||||
'options' => PhabricatorFlagColor::getColorNameMap(),
|
||||
'default' => PhabricatorFlagColor::COLOR_BLUE,
|
||||
),
|
||||
HeraldPreCommitRefAdapter::VALUE_REF_TYPE => array(
|
||||
'options' => array(
|
||||
PhabricatorRepositoryPushLog::REFTYPE_BRANCH
|
||||
=> pht('branch (git/hg)'),
|
||||
PhabricatorRepositoryPushLog::REFTYPE_TAG
|
||||
=> pht('tag (git)'),
|
||||
PhabricatorRepositoryPushLog::REFTYPE_BOOKMARK
|
||||
=> pht('bookmark (hg)'),
|
||||
),
|
||||
'default' => PhabricatorRepositoryPushLog::REFTYPE_BRANCH,
|
||||
),
|
||||
HeraldPreCommitRefAdapter::VALUE_REF_CHANGE => array(
|
||||
'options' => array(
|
||||
PhabricatorRepositoryPushLog::CHANGEFLAG_ADD =>
|
||||
pht('change creates ref'),
|
||||
PhabricatorRepositoryPushLog::CHANGEFLAG_DELETE =>
|
||||
pht('change deletes ref'),
|
||||
PhabricatorRepositoryPushLog::CHANGEFLAG_REWRITE =>
|
||||
pht('change rewrites ref'),
|
||||
PhabricatorRepositoryPushLog::CHANGEFLAG_DANGEROUS =>
|
||||
pht('dangerous change'),
|
||||
),
|
||||
'default' => PhabricatorRepositoryPushLog::CHANGEFLAG_ADD,
|
||||
),
|
||||
),
|
||||
'template' => $this->buildTokenizerTemplates() + array(
|
||||
'rules' => $all_rules,
|
||||
'colors' => PhabricatorFlagColor::getColorNameMap(),
|
||||
'defaultColor' => PhabricatorFlagColor::COLOR_BLUE,
|
||||
'contentSources' => PhabricatorContentSource::getSourceNameMap(),
|
||||
'defaultSource' => PhabricatorContentSource::SOURCE_WEB
|
||||
),
|
||||
'author' => array($rule->getAuthorPHID() =>
|
||||
$handles[$rule->getAuthorPHID()]->getName()),
|
||||
|
|
|
@ -293,6 +293,10 @@ final class HeraldTranscriptController extends HeraldController {
|
|||
case HeraldAdapter::ACTION_FLAG:
|
||||
$target = PhabricatorFlagColor::getColorName($target);
|
||||
break;
|
||||
case HeraldAdapter::ACTION_BLOCK:
|
||||
// Target is a text string.
|
||||
$target = $target;
|
||||
break;
|
||||
default:
|
||||
if ($target) {
|
||||
foreach ($target as $k => $phid) {
|
||||
|
|
|
@ -24,8 +24,8 @@ final class HeraldEngine {
|
|||
return idx($this->rules, $id);
|
||||
}
|
||||
|
||||
public static function loadAndApplyRules(HeraldAdapter $adapter) {
|
||||
$rules = id(new HeraldRuleQuery())
|
||||
public function loadRulesForAdapter(HeraldAdapter $adapter) {
|
||||
return id(new HeraldRuleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withDisabled(false)
|
||||
->withContentTypes(array($adapter->getAdapterContentType()))
|
||||
|
@ -33,8 +33,12 @@ final class HeraldEngine {
|
|||
->needAppliedToPHIDs(array($adapter->getPHID()))
|
||||
->needValidateAuthors(true)
|
||||
->execute();
|
||||
}
|
||||
|
||||
public static function loadAndApplyRules(HeraldAdapter $adapter) {
|
||||
$engine = new HeraldEngine();
|
||||
|
||||
$rules = $engine->loadRulesForAdapter($adapter);
|
||||
$effects = $engine->applyRules($rules, $adapter);
|
||||
$engine->applyEffects($effects, $adapter, $rules);
|
||||
|
||||
|
|
|
@ -16,9 +16,10 @@ final class HeraldRule extends HeraldDAO
|
|||
protected $ruleType;
|
||||
protected $isDisabled = 0;
|
||||
|
||||
protected $configVersion = 15;
|
||||
protected $configVersion = 16;
|
||||
|
||||
private $ruleApplied = self::ATTACHABLE; // phids for which this rule has been applied
|
||||
// phids for which this rule has been applied
|
||||
private $ruleApplied = self::ATTACHABLE;
|
||||
private $validAuthor = self::ATTACHABLE;
|
||||
private $author = self::ATTACHABLE;
|
||||
private $conditions;
|
||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorRepositoryPushLogQuery
|
|||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $repositoryPHIDs;
|
||||
private $pusherPHIDs;
|
||||
private $refTypes;
|
||||
|
@ -14,6 +15,11 @@ final class PhabricatorRepositoryPushLogQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withPHIDs(array $phids) {
|
||||
$this->phids = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withRepositoryPHIDs(array $repository_phids) {
|
||||
$this->repositoryPHIDs = $repository_phids;
|
||||
return $this;
|
||||
|
@ -84,6 +90,13 @@ final class PhabricatorRepositoryPushLogQuery
|
|||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->repositoryPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
|
|
|
@ -233,16 +233,13 @@ JX.install('HeraldRuleEditor', {
|
|||
set_fn = JX.bag;
|
||||
break;
|
||||
case 'contentsource':
|
||||
input = this._renderSelect(this._config.template.contentSources);
|
||||
get_fn = function() { return input.value; };
|
||||
set_fn = function(v) { input.value = v; };
|
||||
set_fn(this._config.template.defaultSource);
|
||||
break;
|
||||
case 'flagcolor':
|
||||
input = this._renderSelect(this._config.template.colors);
|
||||
case 'value-ref-type':
|
||||
case 'value-ref-change':
|
||||
input = this._renderSelect(this._config.select[type].options);
|
||||
get_fn = function() { return input.value; };
|
||||
set_fn = function(v) { input.value = v; };
|
||||
set_fn(this._config.template.defaultColor);
|
||||
set_fn(this._config.select[type]['default']);
|
||||
break;
|
||||
default:
|
||||
input = JX.$N('input', {type: 'text'});
|
||||
|
|
Loading…
Reference in a new issue