@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class DiffusionBrowseResultSet extends Phobject {
4
5 const REASON_IS_FILE = 'is-file';
6 const REASON_IS_SUBMODULE = 'is-submodule';
7 const REASON_IS_DELETED = 'is-deleted';
8 const REASON_IS_NONEXISTENT = 'nonexistent';
9 const REASON_BAD_COMMIT = 'bad-commit';
10 const REASON_IS_EMPTY = 'empty';
11 const REASON_IS_UNTRACKED_PARENT = 'untracked-parent';
12
13 private $paths;
14 private $isValidResults;
15 private $reasonForEmptyResultSet;
16 private $existedAtCommit;
17 private $deletedAtCommit;
18
19 /**
20 * @param array<DiffusionRepositoryPath> $paths
21 */
22 public function setPaths(array $paths) {
23 assert_instances_of($paths, DiffusionRepositoryPath::class);
24 $this->paths = $paths;
25 return $this;
26 }
27 public function getPaths() {
28 return $this->paths;
29 }
30
31 public function setIsValidResults($is_valid) {
32 $this->isValidResults = $is_valid;
33 return $this;
34 }
35 public function isValidResults() {
36 return $this->isValidResults;
37 }
38
39 public function setReasonForEmptyResultSet($reason) {
40 $this->reasonForEmptyResultSet = $reason;
41 return $this;
42 }
43 public function getReasonForEmptyResultSet() {
44 return $this->reasonForEmptyResultSet;
45 }
46
47 public function setExistedAtCommit($existed_at_commit) {
48 $this->existedAtCommit = $existed_at_commit;
49 return $this;
50 }
51 public function getExistedAtCommit() {
52 return $this->existedAtCommit;
53 }
54
55 public function setDeletedAtCommit($deleted_at_commit) {
56 $this->deletedAtCommit = $deleted_at_commit;
57 return $this;
58 }
59 public function getDeletedAtCommit() {
60 return $this->deletedAtCommit;
61 }
62
63 public function toDictionary() {
64 $paths = $this->getPathDicts();
65
66 return array(
67 'paths' => $paths,
68 'isValidResults' => $this->isValidResults(),
69 'reasonForEmptyResultSet' => $this->getReasonForEmptyResultSet(),
70 'existedAtCommit' => $this->getExistedAtCommit(),
71 'deletedAtCommit' => $this->getDeletedAtCommit(),
72 );
73 }
74
75 public function getPathDicts() {
76 $paths = $this->getPaths();
77 if ($paths) {
78 return mpull($paths, 'toDictionary');
79 }
80 return array();
81 }
82
83 /**
84 * Get the best README file in this result set, if one exists.
85 *
86 * Callers should normally use `diffusion.filecontentquery` to pull README
87 * content.
88 *
89 * @return string|null Full path to best README, or null if one does not
90 * exist.
91 */
92 public function getReadmePath() {
93 $allowed_types = array(
94 ArcanistDiffChangeType::FILE_NORMAL => true,
95 ArcanistDiffChangeType::FILE_TEXT => true,
96 );
97
98 $candidates = array();
99 foreach ($this->getPaths() as $path_object) {
100 if (empty($allowed_types[$path_object->getFileType()])) {
101 // Skip directories, images, etc.
102 continue;
103 }
104
105 $local_path = $path_object->getPath();
106 if (!preg_match('/^readme(\.|$)/i', $local_path)) {
107 // Skip files not named "README".
108 continue;
109 }
110
111 $full_path = $path_object->getFullPath();
112 $candidates[$full_path] = self::getReadmePriority($local_path);
113 }
114
115 if (!$candidates) {
116 return null;
117 }
118
119 arsort($candidates);
120 return head_key($candidates);
121 }
122
123 /**
124 * Get the priority of a README file.
125 *
126 * When a directory contains several README files, this function scores them
127 * so the caller can select a preferred file. See @{method:getReadmePath}.
128 *
129 * @param string $path Local README path, like "README.txt".
130 * @return int Priority score, with higher being more preferred.
131 */
132 public static function getReadmePriority($path) {
133 $path = phutil_utf8_strtolower($path);
134 if ($path == 'readme') {
135 return 90;
136 }
137
138 $ext = last(explode('.', $path));
139 switch ($ext) {
140 case 'remarkup':
141 return 100;
142 case 'rainbow':
143 return 80;
144 case 'md':
145 return 70;
146 case 'txt':
147 return 60;
148 default:
149 return 50;
150 }
151 }
152
153 public static function newFromConduit(array $data) {
154 $paths = array();
155 $path_dicts = $data['paths'];
156 foreach ($path_dicts as $dict) {
157 $paths[] = DiffusionRepositoryPath::newFromDictionary($dict);
158 }
159 return id(new DiffusionBrowseResultSet())
160 ->setPaths($paths)
161 ->setIsValidResults($data['isValidResults'])
162 ->setReasonForEmptyResultSet($data['reasonForEmptyResultSet'])
163 ->setExistedAtCommit($data['existedAtCommit'])
164 ->setDeletedAtCommit($data['deletedAtCommit']);
165 }
166}