1
0
Fork 0
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:
epriestley 2012-05-09 17:28:57 -07:00
parent b98847d2b1
commit 1bf68e06a5
12 changed files with 131 additions and 23 deletions

View file

@ -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',

View 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);
}
}

View 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');

View file

@ -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(
'commitID in (%Ld)',
$commit_ids);
$commit_data = mpull($commit_data, null, 'getCommitID');
} }
$commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$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);
$path_changes = queryfx_all( $commit_ids = array_filter(mpull($commits, 'getID'));
$conn_r,
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d', $path_changes = array();
PhabricatorRepository::TABLE_PATHCHANGE, if ($path_id && $commit_ids) {
mpull($commits, 'getID'), $path_changes = queryfx_all(
$path_id); $conn_r,
$path_changes = ipull($path_changes, null, 'commitID'); 'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
PhabricatorRepository::TABLE_PATHCHANGE,
$commit_ids,
$path_id);
$path_changes = ipull($path_changes, null, 'commitID');
}
$history = array(); $history = array();
foreach ($identifiers as $identifier) { foreach ($identifiers as $identifier) {

View file

@ -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.");
}
} }

View file

@ -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');

View file

@ -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();

View file

@ -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');

View file

@ -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!");
} }

View file

@ -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');

View file

@ -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,

View file

@ -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(