@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve lipsum generation of projects

Summary:
Fixes T9156.

- Fix hashtag generation.
- Fix various badnesses.
- Improve project name generator.

Test Plan:
```
$ ./bin/lipsum generate projects
GENERATORS Selected generators: Projects.
WARNING This command generates synthetic test data, including user accounts. It is intended for use in development environments so you can test features more easily. There is no easy way to delete this data or undo the effects of this command. If you run it in a production environment, it will pollute your data with large amounts of meaningless garbage that you can not get rid of.

Are you sure you want to generate piles of garbage? [y/N] y

LIPSUM Generating synthetic test objects forever. Use ^C to stop when satisfied.
Generated "Project": Self-Flying Data Center Swag Performance
Generated "Project": Optimize Cars
Generated "Project": Triaging Culture Optimization
Generated "Project": Automating Experience
Generated "Project": Accelerating NUX Performance
Generated "Project": Optimizing Culture Optimization
Generated "Project": Optimize Hardware
```

{F1042949}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9156

Differential Revision: https://secure.phabricator.com/D14874

+221 -59
+2
src/__phutil_library_map__.php
··· 2862 2862 'PhabricatorProjectMembersPolicyRule' => 'applications/project/policyrule/PhabricatorProjectMembersPolicyRule.php', 2863 2863 'PhabricatorProjectMembersRemoveController' => 'applications/project/controller/PhabricatorProjectMembersRemoveController.php', 2864 2864 'PhabricatorProjectMoveController' => 'applications/project/controller/PhabricatorProjectMoveController.php', 2865 + 'PhabricatorProjectNameContextFreeGrammar' => 'applications/project/lipsum/PhabricatorProjectNameContextFreeGrammar.php', 2865 2866 'PhabricatorProjectNoProjectsDatasource' => 'applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php', 2866 2867 'PhabricatorProjectObjectHasProjectEdgeType' => 'applications/project/edge/PhabricatorProjectObjectHasProjectEdgeType.php', 2867 2868 'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php', ··· 7199 7200 'PhabricatorProjectMembersPolicyRule' => 'PhabricatorPolicyRule', 7200 7201 'PhabricatorProjectMembersRemoveController' => 'PhabricatorProjectController', 7201 7202 'PhabricatorProjectMoveController' => 'PhabricatorProjectController', 7203 + 'PhabricatorProjectNameContextFreeGrammar' => 'PhutilContextFreeGrammar', 7202 7204 'PhabricatorProjectNoProjectsDatasource' => 'PhabricatorTypeaheadDatasource', 7203 7205 'PhabricatorProjectObjectHasProjectEdgeType' => 'PhabricatorEdgeType', 7204 7206 'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+1 -4
src/applications/differential/lipsum/PhabricatorDifferentialRevisionTestDataGenerator.php
··· 27 27 ->setTransactionType(DifferentialTransaction::TYPE_UPDATE) 28 28 ->setNewValue($diff->getPHID()); 29 29 30 - $content_source = PhabricatorContentSource::newForSource( 31 - PhabricatorContentSource::SOURCE_LIPSUM, 32 - array()); 33 30 34 31 id(new DifferentialTransactionEditor()) 35 32 ->setActor($author) 36 - ->setContentSource($content_source) 33 + ->setContentSource($this->getLipsumContentSource()) 37 34 ->applyTransactions($revision, $xactions); 38 35 39 36 return $revision;
+73
src/applications/lipsum/generator/PhabricatorTestDataGenerator.php
··· 2 2 3 3 abstract class PhabricatorTestDataGenerator extends Phobject { 4 4 5 + private $viewer; 6 + 5 7 abstract public function getGeneratorName(); 6 8 abstract public function generateObject(); 7 9 10 + final public function setViewer(PhabricatorUser $viewer) { 11 + $this->viewer = $viewer; 12 + return $this; 13 + } 14 + 15 + final public function getViewer() { 16 + return $this->viewer; 17 + } 18 + 19 + protected function loadRandomPHID($table) { 20 + $conn_r = $table->establishConnection('r'); 21 + 22 + $row = queryfx_one( 23 + $conn_r, 24 + 'SELECT phid FROM %T ORDER BY RAND() LIMIT 1', 25 + $table->getTableName()); 26 + 27 + if (!$row) { 28 + return null; 29 + } 30 + 31 + return $row['phid']; 32 + } 33 + 34 + protected function loadRandomUser() { 35 + $viewer = $this->getViewer(); 36 + 37 + $user_phid = $this->loadRandomPHID(new PhabricatorUser()); 38 + 39 + $user = null; 40 + if ($user_phid) { 41 + $user = id(new PhabricatorPeopleQuery()) 42 + ->setViewer($viewer) 43 + ->withPHIDs(array($user_phid)) 44 + ->executeOne(); 45 + } 46 + 47 + if (!$user) { 48 + throw new Exception( 49 + pht( 50 + 'Failed to load a random user. You may need to generate more '. 51 + 'test users first.')); 52 + } 53 + 54 + return $user; 55 + } 56 + 57 + protected function getLipsumContentSource() { 58 + return PhabricatorContentSource::newForSource( 59 + PhabricatorContentSource::SOURCE_LIPSUM, 60 + array()); 61 + } 62 + 63 + /** 64 + * Roll `n` dice with `d` sides each, then add `bonus` and return the sum. 65 + */ 66 + protected function roll($n, $d, $bonus = 0) { 67 + $sum = 0; 68 + for ($ii = 0; $ii < $n; $ii++) { 69 + $sum += mt_rand(1, $d); 70 + } 71 + 72 + $sum += $bonus; 73 + 74 + return $sum; 75 + } 76 + 77 + 78 + 79 + 8 80 public function loadOneRandom($classname) { 9 81 try { 10 82 return newv($classname, array()) ··· 25 97 public function loadPhabrictorUser() { 26 98 return $this->loadOneRandom('PhabricatorUser'); 27 99 } 100 + 28 101 29 102 }
+21 -1
src/applications/lipsum/management/PhabricatorLipsumGenerateWorkflow.php
··· 120 120 protected function generate(array $generators) { 121 121 $viewer = $this->getViewer(); 122 122 123 + foreach ($generators as $generator) { 124 + $generator->setViewer($this->getViewer()); 125 + } 126 + 123 127 while (true) { 124 128 $generator = $generators[array_rand($generators)]; 125 129 126 - $object = $generator->generateObject(); 130 + try { 131 + $object = $generator->generateObject(); 132 + } catch (Exception $ex) { 133 + echo tsprintf( 134 + "**<bg:yellow> %s </bg>** %s\n", 135 + pht('OOPS'), 136 + pht( 137 + 'Generator ("%s") was unable to generate an object.', 138 + $generator->getGeneratorName())); 139 + 140 + echo tsprintf( 141 + "%B\n", 142 + $ex->getMessage()); 143 + 144 + continue; 145 + } 146 + 127 147 $object_phid = $object->getPHID(); 128 148 129 149 $handles = $viewer->loadHandles(array($object_phid));
+4 -6
src/applications/metamta/receiver/__tests__/PhabricatorObjectMailReceiverTestCase.php
··· 76 76 } 77 77 78 78 private function buildMail($style) { 79 - 80 - // TODO: Clean up test data generators so that we don't need to guarantee 81 - // the existence of a user. 82 - $this->generateNewTestUser(); 83 - 84 - $task = id(new PhabricatorManiphestTaskTestDataGenerator())->generate(); 85 79 $user = $this->generateNewTestUser(); 80 + 81 + $task = id(new PhabricatorManiphestTaskTestDataGenerator()) 82 + ->setViewer($user) 83 + ->generateObject(); 86 84 87 85 $is_public = ($style === 'public'); 88 86 $is_bad_hash = ($style == 'badhash');
+75
src/applications/project/lipsum/PhabricatorProjectNameContextFreeGrammar.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectNameContextFreeGrammar 4 + extends PhutilContextFreeGrammar { 5 + 6 + protected function getRules() { 7 + return array( 8 + 'start' => array( 9 + '[project]', 10 + '[project] [tion]', 11 + '[action] [project]', 12 + '[action] [project] [tion]', 13 + ), 14 + 'project' => array( 15 + 'Backend', 16 + 'Frontend', 17 + 'Web', 18 + 'Mobile', 19 + 'Tablet', 20 + 'Robot', 21 + 'NUX', 22 + 'Cars', 23 + 'Drones', 24 + 'Experience', 25 + 'Swag', 26 + 'Security', 27 + 'Culture', 28 + 'Revenue', 29 + 'Ion Cannon', 30 + 'Graphics Engine', 31 + 'Drivers', 32 + 'Audio Drivers', 33 + 'Graphics Drivers', 34 + 'Hardware', 35 + 'Data Center', 36 + '[project] [project]', 37 + '[adjective] [project]', 38 + '[adjective] [project]', 39 + ), 40 + 'adjective' => array( 41 + 'Self-Driving', 42 + 'Self-Flying', 43 + 'Self-Immolating', 44 + 'Secure', 45 + 'Insecure', 46 + 'Somewhat-Secure', 47 + 'Orbital', 48 + 'Next-Generation', 49 + ), 50 + 'tion' => array( 51 + 'Automation', 52 + 'Optimization', 53 + 'Performance', 54 + 'Improvement', 55 + 'Growth', 56 + 'Monetization', 57 + ), 58 + 'action' => array( 59 + 'Monetize', 60 + 'Monetize', 61 + 'Triage', 62 + 'Triaging', 63 + 'Automate', 64 + 'Automating', 65 + 'Improve', 66 + 'Improving', 67 + 'Optimize', 68 + 'Optimizing', 69 + 'Accelerate', 70 + 'Accelerating', 71 + ), 72 + ); 73 + } 74 + 75 + }
+45 -48
src/applications/project/lipsum/PhabricatorProjectTestDataGenerator.php
··· 3 3 final class PhabricatorProjectTestDataGenerator 4 4 extends PhabricatorTestDataGenerator { 5 5 6 - private $xactions = array(); 7 - 8 6 public function getGeneratorName() { 9 7 return pht('Projects'); 10 8 } 11 9 12 10 public function generateObject() { 13 - $title = $this->generateTitle(); 14 - $author = $this->loadPhabrictorUser(); 15 - $author_phid = $author->getPHID(); 16 - $project = PhabricatorProject::initializeNewProject($author) 17 - ->setName($title); 11 + $author = $this->loadRandomUser(); 12 + $project = PhabricatorProject::initializeNewProject($author); 18 13 19 - $this->addTransaction( 14 + $xactions = array(); 15 + 16 + $xactions[] = $this->newTransaction( 20 17 PhabricatorProjectTransaction::TYPE_NAME, 21 - $title); 22 - $project->attachMemberPHIDs( 23 - $this->loadMembersWithAuthor($author_phid)); 24 - $this->addTransaction( 18 + $this->newProjectTitle()); 19 + 20 + $xactions[] = $this->newTransaction( 25 21 PhabricatorProjectTransaction::TYPE_STATUS, 26 - $this->generateProjectStatus()); 27 - $this->addTransaction( 28 - PhabricatorTransactions::TYPE_VIEW_POLICY, 29 - PhabricatorPolicies::POLICY_PUBLIC); 30 - $this->addTransaction( 31 - PhabricatorTransactions::TYPE_EDIT_POLICY, 32 - PhabricatorPolicies::POLICY_PUBLIC); 33 - $this->addTransaction( 34 - PhabricatorTransactions::TYPE_JOIN_POLICY, 35 - PhabricatorPolicies::POLICY_PUBLIC); 22 + $this->newProjectStatus()); 23 + 24 + // Almost always make the author a member. 25 + $members = array(); 26 + if ($this->roll(1, 20) > 2) { 27 + $members[] = $author->getPHID(); 28 + } 29 + 30 + // Add a few other members. 31 + $size = $this->roll(2, 6, -2); 32 + for ($ii = 0; $ii < $size; $ii++) { 33 + $members[] = $this->loadRandomUser()->getPHID(); 34 + } 35 + 36 + $xactions[] = $this->newTransaction( 37 + PhabricatorTransactions::TYPE_EDGE, 38 + array( 39 + '+' => array_fuse($members), 40 + ), 41 + array( 42 + 'edge:type' => PhabricatorProjectProjectHasMemberEdgeType::EDGECONST, 43 + )); 36 44 37 45 $editor = id(new PhabricatorProjectTransactionEditor()) 38 46 ->setActor($author) 39 - ->setContentSource(PhabricatorContentSource::newConsoleSource()) 47 + ->setContentSource($this->getLipsumContentSource()) 40 48 ->setContinueOnNoEffect(true) 41 - ->applyTransactions($project, $this->xactions); 49 + ->applyTransactions($project, $xactions); 42 50 43 - return $project->save(); 51 + return $project; 44 52 } 45 53 46 - private function addTransaction($type, $value) { 47 - $this->xactions[] = id(new PhabricatorProjectTransaction()) 54 + private function newTransaction($type, $value, $metadata = array()) { 55 + $xaction = id(new PhabricatorProjectTransaction()) 48 56 ->setTransactionType($type) 49 57 ->setNewValue($value); 50 - } 51 58 52 - 53 - public function loadMembersWithAuthor($author) { 54 - $members = array($author); 55 - for ($i = 0; $i < rand(10, 20);$i++) { 56 - $members[] = $this->loadPhabrictorUserPHID(); 59 + foreach ($metadata as $key => $value) { 60 + $xaction->setMetadataValue($key, $value); 57 61 } 58 - return $members; 62 + 63 + return $xaction; 59 64 } 60 65 61 - public function generateTitle() { 62 - return id(new PhutilLipsumContextFreeGrammar()) 66 + public function newProjectTitle() { 67 + return id(new PhabricatorProjectNameContextFreeGrammar()) 63 68 ->generate(); 64 69 } 65 70 66 - public function generateDescription() { 67 - return id(new PhutilLipsumContextFreeGrammar()) 68 - ->generateSeveral(rand(30, 40)); 69 - } 70 - 71 - public function generateProjectStatus() { 72 - $statuses = array_keys(PhabricatorProjectStatus::getStatusMap()); 73 - // Make sure 4/5th of all generated Projects are active 74 - $random = rand(0, 4); 75 - if ($random != 0) { 76 - return $statuses[0]; 71 + public function newProjectStatus() { 72 + if ($this->roll(1, 20) > 5) { 73 + return PhabricatorProjectStatus::STATUS_ACTIVE; 77 74 } else { 78 - return $statuses[1]; 75 + return PhabricatorProjectStatus::STATUS_ARCHIVED; 79 76 } 80 77 } 81 78 }