@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
at recaptime-dev/main 166 lines 4.5 kB view raw
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}