Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php
12242 views
1
<?php
2
3
final class DiffusionLastModifiedQueryConduitAPIMethod
4
extends DiffusionQueryConduitAPIMethod {
5
6
public function getAPIMethodName() {
7
return 'diffusion.lastmodifiedquery';
8
}
9
10
public function getMethodDescription() {
11
return pht('Get the commits at which paths were last modified.');
12
}
13
14
protected function defineReturnType() {
15
return 'map<string, string>';
16
}
17
18
protected function defineCustomParamTypes() {
19
return array(
20
'paths' => 'required map<string, string>',
21
);
22
}
23
24
protected function getGitResult(ConduitAPIRequest $request) {
25
$drequest = $this->getDiffusionRequest();
26
$repository = $drequest->getRepository();
27
28
$paths = $request->getValue('paths');
29
$results = $this->loadCommitsFromCache($paths);
30
31
foreach ($paths as $path => $commit) {
32
if (array_key_exists($path, $results)) {
33
continue;
34
}
35
list($hash) = $repository->execxLocalCommand(
36
'log -n1 %s %s -- %s',
37
'--format=%H',
38
gitsprintf('%s', $commit),
39
$path);
40
$results[$path] = trim($hash);
41
}
42
43
return $results;
44
}
45
46
protected function getSVNResult(ConduitAPIRequest $request) {
47
$drequest = $this->getDiffusionRequest();
48
$repository = $drequest->getRepository();
49
50
$results = array();
51
foreach ($request->getValue('paths') as $path => $commit) {
52
$history_result = DiffusionQuery::callConduitWithDiffusionRequest(
53
$request->getUser(),
54
$drequest,
55
'diffusion.historyquery',
56
array(
57
'commit' => $commit,
58
'path' => $path,
59
'limit' => 1,
60
'offset' => 0,
61
'needDirectChanges' => true,
62
'needChildChanges' => true,
63
));
64
65
$history_array = DiffusionPathChange::newFromConduit(
66
$history_result['pathChanges']);
67
if ($history_array) {
68
$results[$path] = head($history_array)
69
->getCommit()
70
->getCommitIdentifier();
71
}
72
}
73
74
return $results;
75
}
76
77
protected function getMercurialResult(ConduitAPIRequest $request) {
78
$drequest = $this->getDiffusionRequest();
79
$repository = $drequest->getRepository();
80
81
$paths = $request->getValue('paths');
82
$results = $this->loadCommitsFromCache($paths);
83
84
foreach ($paths as $path => $commit) {
85
if (array_key_exists($path, $results)) {
86
continue;
87
}
88
89
list($hash) = $repository->execxLocalCommand(
90
'log --template %s --limit 1 --removed --rev %s -- %s',
91
'{node}',
92
hgsprintf('reverse(ancestors(%s))', $commit),
93
nonempty(ltrim($path, '/'), '.'));
94
$results[$path] = trim($hash);
95
}
96
97
return $results;
98
}
99
100
private function loadCommitsFromCache(array $map) {
101
$drequest = $this->getDiffusionRequest();
102
$repository = $drequest->getRepository();
103
104
$path_map = id(new DiffusionPathIDQuery(array_keys($map)))
105
->loadPathIDs();
106
107
$commit_query = id(new DiffusionCommitQuery())
108
->setViewer($drequest->getUser())
109
->withRepository($repository)
110
->withIdentifiers(array_values($map));
111
$commit_query->execute();
112
113
$commit_map = $commit_query->getIdentifierMap();
114
$commit_map = mpull($commit_map, 'getID');
115
116
$graph_cache = new PhabricatorRepositoryGraphCache();
117
118
$results = array();
119
120
// Spend no more than this many total seconds trying to satisfy queries
121
// via the graph cache.
122
$remaining_time = 10.0;
123
foreach ($map as $path => $commit) {
124
$path_id = idx($path_map, $path);
125
if (!$path_id) {
126
continue;
127
}
128
$commit_id = idx($commit_map, $commit);
129
if (!$commit_id) {
130
continue;
131
}
132
133
$t_start = microtime(true);
134
$cache_result = $graph_cache->loadLastModifiedCommitID(
135
$commit_id,
136
$path_id,
137
$remaining_time);
138
$t_end = microtime(true);
139
140
if ($cache_result !== false) {
141
$results[$path] = $cache_result;
142
}
143
144
$remaining_time -= ($t_end - $t_start);
145
if ($remaining_time <= 0) {
146
break;
147
}
148
}
149
150
if ($results) {
151
$commits = id(new DiffusionCommitQuery())
152
->setViewer($drequest->getUser())
153
->withRepository($repository)
154
->withIDs($results)
155
->execute();
156
foreach ($results as $path => $id) {
157
$commit = idx($commits, $id);
158
if ($commit) {
159
$results[$path] = $commit->getCommitIdentifier();
160
} else {
161
unset($results[$path]);
162
}
163
}
164
}
165
166
return $results;
167
}
168
169
}
170
171