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',
|
||||
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
|
||||
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
|
||||
'AphrontStackTraceView' => 'view/widget/AphrontStackTraceView.php',
|
||||
'AphrontTableView' => 'view/control/AphrontTableView.php',
|
||||
'AphrontTagView' => 'view/AphrontTagView.php',
|
||||
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
|
||||
|
@ -2401,6 +2402,7 @@ phutil_register_library_map(array(
|
|||
'AphrontRequestFailureView' => 'AphrontView',
|
||||
'AphrontRequestTestCase' => 'PhabricatorTestCase',
|
||||
'AphrontSideNavFilterView' => 'AphrontView',
|
||||
'AphrontStackTraceView' => 'AphrontView',
|
||||
'AphrontTableView' => 'AphrontView',
|
||||
'AphrontTagView' => 'AphrontView',
|
||||
'AphrontTokenizerTemplateView' => 'AphrontView',
|
||||
|
|
|
@ -243,7 +243,9 @@ class AphrontDefaultApplicationConfiguration
|
|||
}
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
|
||||
$trace = $this->renderStackTrace($ex->getTrace(), $user);
|
||||
$trace = id(new AphrontStackTraceView())
|
||||
->setUser($user)
|
||||
->setTrace($ex->getTrace());
|
||||
} else {
|
||||
$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 {
|
||||
|
||||
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) {
|
||||
$this->uri = $uri;
|
||||
|
@ -33,31 +41,44 @@ class AphrontRedirectResponse extends AphrontResponse {
|
|||
|
||||
public function buildResponseString() {
|
||||
if ($this->shouldStopForDebugging()) {
|
||||
$user = new PhabricatorUser();
|
||||
|
||||
$view = new PhabricatorStandardPageView();
|
||||
$view->setRequest($this->getRequest());
|
||||
$view->setApplicationName('Debug');
|
||||
$view->setTitle('Stopped on Redirect');
|
||||
|
||||
$error = new AphrontErrorView();
|
||||
$error->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
||||
$error->setTitle('Stopped on Redirect');
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setUser($user);
|
||||
$dialog->setTitle('Stopped on Redirect');
|
||||
|
||||
$error->appendChild(phutil_tag('p', array(), pht(
|
||||
$dialog->appendParagraph(
|
||||
pht(
|
||||
'You were stopped here because %s is set in your configuration.',
|
||||
phutil_tag('tt', array(), 'debug.stop-on-redirect'))));
|
||||
phutil_tag('tt', array(), 'debug.stop-on-redirect')));
|
||||
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $this->getURI(),
|
||||
),
|
||||
$this->getURI());
|
||||
$dialog->appendParagraph(
|
||||
pht(
|
||||
'You are being redirected to: %s',
|
||||
phutil_tag('tt', array(), $this->getURI())));
|
||||
|
||||
$error->appendChild(phutil_tag('p', array(), pht(
|
||||
'Continue to: %s',
|
||||
$link)));
|
||||
$dialog->addCancelButton($this->getURI(), pht('Continue'));
|
||||
|
||||
$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();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ final class PhabricatorEmailVerificationController
|
|||
'user. Make sure you followed the link in the email correctly and are '.
|
||||
'logged in with the user account associated with the email address.');
|
||||
$continue = pht('Rats!');
|
||||
} else if ($email->getIsVerified()) {
|
||||
} else if ($email->getIsVerified() && $user->getIsEmailVerified()) {
|
||||
$title = pht('Address Already Verified');
|
||||
$content = pht(
|
||||
'This email address has already been verified.');
|
||||
|
|
|
@ -19,7 +19,7 @@ final class PhabricatorMustVerifyEmailController
|
|||
|
||||
$email = $user->loadPrimaryEmail();
|
||||
|
||||
if ($email->getIsVerified()) {
|
||||
if ($user->getIsEmailVerified()) {
|
||||
return id(new AphrontRedirectResponse())->setURI('/');
|
||||
}
|
||||
|
||||
|
|
|
@ -88,10 +88,9 @@ final class PhabricatorRepositoryDiscoveryEngine
|
|||
|
||||
try {
|
||||
list($xml, $stderr) = $repository->execxRemoteCommand(
|
||||
'log --xml --quiet --limit %d %s@%s',
|
||||
'log --xml --quiet --limit %d %s',
|
||||
$limit,
|
||||
$repository->getSubversionBaseURI(),
|
||||
$at_rev);
|
||||
$repository->getSubversionBaseURI($at_rev));
|
||||
} catch (CommandException $ex) {
|
||||
$stderr = $ex->getStdErr();
|
||||
if (preg_match('/(path|File) not found/', $stderr)) {
|
||||
|
|
|
@ -155,12 +155,12 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
|||
return $this->getDetail('local-path');
|
||||
}
|
||||
|
||||
public function getSubversionBaseURI() {
|
||||
public function getSubversionBaseURI($commit = null) {
|
||||
$subpath = $this->getDetail('svn-subpath');
|
||||
if (!strlen($subpath)) {
|
||||
$subpath = null;
|
||||
}
|
||||
return $this->getSubversionPathURI($subpath);
|
||||
return $this->getSubversionPathURI($subpath, $commit);
|
||||
}
|
||||
|
||||
public function getSubversionPathURI($path = null, $commit = null) {
|
||||
|
|
|
@ -94,6 +94,17 @@ final class PhabricatorRepositoryTestCase
|
|||
$this->assertEqual(
|
||||
'file:///var/repo/SVN/%3F@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