2011-03-13 01:17:34 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class DiffusionView extends AphrontView {
|
|
|
|
|
|
|
|
private $diffusionRequest;
|
|
|
|
|
|
|
|
final public function setDiffusionRequest(DiffusionRequest $request) {
|
|
|
|
$this->diffusionRequest = $request;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function getDiffusionRequest() {
|
|
|
|
return $this->diffusionRequest;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function linkHistory($path) {
|
Fix many encoding and architecture problems in Diffusion request and URI handling
Summary:
Diffusion request/uri handling is currently a big, hastily ported mess. In particular, it has:
- Tons and tons of duplicated code.
- Bugs with handling unusual branch and file names.
- An excessively large (and yet insufficiently expressive) API on DiffusionRequest, including a nonsensical concrete base class.
- Other tools were doing hacky things like passing ":" branch names.
This diff attempts to fix these issues.
- Make the base class abstract (it was concrete ONLY for "/diffusion/").
- Move all URI generation to DiffusionRequest. Make the core static. Add unit tests.
- Delete the 300 copies of URI generation code throughout Diffusion.
- Move all URI parsing to DiffusionRequest. Make the core static. Add unit tests.
- Add an appropriate static initializer for other callers.
- Convert all code calling `newFromAphrontRequestDictionary` outside of Diffusion to the new `newFromDictionary` API.
- Refactor static initializers to be sensibly-sized.
- Refactor derived DiffusionRequest classes to remove duplicated code.
- Properly encode branch names (fixes branches with "/", see <https://github.com/facebook/phabricator/issues/100>).
- Properly encode path names (fixes issues in D1742).
- Properly escape delimiter characters ";" and "$" in path names so files like "$100" are not interpreted as "line 100".
- Fix a couple warnings.
- Fix a couple lint issues.
- Fix a bug where we would not parse filenames with spaces in them correctly in the Git browse query.
- Fix a bug where Git change queries would fail unnecessarily.
- Provide or improve some documentation.
This thing is pretty gigantic but also kind of hard to split up. If it's unreasonably difficult to review, let me know and I can take a stab at it though.
This supplants D1742.
Test Plan:
- Used home, repository, branch, browse, change, history, diff (ajax), lastmodified (ajax) views of Diffusion.
- Used Owners typeaheads and search.
- Used diffusion.getrecentcommitsbypath method.
- Pushed a change to an absurdly-named file on an absurdly-named branch, everything worked properly.
{F9185}
Reviewers: nh, vrana, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1921
2012-03-20 03:52:14 +01:00
|
|
|
$href = $this->getDiffusionRequest()->generateURI(
|
|
|
|
array(
|
|
|
|
'action' => 'history',
|
|
|
|
'path' => $path,
|
|
|
|
));
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2015-10-06 16:38:15 +02:00
|
|
|
return $this->renderHistoryLink($href);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function linkBranchHistory($branch) {
|
|
|
|
$href = $this->getDiffusionRequest()->generateURI(
|
|
|
|
array(
|
|
|
|
'action' => 'history',
|
|
|
|
'branch' => $branch,
|
|
|
|
));
|
|
|
|
|
|
|
|
return $this->renderHistoryLink($href);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function linkTagHistory($tag) {
|
|
|
|
$href = $this->getDiffusionRequest()->generateURI(
|
|
|
|
array(
|
|
|
|
'action' => 'history',
|
|
|
|
'commit' => $tag,
|
|
|
|
));
|
|
|
|
|
|
|
|
return $this->renderHistoryLink($href);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function renderHistoryLink($href) {
|
2015-09-11 04:28:49 +02:00
|
|
|
return javelin_tag(
|
2011-03-13 01:17:34 +01:00
|
|
|
'a',
|
|
|
|
array(
|
Fix many encoding and architecture problems in Diffusion request and URI handling
Summary:
Diffusion request/uri handling is currently a big, hastily ported mess. In particular, it has:
- Tons and tons of duplicated code.
- Bugs with handling unusual branch and file names.
- An excessively large (and yet insufficiently expressive) API on DiffusionRequest, including a nonsensical concrete base class.
- Other tools were doing hacky things like passing ":" branch names.
This diff attempts to fix these issues.
- Make the base class abstract (it was concrete ONLY for "/diffusion/").
- Move all URI generation to DiffusionRequest. Make the core static. Add unit tests.
- Delete the 300 copies of URI generation code throughout Diffusion.
- Move all URI parsing to DiffusionRequest. Make the core static. Add unit tests.
- Add an appropriate static initializer for other callers.
- Convert all code calling `newFromAphrontRequestDictionary` outside of Diffusion to the new `newFromDictionary` API.
- Refactor static initializers to be sensibly-sized.
- Refactor derived DiffusionRequest classes to remove duplicated code.
- Properly encode branch names (fixes branches with "/", see <https://github.com/facebook/phabricator/issues/100>).
- Properly encode path names (fixes issues in D1742).
- Properly escape delimiter characters ";" and "$" in path names so files like "$100" are not interpreted as "line 100".
- Fix a couple warnings.
- Fix a couple lint issues.
- Fix a bug where we would not parse filenames with spaces in them correctly in the Git browse query.
- Fix a bug where Git change queries would fail unnecessarily.
- Provide or improve some documentation.
This thing is pretty gigantic but also kind of hard to split up. If it's unreasonably difficult to review, let me know and I can take a stab at it though.
This supplants D1742.
Test Plan:
- Used home, repository, branch, browse, change, history, diff (ajax), lastmodified (ajax) views of Diffusion.
- Used Owners typeaheads and search.
- Used diffusion.getrecentcommitsbypath method.
- Pushed a change to an absurdly-named file on an absurdly-named branch, everything worked properly.
{F9185}
Reviewers: nh, vrana, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1921
2012-03-20 03:52:14 +01:00
|
|
|
'href' => $href,
|
2015-09-11 04:28:49 +02:00
|
|
|
'class' => 'diffusion-link-icon',
|
|
|
|
'sigil' => 'has-tooltip',
|
|
|
|
'meta' => array(
|
|
|
|
'tip' => pht('History'),
|
|
|
|
'align' => 'E',
|
|
|
|
),
|
2011-03-13 01:17:34 +01:00
|
|
|
),
|
2015-10-06 16:38:15 +02:00
|
|
|
id(new PHUIIconView())->setIconFont('fa-history bluegrey'));
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
final public function linkBrowse($path, array $details = array()) {
|
2015-09-11 04:28:49 +02:00
|
|
|
require_celerity_resource('diffusion-icons-css');
|
|
|
|
Javelin::initBehavior('phabricator-tooltips');
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2015-09-11 04:28:49 +02:00
|
|
|
$file_type = idx($details, 'type');
|
|
|
|
unset($details['type']);
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2015-09-11 04:28:49 +02:00
|
|
|
$display_name = idx($details, 'name');
|
|
|
|
unset($details['name']);
|
|
|
|
|
|
|
|
if (strlen($display_name)) {
|
|
|
|
$display_name = phutil_tag(
|
|
|
|
'span',
|
|
|
|
array(
|
|
|
|
'class' => 'diffusion-browse-name',
|
|
|
|
),
|
|
|
|
$display_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($details['external'])) {
|
|
|
|
$href = id(new PhutilURI('/diffusion/external/'))
|
|
|
|
->setQueryParams(
|
|
|
|
array(
|
|
|
|
'uri' => idx($details, 'external'),
|
|
|
|
'id' => idx($details, 'hash'),
|
|
|
|
));
|
|
|
|
$tip = pht('Browse External');
|
2011-03-13 01:17:34 +01:00
|
|
|
} else {
|
2015-09-11 04:28:49 +02:00
|
|
|
$href = $this->getDiffusionRequest()->generateURI(
|
|
|
|
$details + array(
|
|
|
|
'action' => 'browse',
|
|
|
|
'path' => $path,
|
|
|
|
));
|
|
|
|
$tip = pht('Browse');
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
2015-09-11 04:28:49 +02:00
|
|
|
$icon = DifferentialChangeType::getIconForFileType($file_type);
|
|
|
|
$icon_view = id(new PHUIIconView())->setIconFont("{$icon} blue");
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2015-09-11 04:28:49 +02:00
|
|
|
// If we're rendering a file or directory name, don't show the tooltip.
|
|
|
|
if ($display_name !== null) {
|
|
|
|
$sigil = null;
|
|
|
|
$meta = null;
|
|
|
|
} else {
|
|
|
|
$sigil = 'has-tooltip';
|
|
|
|
$meta = array(
|
|
|
|
'tip' => $tip,
|
|
|
|
'align' => 'E',
|
|
|
|
);
|
|
|
|
}
|
Improve Diffusion behavior for externals
Summary:
- Feature request from Airtime that I missed in the feedback notes, came up yesterday.
- Identify git submodules as "FILE_SUBMODULE", not "FILE_NORMAL".
- Link git submodules to an external resolver endpoint, which tries to find commits in tracked repositories.
- Identify git symlinks as "FILE_SYMLINK", not "FILE_NORMAL".
- Add folder, file, symlink and externals icons.
Test Plan:
- externals/javelin is now identified as a submoudule and links to Javelin, not identified as a file and links to error.
- bin/phd is now identified as a symlink.
- Interfaces have pretty icons.
Reviewers: btrahan, cpiro, ddfisher, keebuhm, allenjohnashton
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1975
2012-03-21 22:01:20 +01:00
|
|
|
|
2015-09-11 04:28:49 +02:00
|
|
|
return javelin_tag(
|
Improve Diffusion behavior for externals
Summary:
- Feature request from Airtime that I missed in the feedback notes, came up yesterday.
- Identify git submodules as "FILE_SUBMODULE", not "FILE_NORMAL".
- Link git submodules to an external resolver endpoint, which tries to find commits in tracked repositories.
- Identify git symlinks as "FILE_SYMLINK", not "FILE_NORMAL".
- Add folder, file, symlink and externals icons.
Test Plan:
- externals/javelin is now identified as a submoudule and links to Javelin, not identified as a file and links to error.
- bin/phd is now identified as a symlink.
- Interfaces have pretty icons.
Reviewers: btrahan, cpiro, ddfisher, keebuhm, allenjohnashton
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1975
2012-03-21 22:01:20 +01:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $href,
|
2015-09-11 04:28:49 +02:00
|
|
|
'class' => 'diffusion-link-icon',
|
|
|
|
'sigil' => $sigil,
|
|
|
|
'meta' => $meta,
|
Improve Diffusion behavior for externals
Summary:
- Feature request from Airtime that I missed in the feedback notes, came up yesterday.
- Identify git submodules as "FILE_SUBMODULE", not "FILE_NORMAL".
- Link git submodules to an external resolver endpoint, which tries to find commits in tracked repositories.
- Identify git symlinks as "FILE_SYMLINK", not "FILE_NORMAL".
- Add folder, file, symlink and externals icons.
Test Plan:
- externals/javelin is now identified as a submoudule and links to Javelin, not identified as a file and links to error.
- bin/phd is now identified as a symlink.
- Interfaces have pretty icons.
Reviewers: btrahan, cpiro, ddfisher, keebuhm, allenjohnashton
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1975
2012-03-21 22:01:20 +01:00
|
|
|
),
|
2015-09-11 04:28:49 +02:00
|
|
|
array(
|
|
|
|
$icon_view,
|
|
|
|
$display_name,
|
|
|
|
));
|
Improve Diffusion behavior for externals
Summary:
- Feature request from Airtime that I missed in the feedback notes, came up yesterday.
- Identify git submodules as "FILE_SUBMODULE", not "FILE_NORMAL".
- Link git submodules to an external resolver endpoint, which tries to find commits in tracked repositories.
- Identify git symlinks as "FILE_SYMLINK", not "FILE_NORMAL".
- Add folder, file, symlink and externals icons.
Test Plan:
- externals/javelin is now identified as a submoudule and links to Javelin, not identified as a file and links to error.
- bin/phd is now identified as a symlink.
- Interfaces have pretty icons.
Reviewers: btrahan, cpiro, ddfisher, keebuhm, allenjohnashton
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1975
2012-03-21 22:01:20 +01:00
|
|
|
}
|
|
|
|
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
final public static function linkCommit(
|
|
|
|
PhabricatorRepository $repository,
|
2013-02-26 16:12:44 +01:00
|
|
|
$commit,
|
|
|
|
$summary = '') {
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
|
2016-01-02 20:28:31 +01:00
|
|
|
$commit_name = $repository->formatCommitName($commit);
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2013-02-26 16:12:44 +01:00
|
|
|
if (strlen($summary)) {
|
2014-06-10 01:03:58 +02:00
|
|
|
$commit_name .= ': '.$summary;
|
2013-02-26 16:12:44 +01:00
|
|
|
}
|
|
|
|
|
2013-01-18 09:32:58 +01:00
|
|
|
return phutil_tag(
|
2011-03-13 01:17:34 +01:00
|
|
|
'a',
|
|
|
|
array(
|
2016-01-02 20:48:41 +01:00
|
|
|
'href' => $repository->getCommitURI($commit),
|
2011-03-13 01:17:34 +01:00
|
|
|
),
|
|
|
|
$commit_name);
|
|
|
|
}
|
|
|
|
|
2012-06-23 01:52:08 +02:00
|
|
|
final public static function linkRevision($id) {
|
|
|
|
if (!$id) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2013-01-18 09:32:58 +01:00
|
|
|
return phutil_tag(
|
2012-06-23 01:52:08 +02:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => "/D{$id}",
|
|
|
|
),
|
|
|
|
"D{$id}");
|
|
|
|
}
|
|
|
|
|
2014-05-11 00:57:16 +02:00
|
|
|
final public static function renderName($name) {
|
2012-08-09 03:26:23 +02:00
|
|
|
$email = new PhutilEmailAddress($name);
|
2012-12-03 18:27:47 +01:00
|
|
|
if ($email->getDisplayName() && $email->getDomainName()) {
|
2012-08-09 03:26:23 +02:00
|
|
|
Javelin::initBehavior('phabricator-tooltips', array());
|
|
|
|
require_celerity_resource('aphront-tooltip-css');
|
2013-01-25 21:57:17 +01:00
|
|
|
return javelin_tag(
|
2012-08-09 03:26:23 +02:00
|
|
|
'span',
|
|
|
|
array(
|
|
|
|
'sigil' => 'has-tooltip',
|
|
|
|
'meta' => array(
|
|
|
|
'tip' => $email->getAddress(),
|
|
|
|
'align' => 'E',
|
|
|
|
'size' => 'auto',
|
|
|
|
),
|
|
|
|
),
|
2013-01-25 21:57:17 +01:00
|
|
|
$email->getDisplayName());
|
2012-08-09 03:26:23 +02:00
|
|
|
}
|
2013-02-13 23:50:15 +01:00
|
|
|
return hsprintf('%s', $name);
|
2012-08-09 03:26:23 +02:00
|
|
|
}
|
|
|
|
|
2015-10-06 16:38:15 +02:00
|
|
|
final protected function renderBuildable(HarbormasterBuildable $buildable) {
|
|
|
|
$status = $buildable->getBuildableStatus();
|
|
|
|
|
|
|
|
$icon = HarbormasterBuildable::getBuildableStatusIcon($status);
|
|
|
|
$color = HarbormasterBuildable::getBuildableStatusColor($status);
|
|
|
|
$name = HarbormasterBuildable::getBuildableStatusName($status);
|
|
|
|
|
|
|
|
$icon_view = id(new PHUIIconView())
|
|
|
|
->setIconFont($icon.' '.$color);
|
|
|
|
|
|
|
|
$tooltip_view = javelin_tag(
|
|
|
|
'span',
|
|
|
|
array(
|
|
|
|
'sigil' => 'has-tooltip',
|
|
|
|
'meta' => array('tip' => $name),
|
|
|
|
),
|
|
|
|
$icon_view);
|
|
|
|
|
|
|
|
Javelin::initBehavior('phabricator-tooltips');
|
|
|
|
|
|
|
|
return phutil_tag(
|
|
|
|
'a',
|
|
|
|
array('href' => '/'.$buildable->getMonogram()),
|
|
|
|
$tooltip_view);
|
|
|
|
}
|
|
|
|
|
|
|
|
final protected function loadBuildables(array $commits) {
|
|
|
|
assert_instances_of($commits, 'PhabricatorRepositoryCommit');
|
|
|
|
|
|
|
|
if (!$commits) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
|
|
|
|
$viewer = $this->getUser();
|
|
|
|
|
|
|
|
$harbormaster_app = 'PhabricatorHarbormasterApplication';
|
|
|
|
$have_harbormaster = PhabricatorApplication::isClassInstalledForViewer(
|
|
|
|
$harbormaster_app,
|
|
|
|
$viewer);
|
|
|
|
|
|
|
|
if ($have_harbormaster) {
|
|
|
|
$buildables = id(new HarbormasterBuildableQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withBuildablePHIDs(mpull($commits, 'getPHID'))
|
|
|
|
->withManualBuildables(false)
|
|
|
|
->execute();
|
|
|
|
$buildables = mpull($buildables, null, 'getBuildablePHID');
|
|
|
|
} else {
|
|
|
|
$buildables = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $buildables;
|
|
|
|
}
|
|
|
|
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|