mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Merge branch 'master' of github.com:facebook/phabricator
This commit is contained in:
commit
6ead3a160b
9 changed files with 179 additions and 130 deletions
|
@ -81,6 +81,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php',
|
'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php',
|
||||||
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
|
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
|
||||||
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
|
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
|
||||||
|
'AphrontStackTraceView' => 'view/widget/AphrontStackTraceView.php',
|
||||||
'AphrontTableView' => 'view/control/AphrontTableView.php',
|
'AphrontTableView' => 'view/control/AphrontTableView.php',
|
||||||
'AphrontTagView' => 'view/AphrontTagView.php',
|
'AphrontTagView' => 'view/AphrontTagView.php',
|
||||||
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
|
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
|
||||||
|
@ -2401,6 +2402,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontRequestFailureView' => 'AphrontView',
|
'AphrontRequestFailureView' => 'AphrontView',
|
||||||
'AphrontRequestTestCase' => 'PhabricatorTestCase',
|
'AphrontRequestTestCase' => 'PhabricatorTestCase',
|
||||||
'AphrontSideNavFilterView' => 'AphrontView',
|
'AphrontSideNavFilterView' => 'AphrontView',
|
||||||
|
'AphrontStackTraceView' => 'AphrontView',
|
||||||
'AphrontTableView' => 'AphrontView',
|
'AphrontTableView' => 'AphrontView',
|
||||||
'AphrontTagView' => 'AphrontView',
|
'AphrontTagView' => 'AphrontView',
|
||||||
'AphrontTokenizerTemplateView' => 'AphrontView',
|
'AphrontTokenizerTemplateView' => 'AphrontView',
|
||||||
|
|
|
@ -243,7 +243,9 @@ class AphrontDefaultApplicationConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
|
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
|
||||||
$trace = $this->renderStackTrace($ex->getTrace(), $user);
|
$trace = id(new AphrontStackTraceView())
|
||||||
|
->setUser($user)
|
||||||
|
->setTrace($ex->getTrace());
|
||||||
} else {
|
} else {
|
||||||
$trace = null;
|
$trace = null;
|
||||||
}
|
}
|
||||||
|
@ -290,110 +292,4 @@ class AphrontDefaultApplicationConfiguration
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderStackTrace($trace, PhabricatorUser $user) {
|
|
||||||
|
|
||||||
$libraries = PhutilBootloader::getInstance()->getAllLibraries();
|
|
||||||
|
|
||||||
// TODO: Make this configurable?
|
|
||||||
$path = 'https://secure.phabricator.com/diffusion/%s/browse/master/src/';
|
|
||||||
|
|
||||||
$callsigns = array(
|
|
||||||
'arcanist' => 'ARC',
|
|
||||||
'phutil' => 'PHU',
|
|
||||||
'phabricator' => 'P',
|
|
||||||
);
|
|
||||||
|
|
||||||
$rows = array();
|
|
||||||
$depth = count($trace);
|
|
||||||
foreach ($trace as $part) {
|
|
||||||
$lib = null;
|
|
||||||
$file = idx($part, 'file');
|
|
||||||
$relative = $file;
|
|
||||||
foreach ($libraries as $library) {
|
|
||||||
$root = phutil_get_library_root($library);
|
|
||||||
if (Filesystem::isDescendant($file, $root)) {
|
|
||||||
$lib = $library;
|
|
||||||
$relative = Filesystem::readablePath($file, $root);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$where = '';
|
|
||||||
if (isset($part['class'])) {
|
|
||||||
$where .= $part['class'].'::';
|
|
||||||
}
|
|
||||||
if (isset($part['function'])) {
|
|
||||||
$where .= $part['function'].'()';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($file) {
|
|
||||||
if (isset($callsigns[$lib])) {
|
|
||||||
$attrs = array('title' => $file);
|
|
||||||
try {
|
|
||||||
$attrs['href'] = $user->loadEditorLink(
|
|
||||||
'/src/'.$relative,
|
|
||||||
$part['line'],
|
|
||||||
$callsigns[$lib]);
|
|
||||||
} catch (Exception $ex) {
|
|
||||||
// The database can be inaccessible.
|
|
||||||
}
|
|
||||||
if (empty($attrs['href'])) {
|
|
||||||
$attrs['href'] = sprintf($path, $callsigns[$lib]).
|
|
||||||
str_replace(DIRECTORY_SEPARATOR, '/', $relative).
|
|
||||||
'$'.$part['line'];
|
|
||||||
$attrs['target'] = '_blank';
|
|
||||||
}
|
|
||||||
$file_name = phutil_tag(
|
|
||||||
'a',
|
|
||||||
$attrs,
|
|
||||||
$relative);
|
|
||||||
} else {
|
|
||||||
$file_name = phutil_tag(
|
|
||||||
'span',
|
|
||||||
array(
|
|
||||||
'title' => $file,
|
|
||||||
),
|
|
||||||
$relative);
|
|
||||||
}
|
|
||||||
$file_name = hsprintf('%s : %d', $file_name, $part['line']);
|
|
||||||
} else {
|
|
||||||
$file_name = phutil_tag('em', array(), '(Internal)');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$rows[] = array(
|
|
||||||
$depth--,
|
|
||||||
$lib,
|
|
||||||
$file_name,
|
|
||||||
$where,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$table = new AphrontTableView($rows);
|
|
||||||
$table->setHeaders(
|
|
||||||
array(
|
|
||||||
'Depth',
|
|
||||||
'Library',
|
|
||||||
'File',
|
|
||||||
'Where',
|
|
||||||
));
|
|
||||||
$table->setColumnClasses(
|
|
||||||
array(
|
|
||||||
'n',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'wide',
|
|
||||||
));
|
|
||||||
|
|
||||||
return phutil_tag(
|
|
||||||
'div',
|
|
||||||
array('class' => 'exception-trace'),
|
|
||||||
array(
|
|
||||||
phutil_tag(
|
|
||||||
'div',
|
|
||||||
array('class' => 'exception-trace-header'),
|
|
||||||
pht('Stack Trace')),
|
|
||||||
$table->render(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,14 @@
|
||||||
class AphrontRedirectResponse extends AphrontResponse {
|
class AphrontRedirectResponse extends AphrontResponse {
|
||||||
|
|
||||||
private $uri;
|
private $uri;
|
||||||
|
private $stackWhenCreated;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
if ($this->shouldStopForDebugging()) {
|
||||||
|
// If we're going to stop, capture the stack so we can print it out.
|
||||||
|
$this->stackWhenCreated = id(new Exception())->getTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function setURI($uri) {
|
public function setURI($uri) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
|
@ -33,31 +41,44 @@ class AphrontRedirectResponse extends AphrontResponse {
|
||||||
|
|
||||||
public function buildResponseString() {
|
public function buildResponseString() {
|
||||||
if ($this->shouldStopForDebugging()) {
|
if ($this->shouldStopForDebugging()) {
|
||||||
|
$user = new PhabricatorUser();
|
||||||
|
|
||||||
$view = new PhabricatorStandardPageView();
|
$view = new PhabricatorStandardPageView();
|
||||||
$view->setRequest($this->getRequest());
|
$view->setRequest($this->getRequest());
|
||||||
$view->setApplicationName('Debug');
|
$view->setApplicationName('Debug');
|
||||||
$view->setTitle('Stopped on Redirect');
|
$view->setTitle('Stopped on Redirect');
|
||||||
|
|
||||||
$error = new AphrontErrorView();
|
$dialog = new AphrontDialogView();
|
||||||
$error->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
$dialog->setUser($user);
|
||||||
$error->setTitle('Stopped on Redirect');
|
$dialog->setTitle('Stopped on Redirect');
|
||||||
|
|
||||||
$error->appendChild(phutil_tag('p', array(), pht(
|
$dialog->appendParagraph(
|
||||||
'You were stopped here because %s is set in your configuration.',
|
pht(
|
||||||
phutil_tag('tt', array(), 'debug.stop-on-redirect'))));
|
'You were stopped here because %s is set in your configuration.',
|
||||||
|
phutil_tag('tt', array(), 'debug.stop-on-redirect')));
|
||||||
|
|
||||||
$link = phutil_tag(
|
$dialog->appendParagraph(
|
||||||
'a',
|
pht(
|
||||||
array(
|
'You are being redirected to: %s',
|
||||||
'href' => $this->getURI(),
|
phutil_tag('tt', array(), $this->getURI())));
|
||||||
),
|
|
||||||
$this->getURI());
|
|
||||||
|
|
||||||
$error->appendChild(phutil_tag('p', array(), pht(
|
$dialog->addCancelButton($this->getURI(), pht('Continue'));
|
||||||
'Continue to: %s',
|
|
||||||
$link)));
|
|
||||||
|
|
||||||
$view->appendChild($error);
|
$dialog->appendChild(phutil_tag('br'));
|
||||||
|
|
||||||
|
$dialog->appendChild(
|
||||||
|
id(new AphrontStackTraceView())
|
||||||
|
->setUser($user)
|
||||||
|
->setTrace($this->stackWhenCreated));
|
||||||
|
|
||||||
|
$dialog->setIsStandalone(true);
|
||||||
|
$dialog->setWidth(AphrontDialogView::WIDTH_FULL);
|
||||||
|
|
||||||
|
$box = id(new PHUIBoxView())
|
||||||
|
->addMargin(PHUI::MARGIN_LARGE)
|
||||||
|
->appendChild($dialog);
|
||||||
|
|
||||||
|
$view->appendChild($box);
|
||||||
|
|
||||||
return $view->render();
|
return $view->render();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ final class PhabricatorEmailVerificationController
|
||||||
'user. Make sure you followed the link in the email correctly and are '.
|
'user. Make sure you followed the link in the email correctly and are '.
|
||||||
'logged in with the user account associated with the email address.');
|
'logged in with the user account associated with the email address.');
|
||||||
$continue = pht('Rats!');
|
$continue = pht('Rats!');
|
||||||
} else if ($email->getIsVerified()) {
|
} else if ($email->getIsVerified() && $user->getIsEmailVerified()) {
|
||||||
$title = pht('Address Already Verified');
|
$title = pht('Address Already Verified');
|
||||||
$content = pht(
|
$content = pht(
|
||||||
'This email address has already been verified.');
|
'This email address has already been verified.');
|
||||||
|
|
|
@ -19,7 +19,7 @@ final class PhabricatorMustVerifyEmailController
|
||||||
|
|
||||||
$email = $user->loadPrimaryEmail();
|
$email = $user->loadPrimaryEmail();
|
||||||
|
|
||||||
if ($email->getIsVerified()) {
|
if ($user->getIsEmailVerified()) {
|
||||||
return id(new AphrontRedirectResponse())->setURI('/');
|
return id(new AphrontRedirectResponse())->setURI('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,10 +88,9 @@ final class PhabricatorRepositoryDiscoveryEngine
|
||||||
|
|
||||||
try {
|
try {
|
||||||
list($xml, $stderr) = $repository->execxRemoteCommand(
|
list($xml, $stderr) = $repository->execxRemoteCommand(
|
||||||
'log --xml --quiet --limit %d %s@%s',
|
'log --xml --quiet --limit %d %s',
|
||||||
$limit,
|
$limit,
|
||||||
$repository->getSubversionBaseURI(),
|
$repository->getSubversionBaseURI($at_rev));
|
||||||
$at_rev);
|
|
||||||
} catch (CommandException $ex) {
|
} catch (CommandException $ex) {
|
||||||
$stderr = $ex->getStdErr();
|
$stderr = $ex->getStdErr();
|
||||||
if (preg_match('/(path|File) not found/', $stderr)) {
|
if (preg_match('/(path|File) not found/', $stderr)) {
|
||||||
|
|
|
@ -155,12 +155,12 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
return $this->getDetail('local-path');
|
return $this->getDetail('local-path');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubversionBaseURI() {
|
public function getSubversionBaseURI($commit = null) {
|
||||||
$subpath = $this->getDetail('svn-subpath');
|
$subpath = $this->getDetail('svn-subpath');
|
||||||
if (!strlen($subpath)) {
|
if (!strlen($subpath)) {
|
||||||
$subpath = null;
|
$subpath = null;
|
||||||
}
|
}
|
||||||
return $this->getSubversionPathURI($subpath);
|
return $this->getSubversionPathURI($subpath, $commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubversionPathURI($path = null, $commit = null) {
|
public function getSubversionPathURI($path = null, $commit = null) {
|
||||||
|
|
|
@ -94,6 +94,17 @@ final class PhabricatorRepositoryTestCase
|
||||||
$this->assertEqual(
|
$this->assertEqual(
|
||||||
'file:///var/repo/SVN/%3F@22',
|
'file:///var/repo/SVN/%3F@22',
|
||||||
$repo->getSubversionPathURI('?', 22));
|
$repo->getSubversionPathURI('?', 22));
|
||||||
|
|
||||||
|
$repo->setDetail('svn-subpath', 'quack/trunk/');
|
||||||
|
|
||||||
|
$this->assertEqual(
|
||||||
|
'file:///var/repo/SVN/quack/trunk/@',
|
||||||
|
$repo->getSubversionBaseURI());
|
||||||
|
|
||||||
|
$this->assertEqual(
|
||||||
|
'file:///var/repo/SVN/quack/trunk/@HEAD',
|
||||||
|
$repo->getSubversionBaseURI('HEAD'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
120
src/view/widget/AphrontStackTraceView.php
Normal file
120
src/view/widget/AphrontStackTraceView.php
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AphrontStackTraceView extends AphrontView {
|
||||||
|
|
||||||
|
private $trace;
|
||||||
|
|
||||||
|
public function setTrace($trace) {
|
||||||
|
$this->trace = $trace;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() {
|
||||||
|
$user = $this->getUser();
|
||||||
|
$trace = $this->trace;
|
||||||
|
|
||||||
|
$libraries = PhutilBootloader::getInstance()->getAllLibraries();
|
||||||
|
|
||||||
|
// TODO: Make this configurable?
|
||||||
|
$path = 'https://secure.phabricator.com/diffusion/%s/browse/master/src/';
|
||||||
|
|
||||||
|
$callsigns = array(
|
||||||
|
'arcanist' => 'ARC',
|
||||||
|
'phutil' => 'PHU',
|
||||||
|
'phabricator' => 'P',
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
$depth = count($trace);
|
||||||
|
foreach ($trace as $part) {
|
||||||
|
$lib = null;
|
||||||
|
$file = idx($part, 'file');
|
||||||
|
$relative = $file;
|
||||||
|
foreach ($libraries as $library) {
|
||||||
|
$root = phutil_get_library_root($library);
|
||||||
|
if (Filesystem::isDescendant($file, $root)) {
|
||||||
|
$lib = $library;
|
||||||
|
$relative = Filesystem::readablePath($file, $root);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$where = '';
|
||||||
|
if (isset($part['class'])) {
|
||||||
|
$where .= $part['class'].'::';
|
||||||
|
}
|
||||||
|
if (isset($part['function'])) {
|
||||||
|
$where .= $part['function'].'()';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file) {
|
||||||
|
if (isset($callsigns[$lib])) {
|
||||||
|
$attrs = array('title' => $file);
|
||||||
|
try {
|
||||||
|
$attrs['href'] = $user->loadEditorLink(
|
||||||
|
'/src/'.$relative,
|
||||||
|
$part['line'],
|
||||||
|
$callsigns[$lib]);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
// The database can be inaccessible.
|
||||||
|
}
|
||||||
|
if (empty($attrs['href'])) {
|
||||||
|
$attrs['href'] = sprintf($path, $callsigns[$lib]).
|
||||||
|
str_replace(DIRECTORY_SEPARATOR, '/', $relative).
|
||||||
|
'$'.$part['line'];
|
||||||
|
$attrs['target'] = '_blank';
|
||||||
|
}
|
||||||
|
$file_name = phutil_tag(
|
||||||
|
'a',
|
||||||
|
$attrs,
|
||||||
|
$relative);
|
||||||
|
} else {
|
||||||
|
$file_name = phutil_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'title' => $file,
|
||||||
|
),
|
||||||
|
$relative);
|
||||||
|
}
|
||||||
|
$file_name = hsprintf('%s : %d', $file_name, $part['line']);
|
||||||
|
} else {
|
||||||
|
$file_name = phutil_tag('em', array(), '(Internal)');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
$depth--,
|
||||||
|
$lib,
|
||||||
|
$file_name,
|
||||||
|
$where,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$table = new AphrontTableView($rows);
|
||||||
|
$table->setHeaders(
|
||||||
|
array(
|
||||||
|
'Depth',
|
||||||
|
'Library',
|
||||||
|
'File',
|
||||||
|
'Where',
|
||||||
|
));
|
||||||
|
$table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'n',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'wide',
|
||||||
|
));
|
||||||
|
|
||||||
|
return phutil_tag(
|
||||||
|
'div',
|
||||||
|
array('class' => 'exception-trace'),
|
||||||
|
array(
|
||||||
|
phutil_tag(
|
||||||
|
'div',
|
||||||
|
array('class' => 'exception-trace-header'),
|
||||||
|
pht('Stack Trace')),
|
||||||
|
$table->render(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue