Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/differential/engine/DifferentialAffectedPathEngine.php
12256 views
1
<?php
2
3
final class DifferentialAffectedPathEngine
4
extends Phobject {
5
6
private $revision;
7
private $diff;
8
9
public function setRevision(DifferentialRevision $revision) {
10
$this->revision = $revision;
11
return $this;
12
}
13
14
public function getRevision() {
15
return $this->revision;
16
}
17
18
public function setDiff(DifferentialDiff $diff) {
19
$this->diff = $diff;
20
return $this;
21
}
22
23
public function getDiff() {
24
return $this->diff;
25
}
26
27
public function updateAffectedPaths() {
28
$revision = $this->getRevision();
29
$diff = $this->getDiff();
30
$repository = $revision->getRepository();
31
32
if ($repository) {
33
$repository_id = $repository->getID();
34
} else {
35
$repository_id = null;
36
}
37
38
$paths = $this->getAffectedPaths();
39
40
$path_ids =
41
PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(
42
$paths);
43
44
$table = new DifferentialAffectedPath();
45
$conn = $table->establishConnection('w');
46
47
$sql = array();
48
foreach ($path_ids as $path_id) {
49
$sql[] = qsprintf(
50
$conn,
51
'(%nd, %d, %d)',
52
$repository_id,
53
$path_id,
54
$revision->getID());
55
}
56
57
queryfx(
58
$conn,
59
'DELETE FROM %R WHERE revisionID = %d',
60
$table,
61
$revision->getID());
62
if ($sql) {
63
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
64
queryfx(
65
$conn,
66
'INSERT INTO %R (repositoryID, pathID, revisionID) VALUES %LQ',
67
$table,
68
$chunk);
69
}
70
}
71
}
72
73
public function destroyAffectedPaths() {
74
$revision = $this->getRevision();
75
76
$table = new DifferentialAffectedPath();
77
$conn = $table->establishConnection('w');
78
79
queryfx(
80
$conn,
81
'DELETE FROM %R WHERE revisionID = %d',
82
$table,
83
$revision->getID());
84
}
85
86
public function getAffectedPaths() {
87
$revision = $this->getRevision();
88
$diff = $this->getDiff();
89
$repository = $revision->getRepository();
90
91
$path_prefix = null;
92
if ($repository) {
93
$local_root = $diff->getSourceControlPath();
94
if ($local_root) {
95
// We're in a working copy which supports subdirectory checkouts (e.g.,
96
// SVN) so we need to figure out what prefix we should add to each path
97
// (e.g., trunk/projects/example/) to get the absolute path from the
98
// root of the repository. DVCS systems like Git and Mercurial are not
99
// affected.
100
101
// Normalize both paths and check if the repository root is a prefix of
102
// the local root. If so, throw it away. Note that this correctly
103
// handles the case where the remote path is "/".
104
$local_root = id(new PhutilURI($local_root))->getPath();
105
$local_root = rtrim($local_root, '/');
106
107
$repo_root = id(new PhutilURI($repository->getRemoteURI()))->getPath();
108
$repo_root = rtrim($repo_root, '/');
109
110
if (!strncmp($repo_root, $local_root, strlen($repo_root))) {
111
$path_prefix = substr($local_root, strlen($repo_root));
112
}
113
}
114
}
115
116
$changesets = $diff->getChangesets();
117
118
$paths = array();
119
foreach ($changesets as $changeset) {
120
$paths[] = $path_prefix.'/'.$changeset->getFilename();
121
}
122
123
// Mark this as also touching all parent paths, so you can see all pending
124
// changes to any file within a directory.
125
$all_paths = array();
126
foreach ($paths as $local) {
127
foreach (DiffusionPathIDQuery::expandPathToRoot($local) as $path) {
128
$all_paths[$path] = true;
129
}
130
}
131
$all_paths = array_keys($all_paths);
132
133
return $all_paths;
134
}
135
136
}
137
138