Skip to content

Commit 2cfc3ac

Browse files
author
epriestley
committed
Allow Herald pre-commit rules to act on repository projects
Summary: Fixes T4264. Adds: - New "Repository's projects" field to Herald pre-commit rules, so you can write global rules which act based on projects. - Allows pre-ref/pre-content rules to bind to projects, and fire for all repositories in that project, so users with limited power can write rules which apply to many repositories. - The pre-ref and pre-content classes were starting to share a fair amount of code, so I made them both extend an abstract base class. Test Plan: Wrote new pre-ref and pre-content rules bound to projects, then pushed commits into repositories in those projects and not in those projects. The "repository projects" field populated, and the rules fired for repositories in the relevant projects. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4264 Differential Revision: https://secure.phabricator.com/D7883
1 parent ee26807 commit 2cfc3ac

File tree

8 files changed

+158
-239
lines changed

8 files changed

+158
-239
lines changed

scripts/repository/commit_hook.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
$repository = id(new PhabricatorRepositoryQuery())
1414
->setViewer(PhabricatorUser::getOmnipotentUser())
1515
->withCallsigns(array($argv[1]))
16+
->needProjectPHIDs(true)
1617
->executeOne();
1718

1819
if (!$repository) {

src/__phutil_library_map__.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@
778778
'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php',
779779
'HeraldPHIDTypeRule' => 'applications/herald/phid/HeraldPHIDTypeRule.php',
780780
'HeraldPholioMockAdapter' => 'applications/herald/adapter/HeraldPholioMockAdapter.php',
781+
'HeraldPreCommitAdapter' => 'applications/diffusion/herald/HeraldPreCommitAdapter.php',
781782
'HeraldPreCommitContentAdapter' => 'applications/diffusion/herald/HeraldPreCommitContentAdapter.php',
782783
'HeraldPreCommitRefAdapter' => 'applications/diffusion/herald/HeraldPreCommitRefAdapter.php',
783784
'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php',
@@ -3251,8 +3252,9 @@
32513252
'HeraldNewController' => 'HeraldController',
32523253
'HeraldPHIDTypeRule' => 'PhabricatorPHIDType',
32533254
'HeraldPholioMockAdapter' => 'HeraldAdapter',
3254-
'HeraldPreCommitContentAdapter' => 'HeraldAdapter',
3255-
'HeraldPreCommitRefAdapter' => 'HeraldAdapter',
3255+
'HeraldPreCommitAdapter' => 'HeraldAdapter',
3256+
'HeraldPreCommitContentAdapter' => 'HeraldPreCommitAdapter',
3257+
'HeraldPreCommitRefAdapter' => 'HeraldPreCommitAdapter',
32563258
'HeraldRecursiveConditionsException' => 'Exception',
32573259
'HeraldRemarkupRule' => 'PhabricatorRemarkupRuleObject',
32583260
'HeraldRule' =>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
abstract class HeraldPreCommitAdapter extends HeraldAdapter {
4+
5+
private $log;
6+
private $hookEngine;
7+
8+
public function setPushLog(PhabricatorRepositoryPushLog $log) {
9+
$this->log = $log;
10+
return $this;
11+
}
12+
13+
public function setHookEngine(DiffusionCommitHookEngine $engine) {
14+
$this->hookEngine = $engine;
15+
return $this;
16+
}
17+
18+
public function getHookEngine() {
19+
return $this->hookEngine;
20+
}
21+
22+
public function getAdapterApplicationClass() {
23+
return 'PhabricatorApplicationDiffusion';
24+
}
25+
26+
public function getObject() {
27+
return $this->log;
28+
}
29+
30+
public function supportsRuleType($rule_type) {
31+
switch ($rule_type) {
32+
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
33+
case HeraldRuleTypeConfig::RULE_TYPE_OBJECT:
34+
return true;
35+
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
36+
default:
37+
return false;
38+
}
39+
}
40+
41+
public function canTriggerOnObject($object) {
42+
if ($object instanceof PhabricatorRepository) {
43+
return true;
44+
}
45+
46+
if ($object instanceof PhabricatorProject) {
47+
return true;
48+
}
49+
50+
return false;
51+
}
52+
53+
public function explainValidTriggerObjects() {
54+
return pht(
55+
'This rule can trigger for **repositories** or **projects**.');
56+
}
57+
58+
public function getTriggerObjectPHIDs() {
59+
return array_merge(
60+
array(
61+
$this->hookEngine->getRepository()->getPHID(),
62+
$this->getPHID(),
63+
),
64+
$this->hookEngine->getRepository()->getProjectPHIDs());
65+
}
66+
67+
public function getActions($rule_type) {
68+
switch ($rule_type) {
69+
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
70+
case HeraldRuleTypeConfig::RULE_TYPE_OBJECT:
71+
return array(
72+
self::ACTION_BLOCK,
73+
self::ACTION_NOTHING
74+
);
75+
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
76+
return array(
77+
self::ACTION_NOTHING,
78+
);
79+
}
80+
}
81+
82+
public function getPHID() {
83+
return $this->getObject()->getPHID();
84+
}
85+
86+
public function applyHeraldEffects(array $effects) {
87+
assert_instances_of($effects, 'HeraldEffect');
88+
89+
$result = array();
90+
foreach ($effects as $effect) {
91+
$action = $effect->getAction();
92+
switch ($action) {
93+
case self::ACTION_NOTHING:
94+
$result[] = new HeraldApplyTranscript(
95+
$effect,
96+
true,
97+
pht('Did nothing.'));
98+
break;
99+
case self::ACTION_BLOCK:
100+
$result[] = new HeraldApplyTranscript(
101+
$effect,
102+
true,
103+
pht('Blocked push.'));
104+
break;
105+
default:
106+
throw new Exception(pht('No rules to handle action "%s"!', $action));
107+
}
108+
}
109+
110+
return $result;
111+
}
112+
113+
}

0 commit comments

Comments
 (0)