mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 12:00:55 +01:00
Improve Diffusion error messages and UI for partially imported repositories
Summary: - When you have an un-cloned repository, we currently throw random-looking Git/Hg exception. Instead, throw a useful error. - When you have a cloned but undiscovered repository, we show no commits. This is crazy confusing. Instead, show commits as "importing...". - Fix some warnings and errors for empty path table cases, etc. Test Plan: - Wiped database. - Added Mercurial repo without running daemons. Viewed in Diffusion, got a good exception. - Pulled Mercurial repo without discovering it. Got "Importing...". - Discovered Mercurial repo without parsing it. Got "Importing..." plus date information. - Parsed Mercurial repo, got everything working properly. - Added Git repo without running daemons, did all the stuff above, same results. - This doesn't improve SVN much but that's a trickier case since we don't actually make SVN calls and rely only on the parse state. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T776 Differential Revision: https://secure.phabricator.com/D2439
This commit is contained in:
parent
b98847d2b1
commit
1bf68e06a5
12 changed files with 131 additions and 23 deletions
|
@ -373,6 +373,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
|
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
|
||||||
'DiffusionRepositoryTag' => 'applications/diffusion/tag',
|
'DiffusionRepositoryTag' => 'applications/diffusion/tag',
|
||||||
'DiffusionRequest' => 'applications/diffusion/request/base',
|
'DiffusionRequest' => 'applications/diffusion/request/base',
|
||||||
|
'DiffusionSetupException' => 'applications/diffusion/exception/setup',
|
||||||
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn',
|
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn',
|
||||||
'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/svn',
|
'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/svn',
|
||||||
'DiffusionSvnCommitTagsQuery' => 'applications/diffusion/query/committags/svn',
|
'DiffusionSvnCommitTagsQuery' => 'applications/diffusion/query/committags/svn',
|
||||||
|
|
25
src/applications/diffusion/exception/setup/DiffusionSetupException.php
Executable file
25
src/applications/diffusion/exception/setup/DiffusionSetupException.php
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class DiffusionSetupException extends AphrontUsageException {
|
||||||
|
|
||||||
|
public function __construct($message) {
|
||||||
|
parent::__construct('Diffusion Setup Exception', $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/applications/diffusion/exception/setup/__init__.php
Normal file
12
src/applications/diffusion/exception/setup/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/exception/usage');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('DiffusionSetupException.php');
|
|
@ -75,20 +75,37 @@ abstract class DiffusionQuery {
|
||||||
$identifiers);
|
$identifiers);
|
||||||
$commits = mpull($commits, null, 'getCommitIdentifier');
|
$commits = mpull($commits, null, 'getCommitIdentifier');
|
||||||
|
|
||||||
// Reorder the commits in identifier order so we preserve nth-parent
|
// Build empty commit objects for every commit, so we can show unparsed
|
||||||
// relationships when the identifiers are the parents of a merge commit.
|
// commits in history views as "unparsed" instead of not showing them. This
|
||||||
$commits = array_select_keys($commits, $identifiers);
|
// makes the process of importing and parsing commits much clearer to the
|
||||||
|
// user.
|
||||||
|
|
||||||
if (!$commits) {
|
$commit_list = array();
|
||||||
return array();
|
foreach ($identifiers as $identifier) {
|
||||||
|
$commit_obj = idx($commits, $identifier);
|
||||||
|
if (!$commit_obj) {
|
||||||
|
$commit_obj = new PhabricatorRepositoryCommit();
|
||||||
|
$commit_obj->setRepositoryID($repository->getID());
|
||||||
|
$commit_obj->setCommitIdentifier($identifier);
|
||||||
|
$commit_obj->setIsUnparsed(true);
|
||||||
|
$commit_obj->makeEphemeral();
|
||||||
}
|
}
|
||||||
|
$commit_list[$identifier] = $commit_obj;
|
||||||
|
}
|
||||||
|
$commits = $commit_list;
|
||||||
|
|
||||||
|
$commit_ids = array_filter(mpull($commits, 'getID'));
|
||||||
|
if ($commit_ids) {
|
||||||
$commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
|
$commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
|
||||||
'commitID in (%Ld)',
|
'commitID in (%Ld)',
|
||||||
mpull($commits, 'getID'));
|
$commit_ids);
|
||||||
$commit_data = mpull($commit_data, null, 'getCommitID');
|
$commit_data = mpull($commit_data, null, 'getCommitID');
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($commits as $commit) {
|
foreach ($commits as $commit) {
|
||||||
|
if (!$commit->getID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (idx($commit_data, $commit->getID())) {
|
if (idx($commit_data, $commit->getID())) {
|
||||||
$commit->attachCommitData($commit_data[$commit->getID()]);
|
$commit->attachCommitData($commit_data[$commit->getID()]);
|
||||||
}
|
}
|
||||||
|
@ -123,13 +140,18 @@ abstract class DiffusionQuery {
|
||||||
$paths = ipull($paths, 'id', 'path');
|
$paths = ipull($paths, 'id', 'path');
|
||||||
$path_id = idx($paths, $path_normal);
|
$path_id = idx($paths, $path_normal);
|
||||||
|
|
||||||
|
$commit_ids = array_filter(mpull($commits, 'getID'));
|
||||||
|
|
||||||
|
$path_changes = array();
|
||||||
|
if ($path_id && $commit_ids) {
|
||||||
$path_changes = queryfx_all(
|
$path_changes = queryfx_all(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
|
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
|
||||||
PhabricatorRepository::TABLE_PATHCHANGE,
|
PhabricatorRepository::TABLE_PATHCHANGE,
|
||||||
mpull($commits, 'getID'),
|
$commit_ids,
|
||||||
$path_id);
|
$path_id);
|
||||||
$path_changes = ipull($path_changes, null, 'commitID');
|
$path_changes = ipull($path_changes, null, 'commitID');
|
||||||
|
}
|
||||||
|
|
||||||
$history = array();
|
$history = array();
|
||||||
foreach ($identifiers as $identifier) {
|
foreach ($identifiers as $identifier) {
|
||||||
|
|
|
@ -510,4 +510,16 @@ abstract class DiffusionRequest {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function raiseCloneException() {
|
||||||
|
$host = php_uname('n');
|
||||||
|
$callsign = $this->getRepository()->getCallsign();
|
||||||
|
throw new DiffusionSetupException(
|
||||||
|
"The working copy for this repository ('{$callsign}') hasn't been ".
|
||||||
|
"cloned yet on this machine ('{$host}'). Make sure you've started the ".
|
||||||
|
"Phabricator daemons. If this problem persists for longer than a clone ".
|
||||||
|
"should take, check the daemon logs (in the Daemon Console) to see if ".
|
||||||
|
"there were errors cloning the repository. Consult the 'Diffusion User ".
|
||||||
|
"Guide' in the documentation for help setting up repositories.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/exception/setup');
|
||||||
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
|
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
|
||||||
phutil_require_module('phabricator', 'applications/repository/storage/commit');
|
phutil_require_module('phabricator', 'applications/repository/storage/commit');
|
||||||
phutil_require_module('phabricator', 'applications/repository/storage/commitdata');
|
phutil_require_module('phabricator', 'applications/repository/storage/commitdata');
|
||||||
|
|
|
@ -26,13 +26,19 @@ final class DiffusionGitRequest extends DiffusionRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function didInitialize() {
|
protected function didInitialize() {
|
||||||
|
$repository = $this->getRepository();
|
||||||
|
|
||||||
|
if (!Filesystem::pathExists($repository->getLocalPath())) {
|
||||||
|
$this->raiseCloneException();
|
||||||
|
}
|
||||||
|
|
||||||
if (!$this->commit) {
|
if (!$this->commit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand short commit names and verify
|
// Expand short commit names and verify
|
||||||
|
|
||||||
$future = $this->getRepository()->getLocalCommandFuture(
|
$future = $repository->getLocalCommandFuture(
|
||||||
'cat-file --batch');
|
'cat-file --batch');
|
||||||
$future->write($this->commit);
|
$future->write($this->commit);
|
||||||
list($stdout) = $future->resolvex();
|
list($stdout) = $future->resolvex();
|
||||||
|
|
|
@ -10,5 +10,7 @@ phutil_require_module('phabricator', 'aphront/exception/usage');
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/data/branch');
|
phutil_require_module('phabricator', 'applications/diffusion/data/branch');
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/request/base');
|
phutil_require_module('phabricator', 'applications/diffusion/request/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'filesystem');
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('DiffusionGitRequest.php');
|
phutil_require_source('DiffusionGitRequest.php');
|
||||||
|
|
|
@ -26,6 +26,12 @@ final class DiffusionMercurialRequest extends DiffusionRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function didInitialize() {
|
protected function didInitialize() {
|
||||||
|
$repository = $this->getRepository();
|
||||||
|
|
||||||
|
if (!Filesystem::pathExists($repository->getLocalPath())) {
|
||||||
|
$this->raiseCloneException();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +39,11 @@ final class DiffusionMercurialRequest extends DiffusionRequest {
|
||||||
if ($this->branch) {
|
if ($this->branch) {
|
||||||
return $this->branch;
|
return $this->branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->repository) {
|
if ($this->repository) {
|
||||||
return $this->repository->getDetail('default-branch', 'default');
|
return $this->repository->getDetail('default-branch', 'default');
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception("Unable to determine branch!");
|
throw new Exception("Unable to determine branch!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,7 @@
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/request/base');
|
phutil_require_module('phabricator', 'applications/diffusion/request/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'filesystem');
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('DiffusionMercurialRequest.php');
|
phutil_require_source('DiffusionMercurialRequest.php');
|
||||||
|
|
|
@ -93,6 +93,17 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
||||||
$author = phutil_escape_html($history->getAuthorName());
|
$author = phutil_escape_html($history->getAuthorName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$commit = $history->getCommit();
|
||||||
|
if ($commit && !$commit->getIsUnparsed() && $data) {
|
||||||
|
$change = $this->linkChange(
|
||||||
|
$history->getChangeType(),
|
||||||
|
$history->getFileType(),
|
||||||
|
$path = null,
|
||||||
|
$history->getCommitIdentifier());
|
||||||
|
} else {
|
||||||
|
$change = "<em>Importing\xE2\x80\xA6</em>";
|
||||||
|
}
|
||||||
|
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
$this->linkBrowse(
|
$this->linkBrowse(
|
||||||
$drequest->getPath(),
|
$drequest->getPath(),
|
||||||
|
@ -103,11 +114,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
||||||
self::linkCommit(
|
self::linkCommit(
|
||||||
$drequest->getRepository(),
|
$drequest->getRepository(),
|
||||||
$history->getCommitIdentifier()),
|
$history->getCommitIdentifier()),
|
||||||
$this->linkChange(
|
$change,
|
||||||
$history->getChangeType(),
|
|
||||||
$history->getFileType(),
|
|
||||||
null,
|
|
||||||
$history->getCommitIdentifier()),
|
|
||||||
$date,
|
$date,
|
||||||
$time,
|
$time,
|
||||||
$author,
|
$author,
|
||||||
|
|
|
@ -27,6 +27,16 @@ final class PhabricatorRepositoryCommit extends PhabricatorRepositoryDAO {
|
||||||
protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE;
|
protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE;
|
||||||
|
|
||||||
private $commitData;
|
private $commitData;
|
||||||
|
private $isUnparsed;
|
||||||
|
|
||||||
|
public function setIsUnparsed($is_unparsed) {
|
||||||
|
$this->isUnparsed = $is_unparsed;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsUnparsed() {
|
||||||
|
return $this->isUnparsed;
|
||||||
|
}
|
||||||
|
|
||||||
public function getConfiguration() {
|
public function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
|
|
Loading…
Reference in a new issue