2013-03-15 12:28:43 +01:00
|
|
|
<?php
|
|
|
|
|
2013-03-22 14:29:37 +01:00
|
|
|
final class ReleephProject extends ReleephDAO
|
|
|
|
implements PhabricatorPolicyInterface {
|
2013-03-15 12:28:43 +01:00
|
|
|
|
|
|
|
const DEFAULT_BRANCH_NAMESPACE = 'releeph-releases';
|
|
|
|
const SYSTEM_AGENT_USERNAME_PREFIX = 'releeph-agent-';
|
|
|
|
|
|
|
|
protected $name;
|
|
|
|
|
|
|
|
// Specifying the place to pick from is a requirement for svn, though not
|
|
|
|
// for git. It's always useful though for reasoning about what revs have
|
|
|
|
// been picked and which haven't.
|
|
|
|
protected $trunkBranch;
|
|
|
|
|
|
|
|
protected $repositoryPHID;
|
|
|
|
protected $isActive;
|
|
|
|
protected $createdByUserPHID;
|
|
|
|
protected $arcanistProjectID;
|
|
|
|
|
|
|
|
protected $details = array();
|
|
|
|
|
2013-08-14 17:59:28 +02:00
|
|
|
private $repository = self::ATTACHABLE;
|
2014-04-14 21:07:32 +02:00
|
|
|
private $arcanistProject = self::ATTACHABLE;
|
2013-08-14 17:59:28 +02:00
|
|
|
|
2013-03-15 12:28:43 +01:00
|
|
|
public function getConfiguration() {
|
|
|
|
return array(
|
|
|
|
self::CONFIG_AUX_PHID => true,
|
|
|
|
self::CONFIG_SERIALIZATION => array(
|
|
|
|
'details' => self::SERIALIZATION_JSON,
|
|
|
|
),
|
|
|
|
) + parent::getConfiguration();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function generatePHID() {
|
2013-07-21 17:41:38 +02:00
|
|
|
return PhabricatorPHID::generateNewPHID(ReleephPHIDTypeProject::TYPECONST);
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getDetail($key, $default = null) {
|
|
|
|
return idx($this->details, $key, $default);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getURI($path = null) {
|
|
|
|
$components = array(
|
|
|
|
'/releeph/project',
|
|
|
|
$this->getID(),
|
|
|
|
$path
|
|
|
|
);
|
2013-05-22 16:42:30 +02:00
|
|
|
return implode('/', $components);
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function setDetail($key, $value) {
|
|
|
|
$this->details[$key] = $value;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2014-04-14 21:07:32 +02:00
|
|
|
public function getArcanistProject() {
|
|
|
|
return $this->assertAttached($this->arcanistProject);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function attachArcanistProject(
|
|
|
|
PhabricatorRepositoryArcanistProject $arcanist_project = null) {
|
|
|
|
$this->arcanistProject = $arcanist_project;
|
|
|
|
return $this;
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getPushers() {
|
|
|
|
return $this->getDetail('pushers', array());
|
|
|
|
}
|
|
|
|
|
2013-04-18 18:45:12 +02:00
|
|
|
public function isPusher(PhabricatorUser $user) {
|
|
|
|
// TODO Deprecate this once `isPusher` is out of the Facebook codebase.
|
|
|
|
return $this->isAuthoritative($user);
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
2013-04-18 18:45:12 +02:00
|
|
|
public function isAuthoritative(PhabricatorUser $user) {
|
|
|
|
return $this->isAuthoritativePHID($user->getPHID());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function isAuthoritativePHID($phid) {
|
|
|
|
$pushers = $this->getPushers();
|
|
|
|
if (!$pushers) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return in_array($phid, $pushers);
|
|
|
|
}
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
2013-08-14 17:59:28 +02:00
|
|
|
public function attachRepository(PhabricatorRepository $repository) {
|
|
|
|
$this->repository = $repository;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRepository() {
|
|
|
|
return $this->assertAttached($this->repository);
|
|
|
|
}
|
|
|
|
|
2013-09-26 01:54:48 +02:00
|
|
|
// TODO: Remove once everything uses ProjectQuery. Also, T603.
|
2013-03-15 12:28:43 +01:00
|
|
|
public function loadPhabricatorRepository() {
|
|
|
|
return $this->loadOneRelative(
|
|
|
|
new PhabricatorRepository(),
|
2013-08-14 17:59:28 +02:00
|
|
|
'phid',
|
|
|
|
'getRepositoryPHID');
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getReleephFieldSelector() {
|
2013-08-14 17:58:54 +02:00
|
|
|
return new ReleephDefaultFieldSelector();
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function isTestFile($filename) {
|
|
|
|
$test_paths = $this->getDetail('testPaths', array());
|
|
|
|
|
|
|
|
foreach ($test_paths as $test_path) {
|
|
|
|
if (preg_match($test_path, $filename)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-03-22 14:29:37 +01:00
|
|
|
|
|
|
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
|
|
|
|
|
|
|
public function getCapabilities() {
|
|
|
|
return array(
|
|
|
|
PhabricatorPolicyCapability::CAN_VIEW,
|
Move edit/deactivate operations onto project view page in Releeph
Summary:
Ref T3092.
Releeph's objects basically go like this:
- At the top level, we have Projects (like "www" or "libphutil")
- Each project has Branches (like "LATEST" or "v1.1.3")
- Each branch has Requests (like pull requests, e.g. "please merge commit X into branch Y (in project Z)")
Currently, there's no real "project detail" or "branch detail" page. Instead, we have a search results page for their contained objects. That is, the "project detail" page shows a list of branches in the project, using ApplicationSearch.
This means that operations like "edit" and "deactivate" are one level up, on the respective list pages.
Instead, move details onto the detail pages. This gives us more room for actions and information, and simplifies the list views.
Basically, these are "detail pages" where the object content is a search interface. We do something simliar to this in Phame right now, although it's messier there (no ApplicationSearch yet).
@chad, you might have some ideas here. Roughly, the design question is "How should we present an object's detail view when its content is really a search interface (Phame Blog for Posts, Releeph Project for Branches)?"
I think the simple approach I've taken here (see screenshot) gives us reasonable results, but overall it's something we haven't done much or done too much thinking about, I think.
Test Plan: {F54774}
Reviewers: btrahan
Reviewed By: btrahan
CC: chad, aran
Maniphest Tasks: T3092
Differential Revision: https://secure.phabricator.com/D6771
2013-08-20 03:30:30 +02:00
|
|
|
PhabricatorPolicyCapability::CAN_EDIT,
|
2013-03-22 14:29:37 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPolicy($capability) {
|
|
|
|
return PhabricatorPolicies::POLICY_USER;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-09-27 17:43:41 +02:00
|
|
|
public function describeAutomaticCapability($capability) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|