2011-04-03 23:48:36 +02:00
|
|
|
<?php
|
|
|
|
|
2012-03-10 00:46:25 +01:00
|
|
|
final class PhabricatorOwnersDetailController
|
|
|
|
extends PhabricatorOwnersController {
|
2011-04-03 23:48:36 +02:00
|
|
|
|
2015-05-27 19:29:01 +02:00
|
|
|
public function shouldAllowPublic() {
|
|
|
|
return true;
|
2011-04-04 04:20:47 +02:00
|
|
|
}
|
|
|
|
|
2015-05-27 19:29:01 +02:00
|
|
|
public function handleRequest(AphrontRequest $request) {
|
|
|
|
$viewer = $this->getViewer();
|
2011-04-04 04:20:47 +02:00
|
|
|
|
2015-05-27 19:29:01 +02:00
|
|
|
$package = id(new PhabricatorOwnersPackageQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withIDs(array($request->getURIData('id')))
|
|
|
|
->executeOne();
|
2011-04-04 07:03:27 +02:00
|
|
|
if (!$package) {
|
|
|
|
return new Aphront404Response();
|
2011-04-04 04:20:47 +02:00
|
|
|
}
|
|
|
|
|
2011-04-04 07:03:27 +02:00
|
|
|
$paths = $package->loadPaths();
|
2011-04-04 04:20:47 +02:00
|
|
|
|
2012-05-20 20:30:01 +02:00
|
|
|
$repository_phids = array();
|
2011-04-04 07:03:27 +02:00
|
|
|
foreach ($paths as $path) {
|
2012-05-20 20:30:01 +02:00
|
|
|
$repository_phids[$path->getRepositoryPHID()] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($repository_phids) {
|
2013-09-26 01:54:48 +02:00
|
|
|
$repositories = id(new PhabricatorRepositoryQuery())
|
2015-05-27 19:29:01 +02:00
|
|
|
->setViewer($viewer)
|
2013-09-26 01:54:48 +02:00
|
|
|
->withPHIDs(array_keys($repository_phids))
|
|
|
|
->execute();
|
2012-05-20 20:30:01 +02:00
|
|
|
$repositories = mpull($repositories, null, 'getPHID');
|
|
|
|
} else {
|
|
|
|
$repositories = array();
|
2011-04-04 07:03:27 +02:00
|
|
|
}
|
2012-05-20 20:30:01 +02:00
|
|
|
|
2015-05-27 19:29:31 +02:00
|
|
|
$actions = $this->buildPackageActionView($package);
|
|
|
|
$properties = $this->buildPackagePropertyView($package);
|
|
|
|
$properties->setActionList($actions);
|
2011-04-04 04:20:47 +02:00
|
|
|
|
2015-05-27 19:29:31 +02:00
|
|
|
$header = id(new PHUIHeaderView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setHeader($package->getName())
|
|
|
|
->setPolicyObject($package);
|
2015-03-03 22:51:28 +01:00
|
|
|
|
2015-05-27 19:29:31 +02:00
|
|
|
$panel = id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
|
|
|
->addPropertyList($properties);
|
2011-04-04 07:03:27 +02:00
|
|
|
|
2012-03-05 18:57:46 +01:00
|
|
|
$commit_views = array();
|
|
|
|
|
2014-11-08 01:45:59 +01:00
|
|
|
$commit_uri = id(new PhutilURI('/audit/'))
|
2012-03-05 18:57:46 +01:00
|
|
|
->setQueryParams(
|
|
|
|
array(
|
2014-11-08 01:45:59 +01:00
|
|
|
'auditorPHIDs' => $package->getPHID(),
|
2012-03-05 18:57:46 +01:00
|
|
|
));
|
|
|
|
|
2014-04-27 18:43:05 +02:00
|
|
|
$attention_commits = id(new DiffusionCommitQuery())
|
|
|
|
->setViewer($request->getUser())
|
|
|
|
->withAuditorPHIDs(array($package->getPHID()))
|
|
|
|
->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_CONCERN)
|
2012-03-05 18:57:46 +01:00
|
|
|
->needCommitData(true)
|
2014-04-27 18:43:05 +02:00
|
|
|
->setLimit(10)
|
|
|
|
->execute();
|
2012-03-05 18:57:46 +01:00
|
|
|
if ($attention_commits) {
|
2014-04-27 18:43:05 +02:00
|
|
|
$view = id(new PhabricatorAuditListView())
|
2015-05-27 19:29:01 +02:00
|
|
|
->setUser($viewer)
|
2014-04-27 18:43:05 +02:00
|
|
|
->setCommits($attention_commits);
|
2012-03-05 18:57:46 +01:00
|
|
|
|
|
|
|
$commit_views[] = array(
|
|
|
|
'view' => $view,
|
2013-05-22 00:31:24 +02:00
|
|
|
'header' => pht('Commits in this Package that Need Attention'),
|
2015-03-18 15:08:50 +01:00
|
|
|
'button' => id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setHref($commit_uri->alter('status', 'open'))
|
|
|
|
->setText(pht('View All Problem Commits')),
|
2012-03-05 18:57:46 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-04-27 18:43:05 +02:00
|
|
|
$all_commits = id(new DiffusionCommitQuery())
|
|
|
|
->setViewer($request->getUser())
|
|
|
|
->withAuditorPHIDs(array($package->getPHID()))
|
2012-03-05 18:57:46 +01:00
|
|
|
->needCommitData(true)
|
2014-04-27 18:43:05 +02:00
|
|
|
->setLimit(100)
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$view = id(new PhabricatorAuditListView())
|
2015-05-27 19:29:01 +02:00
|
|
|
->setUser($viewer)
|
2014-04-27 18:43:05 +02:00
|
|
|
->setCommits($all_commits)
|
|
|
|
->setNoDataString(pht('No commits in this package.'));
|
2012-03-05 18:57:46 +01:00
|
|
|
|
|
|
|
$commit_views[] = array(
|
|
|
|
'view' => $view,
|
2013-05-22 00:31:24 +02:00
|
|
|
'header' => pht('Recent Commits in Package'),
|
2015-03-03 22:51:28 +01:00
|
|
|
'button' => id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setHref($commit_uri)
|
|
|
|
->setText(pht('View All Package Commits')),
|
2012-03-05 18:57:46 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$phids = array();
|
|
|
|
foreach ($commit_views as $commit_view) {
|
|
|
|
$phids[] = $commit_view['view']->getRequiredHandlePHIDs();
|
|
|
|
}
|
|
|
|
$phids = array_mergev($phids);
|
2012-09-05 04:02:56 +02:00
|
|
|
$handles = $this->loadViewerHandles($phids);
|
2012-03-05 18:57:46 +01:00
|
|
|
|
|
|
|
$commit_panels = array();
|
|
|
|
foreach ($commit_views as $commit_view) {
|
2015-03-03 22:51:28 +01:00
|
|
|
$commit_panel = new PHUIObjectBoxView();
|
|
|
|
$header = new PHUIHeaderView();
|
|
|
|
$header->setHeader($commit_view['header']);
|
2012-03-05 18:57:46 +01:00
|
|
|
if (isset($commit_view['button'])) {
|
2015-03-03 22:51:28 +01:00
|
|
|
$header->addActionLink($commit_view['button']);
|
2012-03-05 18:57:46 +01:00
|
|
|
}
|
|
|
|
$commit_view['view']->setHandles($handles);
|
2015-03-03 22:51:28 +01:00
|
|
|
$commit_panel->setHeader($header);
|
2012-03-05 18:57:46 +01:00
|
|
|
$commit_panel->appendChild($commit_view['view']);
|
|
|
|
|
|
|
|
$commit_panels[] = $commit_panel;
|
|
|
|
}
|
|
|
|
|
2015-03-03 22:51:28 +01:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
$crumbs->addTextCrumb($package->getName());
|
|
|
|
|
2015-05-27 19:30:08 +02:00
|
|
|
$timeline = $this->buildTransactionTimeline(
|
|
|
|
$package,
|
|
|
|
new PhabricatorOwnersPackageTransactionQuery());
|
|
|
|
$timeline->setShouldTerminate(true);
|
|
|
|
|
2013-05-22 00:31:24 +02:00
|
|
|
return $this->buildApplicationPage(
|
2015-05-27 19:29:01 +02:00
|
|
|
array(
|
|
|
|
$crumbs,
|
|
|
|
$panel,
|
2015-05-27 19:29:31 +02:00
|
|
|
$this->renderPathsTable($paths, $repositories),
|
2015-05-27 19:29:01 +02:00
|
|
|
$commit_panels,
|
2015-05-27 19:30:08 +02:00
|
|
|
$timeline,
|
2015-05-27 19:29:01 +02:00
|
|
|
),
|
2011-04-03 23:48:36 +02:00
|
|
|
array(
|
2015-05-27 19:29:31 +02:00
|
|
|
'title' => $package->getName(),
|
2011-04-03 23:48:36 +02:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2015-05-27 19:29:31 +02:00
|
|
|
|
|
|
|
private function buildPackagePropertyView(PhabricatorOwnersPackage $package) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
$view = id(new PHUIPropertyListView())
|
|
|
|
->setUser($viewer);
|
|
|
|
|
|
|
|
$primary_phid = $package->getPrimaryOwnerPHID();
|
|
|
|
if ($primary_phid) {
|
|
|
|
$primary_owner = $viewer->renderHandle($primary_phid);
|
|
|
|
} else {
|
|
|
|
$primary_owner = phutil_tag('em', array(), pht('None'));
|
|
|
|
}
|
|
|
|
$view->addProperty(pht('Primary Owner'), $primary_owner);
|
|
|
|
|
|
|
|
// TODO: needOwners() this on the Query.
|
|
|
|
$owners = $package->loadOwners();
|
|
|
|
if ($owners) {
|
|
|
|
$owner_list = $viewer->renderHandleList(mpull($owners, 'getUserPHID'));
|
|
|
|
} else {
|
|
|
|
$owner_list = phutil_tag('em', array(), pht('None'));
|
|
|
|
}
|
|
|
|
$view->addProperty(pht('Owners'), $owner_list);
|
|
|
|
|
|
|
|
if ($package->getAuditingEnabled()) {
|
|
|
|
$auditing = pht('Enabled');
|
|
|
|
} else {
|
|
|
|
$auditing = pht('Disabled');
|
|
|
|
}
|
|
|
|
$view->addProperty(pht('Auditing'), $auditing);
|
|
|
|
|
|
|
|
$description = $package->getDescription();
|
|
|
|
if (strlen($description)) {
|
|
|
|
$view->addSectionHeader(pht('Description'));
|
|
|
|
$view->addTextContent(
|
|
|
|
$output = PhabricatorMarkupEngine::renderOneObject(
|
|
|
|
id(new PhabricatorMarkupOneOff())->setContent($description),
|
|
|
|
'default',
|
|
|
|
$viewer));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPackageActionView(PhabricatorOwnersPackage $package) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
// TODO: Implement this capability.
|
|
|
|
$can_edit = true;
|
|
|
|
|
|
|
|
$id = $package->getID();
|
|
|
|
$edit_uri = $this->getApplicationURI("/edit/{$id}/");
|
2015-05-27 19:29:50 +02:00
|
|
|
$paths_uri = $this->getApplicationURI("/paths/{$id}/");
|
2015-05-27 19:29:31 +02:00
|
|
|
|
|
|
|
$view = id(new PhabricatorActionListView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setObject($package)
|
|
|
|
->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Edit Package'))
|
|
|
|
->setIcon('fa-pencil')
|
|
|
|
->setDisabled(!$can_edit)
|
|
|
|
->setWorkflow(!$can_edit)
|
|
|
|
->setHref($edit_uri))
|
2015-05-27 19:29:50 +02:00
|
|
|
->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Edit Paths'))
|
|
|
|
->setIcon('fa-folder-open')
|
|
|
|
->setDisabled(!$can_edit)
|
|
|
|
->setWorkflow(!$can_edit)
|
Convert Owners paths to application transactions
Summary:
Ref T8320. Fixes T8317. Fixes T2831. Fixes T8073. Fixes T7127.
There was a bug with this line:
for ($ii = 0; $ii < count($paths); $ii++) {
...because the array may be sparse if there have been deletes, so `count($paths)` might be 3, but the real keys could be `1`, `5` and `6`. I think this was the primary issue behind T7127.
The old Editor did a lot of work to try to validate paths. When a path failed to validate, it silently discarded it. This was silly and pointless: it's incredibly bad UX; and it's totally fine if users saves "invalid" paths. This was likely the cause of T8317, and probably the cause of T8073.
T2831 I'm less sure about, but I can't reproduce it and I rewrote all the logic so I suspect it's gone.
This also records and shows edits, so if stuff does keep happening it should be more clear what's going on.
I removed some adjacent stuff:
- I removed the ability to delete packages. I'll add "disable" in a future diff, plus `bin/remove destroy`, like other objects. Getting rid of this now let me get rid of all the mail stuff.
- I removed "path validation" where packages would try to automatically update in response to commits. This doesn't necessarily make sense in Git/Mercurial, is sketchy, could easily have been the source of T2831, and seems generally complicated and not very valuable. We could maybe restore it some day, but I'd like to get Owners stable before trying to do crazy stuff like that.
Test Plan: {F437687}
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T8317, T8073, T7127, T2831, T8320
Differential Revision: https://secure.phabricator.com/D13032
2015-05-27 19:30:26 +02:00
|
|
|
->setHref($paths_uri));
|
2015-05-27 19:29:31 +02:00
|
|
|
|
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function renderPathsTable(array $paths, array $repositories) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
$rows = array();
|
|
|
|
foreach ($paths as $path) {
|
|
|
|
$repo = idx($repositories, $path->getRepositoryPHID());
|
|
|
|
if (!$repo) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$href = DiffusionRequest::generateDiffusionURI(
|
|
|
|
array(
|
|
|
|
'callsign' => $repo->getCallsign(),
|
|
|
|
'branch' => $repo->getDefaultBranch(),
|
|
|
|
'path' => $path->getPath(),
|
|
|
|
'action' => 'browse',
|
|
|
|
));
|
|
|
|
|
|
|
|
$path_link = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => (string)$href,
|
|
|
|
),
|
|
|
|
$path->getPath());
|
|
|
|
|
|
|
|
$rows[] = array(
|
|
|
|
($path->getExcluded() ? '-' : '+'),
|
|
|
|
$repo->getName(),
|
|
|
|
$path_link,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2015-05-27 19:29:50 +02:00
|
|
|
$info = null;
|
|
|
|
if (!$paths) {
|
|
|
|
$info = id(new PHUIInfoView())
|
|
|
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
|
|
|
->setErrors(
|
|
|
|
array(
|
|
|
|
pht(
|
|
|
|
'This package does not contain any paths yet. Use '.
|
|
|
|
'"Edit Paths" to add some.'),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2015-05-27 19:29:31 +02:00
|
|
|
$table = id(new AphrontTableView($rows))
|
|
|
|
->setHeaders(
|
|
|
|
array(
|
|
|
|
null,
|
|
|
|
pht('Repository'),
|
|
|
|
pht('Path'),
|
|
|
|
))
|
|
|
|
->setColumnClasses(
|
|
|
|
array(
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
'wide',
|
|
|
|
));
|
|
|
|
|
2015-05-27 19:29:50 +02:00
|
|
|
$box = id(new PHUIObjectBoxView())
|
2015-05-27 19:29:31 +02:00
|
|
|
->setHeaderText(pht('Paths'))
|
2015-06-29 21:28:55 +02:00
|
|
|
->setTable($table);
|
2015-05-27 19:29:31 +02:00
|
|
|
|
2015-05-27 19:29:50 +02:00
|
|
|
if ($info) {
|
|
|
|
$box->setInfoView($info);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $box;
|
2015-05-27 19:29:31 +02:00
|
|
|
}
|
|
|
|
|
2011-04-03 23:48:36 +02:00
|
|
|
}
|