1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 11:30:55 +01:00

Search Symbols by Repository, not Project

Summary:
Fixes T7977.
- Move Indexed Languages and See Symbols From config to Repository
- Make symbol search skip projects

This also makes the default languages to Everything instead of Nothing.

Test Plan:
- Browse files, click symbols.
- Use quick search to find symbols
- Browse revision, click symbols

Reviewers: joshuaspence, epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, epriestley

Maniphest Tasks: T7977

Differential Revision: https://secure.phabricator.com/D12687
This commit is contained in:
Aviv Eyal 2015-05-18 06:29:47 -07:00 committed by epriestley
parent 79e8d9fc2d
commit 898ce6bace
16 changed files with 336 additions and 83 deletions

View file

@ -0,0 +1,68 @@
<?php
$table_w = new PhabricatorRepository();
$conn_w = $table_w->establishConnection('w');
// Repository and Project share a database.
$conn_r = $table_w->establishConnection('r');
$projects_table = 'repository_arcanistproject';
$raw_projects_data = queryfx_all($conn_r, 'SELECT * FROM %T', $projects_table);
$raw_projects_data = ipull($raw_projects_data, null, 'id');
$repository_ids = ipull($raw_projects_data, 'repositoryID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs($repository_ids)
->execute();
$projects_to_repo_ids_map = ipull($raw_projects_data, 'repositoryID', 'phid');
$projects_to_repos_map = array();
foreach ($projects_to_repo_ids_map as $projectPHID => $repositoryID) {
$repo = idx($repositories, $repositoryID);
if ($repo) {
$projects_to_repos_map[$projectPHID] = $repo->getPHID();
}
}
foreach ($raw_projects_data as $project_row) {
$repositoryID = idx($project_row, 'repositoryID');
$repo = idx($repositories, $repositoryID);
if (!$repo) {
continue;
}
echo pht(
"Migrating symbols configuration for '%s' project...\n",
idx($project_row, 'name', '???'));
$symbol_index_projects = $project_row['symbolIndexProjects'];
$symbol_index_projects = phutil_json_decode($symbol_index_projects);
$sources = $repo->getDetail('symbol-sources', array());
foreach ($symbol_index_projects as $index_project) {
$sources[] = idx($projects_to_repos_map, $index_project);
}
$sources = array_filter($sources);
$sources = array_unique($sources);
$repo->setDetail('symbol-sources', $sources);
$languages = $project_row['symbolIndexLanguages'];
$languages = phutil_json_decode($languages);
$languages = array_merge(
$repo->getDetail('symbol-languages', array()),
$languages);
$languages = array_unique($languages);
$repo->setDetail('symbol-languages', $languages);
queryfx(
$conn_w,
'UPDATE %T SET details = %s WHERE id = %d',
$table_w->getTableName(),
json_encode($repo->getDetails()),
$repo->getID());
}

View file

@ -0,0 +1,3 @@
ALTER TABLE {$NAMESPACE}_repository.repository_arcanistproject
DROP COLUMN symbolIndexLanguages,
DROP COLUMN symbolIndexProjects;

View file

@ -605,6 +605,7 @@ phutil_register_library_map(array(
'DiffusionRepositoryPath' => 'applications/diffusion/data/DiffusionRepositoryPath.php',
'DiffusionRepositoryRef' => 'applications/diffusion/data/DiffusionRepositoryRef.php',
'DiffusionRepositoryRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRepositoryRemarkupRule.php',
'DiffusionRepositorySymbolsController' => 'applications/diffusion/controller/DiffusionRepositorySymbolsController.php',
'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
'DiffusionResolveRefsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionResolveRefsConduitAPIMethod.php',
@ -3847,6 +3848,7 @@ phutil_register_library_map(array(
'DiffusionRepositoryNewController' => 'DiffusionController',
'DiffusionRepositoryRef' => 'Phobject',
'DiffusionRepositoryRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'DiffusionRepositorySymbolsController' => 'DiffusionRepositoryEditController',
'DiffusionResolveRefsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionResolveUserQuery' => 'Phobject',
'DiffusionSSHWorkflow' => 'PhabricatorSSHWorkflow',

View file

@ -260,14 +260,14 @@ final class DifferentialRevisionViewController extends DifferentialController {
'whitespace',
DifferentialChangesetParser::WHITESPACE_IGNORE_MOST);
$arc_project = $target->getArcanistProject();
if ($arc_project) {
list($symbol_indexes, $project_phids) = $this->buildSymbolIndexes(
$arc_project,
$repository = $revision->getRepository();
if ($repository) {
list($symbol_indexes, $repository_phids) = $this->buildSymbolIndexes(
$repository,
$visible_changesets);
} else {
$symbol_indexes = array();
$project_phids = null;
$repository_phids = null;
}
$revision_detail->setActions($actions);
@ -307,12 +307,12 @@ final class DifferentialRevisionViewController extends DifferentialController {
),
$comment_view);
if ($arc_project) {
if ($repository) {
Javelin::initBehavior(
'repository-crossreference',
array(
'section' => $wrap_id,
'projects' => $project_phids,
'repositories' => $repository_phids,
));
}
@ -750,35 +750,33 @@ final class DifferentialRevisionViewController extends DifferentialController {
}
private function buildSymbolIndexes(
PhabricatorRepositoryArcanistProject $arc_project,
PhabricatorRepository $repository,
array $visible_changesets) {
assert_instances_of($visible_changesets, 'DifferentialChangeset');
$engine = PhabricatorSyntaxHighlighter::newEngine();
$langs = $arc_project->getSymbolIndexLanguages();
if (!$langs) {
return array(array(), array());
}
$langs = $repository->getSymbolLanguages();
$langs = nonempty($langs, array());
$symbol_indexes = array();
$project_phids = array_merge(
array($arc_project->getPHID()),
nonempty($arc_project->getSymbolIndexProjects(), array()));
$repository_phids = array_merge(
array($repository->getPHID()),
nonempty($repository->getSymbolSources(), array()));
$indexed_langs = array_fill_keys($langs, true);
foreach ($visible_changesets as $key => $changeset) {
$lang = $engine->getLanguageFromFilename($changeset->getFilename());
if (isset($indexed_langs[$lang])) {
if (empty($indexed_langs) || isset($indexed_langs[$lang])) {
$symbol_indexes[$key] = array(
'lang' => $lang,
'projects' => $project_phids,
'lang' => $lang,
'repositories' => $repository_phids,
);
}
}
return array($symbol_indexes, $project_phids);
return array($symbol_indexes, $repository_phids);
}
private function loadOtherRevisions(

View file

@ -100,6 +100,7 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
'hosting/' => 'DiffusionRepositoryEditHostingController',
'(?P<serve>serve)/' => 'DiffusionRepositoryEditHostingController',
'update/' => 'DiffusionRepositoryEditUpdateController',
'symbol/' => 'DiffusionRepositorySymbolsController',
),
'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController',
'mirror/' => array(

View file

@ -266,32 +266,20 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
$id = celerity_generate_unique_node_id();
$projects = $drequest->loadArcanistProjects();
$langs = array();
foreach ($projects as $project) {
$ls = $project->getSymbolIndexLanguages();
if (!$ls) {
continue;
}
$dep_projects = $project->getSymbolIndexProjects();
$dep_projects[] = $project->getPHID();
foreach ($ls as $lang) {
if (!isset($langs[$lang])) {
$langs[$lang] = array();
}
$langs[$lang] += $dep_projects + array($project);
}
}
$repo = $drequest->getRepository();
$symbol_repos = $repo->getSymbolSources();
$symbol_repos[] = $repo;
$lang = last(explode('.', $drequest->getPath()));
if (isset($langs[$lang])) {
$repo_languages = $repo->getSymbolLanguages();
$repo_languages = array_fill_keys($repo_languages, true);
if (empty($repo_languages) || isset($repo_languages[$lang])) {
Javelin::initBehavior(
'repository-crossreference',
array(
'container' => $id,
'lang' => $lang,
'projects' => $langs[$lang],
'repositories' => $symbol_repos,
));
}

View file

@ -62,6 +62,10 @@ final class DiffusionRepositoryEditMainController
$encoding_properties =
$this->buildEncodingProperties($repository, $encoding_actions);
$symbols_actions = $this->buildSymbolsActions($repository);
$symbols_properties =
$this->buildSymbolsProperties($repository, $symbols_actions);
$hosting_properties = $this->buildHostingProperties(
$repository,
$this->buildHostingActions($repository));
@ -157,6 +161,10 @@ final class DiffusionRepositoryEditMainController
->setHeaderText(pht('Text Encoding'))
->addPropertyList($encoding_properties);
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Symbols'))
->addPropertyList($symbols_properties);
if ($branches_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Branches'))
@ -1187,6 +1195,53 @@ final class DiffusionRepositoryEditMainController
return $mirror_list;
}
private function buildSymbolsActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setObjectURI($this->getRequest()->getRequestURI())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Symbols'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/symbol/'));
$view->addAction($edit);
return $view;
}
private function buildSymbolsProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$languages = $repository->getSymbolLanguages();
if ($languages) {
$languages = implode(', ', $languages);
} else {
$languages = phutil_tag('em', array(), pht('Any'));
}
$view->addProperty(pht('Languages'), $languages);
$sources = $repository->getSymbolSources();
if ($sources) {
$handles = $viewer->loadHandles($sources);
$sources = $handles->renderList();
} else {
$sources = phutil_tag('em', array(), pht('This Repository Only'));
}
$view->addProperty(pht('Use Symbols From'), $sources);
return $view;
}
private function getEnvConfigLink() {
$config_href = '/config/edit/environment.append-paths/';
return phutil_tag(

View file

@ -0,0 +1,123 @@
<?php
final class DiffusionRepositorySymbolsController
extends DiffusionRepositoryEditController {
protected function processDiffusionRequest(AphrontRequest $request) {
$user = $request->getUser();
$drequest = $this->diffusionRequest;
$repository = $drequest->getRepository();
$repository = id(new PhabricatorRepositoryQuery())
->setViewer($user)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->withIDs(array($repository->getID()))
->executeOne();
if (!$repository) {
return new Aphront404Response();
}
$edit_uri = $this->getRepositoryControllerURI($repository, 'edit/');
$v_sources = $repository->getSymbolSources();
$v_languages = $repository->getSymbolLanguages();
if ($v_languages) {
$v_languages = implode(', ', $v_languages);
}
$errors = array();
if ($request->isFormPost()) {
$v_sources = $request->getArr('sources');
$v_languages = $request->getStrList('languages');
$v_languages = array_map('phutil_utf8_strtolower', $v_languages);
if (!$errors) {
$xactions = array();
$template = id(new PhabricatorRepositoryTransaction());
$type_sources = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES;
$type_lang = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE;
$xactions[] = id(clone $template)
->setTransactionType($type_sources)
->setNewValue($v_sources);
$xactions[] = id(clone $template)
->setTransactionType($type_lang)
->setNewValue($v_languages);
try {
id(new PhabricatorRepositoryEditor())
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request)
->setActor($user)
->applyTransactions($repository, $xactions);
return id(new AphrontRedirectResponse())->setURI($edit_uri);
} catch (Exception $ex) {
$errors[] = $ex->getMessage();
}
}
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Edit Symbols'));
$title = pht('Edit %s', $repository->getName());
$form = id(new AphrontFormView())
->setUser($user)
->appendRemarkupInstructions($this->getInstructions())
->appendChild(
id(new AphrontFormTextControl())
->setName('languages')
->setLabel(pht('Indexed Languages'))
->setCaption(pht(
'File extensions, separate with commas, for example: php, py. '.
'Leave blank for "any".'))
->setValue($v_languages))
->appendControl(
id(new AphrontFormTokenizerControl())
->setName('sources')
->setLabel(pht('Uses Symbols From'))
->setDatasource(new DiffusionRepositoryDatasource())
->setValue($v_sources))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save'))
->addCancelButton($edit_uri));
$object_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setForm($form)
->setFormErrors($errors);
return $this->buildApplicationPage(
array(
$crumbs,
$object_box,
),
array(
'title' => $title,
));
}
private function getInstructions() {
return pht(<<<EOT
Configure Symbols for this repository.
See [[%s | Symbol Indexes]] for more information on using symbols.
EOT
,
PhabricatorEnv::getDoclink(
'Diffusion User Guide: Symbol Indexes'));
}
}

View file

@ -128,7 +128,7 @@ final class DiffusionSymbolController extends DiffusionController {
'',
));
$table->setNoDataString(
pht('No matching symbol could be found in any indexed project.'));
pht('No matching symbol could be found in any indexed repository.'));
$panel = new PHUIObjectBoxView();
$panel->setHeaderText(pht('Similar Symbols'));

View file

@ -146,11 +146,12 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
$this->loadPaths($symbols);
}
if ($this->needRepositories) {
$this->loadRepositories($symbols);
$symbols = $this->loadRepositories($symbols);
}
}
return $symbols;
}
@ -249,10 +250,16 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
->execute();
$repos = mpull($repos, null, 'getPHID');
$visible = array();
foreach ($symbols as $symbol) {
$repository = idx($repos, $symbol->getRepositoryPHID());
$symbol->attachRepository($repository);
// repository is null mean "user can't view repo", so hide the symbol
if ($repository) {
$symbol->attachRepository($repository);
$visible[] = $symbol;
}
}
return $visible;
}
}

View file

@ -34,13 +34,6 @@ final class PhabricatorRepositoryArcanistProjectEditController
asort($repos);
if ($request->isFormPost()) {
$indexed = $request->getStrList('symbolIndexLanguages');
$indexed = array_map('strtolower', $indexed);
$project->setSymbolIndexLanguages($indexed);
$project->setSymbolIndexProjects($request->getArr('symbolIndexProjects'));
$repo_id = $request->getInt('repository', 0);
if (isset($repos[$repo_id])) {
$project->setRepositoryID($repo_id);
@ -51,19 +44,6 @@ final class PhabricatorRepositoryArcanistProjectEditController
}
}
$langs = $project->getSymbolIndexLanguages();
if ($langs) {
$langs = implode(', ', $langs);
} else {
$langs = null;
}
if ($project->getSymbolIndexProjects()) {
$uses = $project->getSymbolIndexProjects();
} else {
$uses = array();
}
$form = id(new AphrontFormView())
->setUser($user)
->appendChild(
@ -80,20 +60,6 @@ final class PhabricatorRepositoryArcanistProjectEditController
->setOptions($repos)
->setName('repository')
->setValue($project->getRepositoryID()))
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Indexed Languages'))
->setName('symbolIndexLanguages')
->setCaption(pht(
'Separate with commas, for example: %s',
phutil_tag('tt', array(), 'php, py')))
->setValue($langs))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Uses Symbols From'))
->setName('symbolIndexProjects')
->setDatasource(new DiffusionArcanistProjectDatasource())
->setValue($uses))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/repository/')

View file

@ -41,6 +41,8 @@ final class PhabricatorRepositoryEditor
$types[] = PhabricatorRepositoryTransaction::TYPE_DANGEROUS;
$types[] = PhabricatorRepositoryTransaction::TYPE_CLONE_NAME;
$types[] = PhabricatorRepositoryTransaction::TYPE_SERVICE;
$types[] = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE;
$types[] = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES;
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
@ -98,6 +100,10 @@ final class PhabricatorRepositoryEditor
return $object->getDetail('clone-name');
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
return $object->getAlmanacServicePHID();
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
return $object->getSymbolLanguages();
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
return $object->getSymbolSources();
}
}
@ -131,6 +137,8 @@ final class PhabricatorRepositoryEditor
case PhabricatorRepositoryTransaction::TYPE_DANGEROUS:
case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME:
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
return $xaction->getNewValue();
case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE:
@ -205,6 +213,12 @@ final class PhabricatorRepositoryEditor
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
$object->setAlmanacServicePHID($xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
$object->setDetail('symbol-languages', $xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
$object->setDetail('symbol-sources', $xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_ENCODING:
// Make sure the encoding is valid by converting to UTF-8. This tests
// that the user has mbstring installed, and also that they didn't type
@ -314,6 +328,8 @@ final class PhabricatorRepositoryEditor
case PhabricatorRepositoryTransaction::TYPE_DANGEROUS:
case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME:
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,

View file

@ -1778,6 +1778,17 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
}
/* -( Symbols )-------------------------------------------------------------*/
public function getSymbolSources() {
return $this->getDetail('symbol-sources');
}
public function getSymbolLanguages() {
return $this->getDetail('symbol-languages');
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -9,19 +9,12 @@ final class PhabricatorRepositoryArcanistProject
protected $name;
protected $repositoryID;
protected $symbolIndexLanguages = array();
protected $symbolIndexProjects = array();
private $repository = self::ATTACHABLE;
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_SERIALIZATION => array(
'symbolIndexLanguages' => self::SERIALIZATION_JSON,
'symbolIndexProjects' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text128',
'repositoryID' => 'id?',

View file

@ -25,6 +25,8 @@ final class PhabricatorRepositoryTransaction
const TYPE_DANGEROUS = 'repo:dangerous';
const TYPE_CLONE_NAME = 'repo:clone-name';
const TYPE_SERVICE = 'repo:service';
const TYPE_SYMBOLS_SOURCES = 'repo:symbol-source';
const TYPE_SYMBOLS_LANGUAGE = 'repo:symbol-language';
// TODO: Clean up these legacy transaction types.
const TYPE_SSH_LOGIN = 'repo:ssh-login';
@ -61,6 +63,14 @@ final class PhabricatorRepositoryTransaction
$phids[] = $new;
}
break;
case self::TYPE_SYMBOLS_SOURCES:
if ($old) {
$phids = array_merge($phids, $old);
}
if ($new) {
$phids = array_merge($phids, $new);
}
break;
}
return $phids;
@ -393,6 +403,18 @@ final class PhabricatorRepositoryTransaction
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case self::TYPE_SYMBOLS_SOURCES:
return pht(
'%s changed symbol sources from %s to %s.',
$this->renderHandleLink($author_phid),
empty($old) ? pht('None') : $this->renderHandleList($old),
empty($new) ? pht('None') : $this->renderHandleList($new));
case self::TYPE_SYMBOLS_LANGUAGE:
return pht('%s changed indexed languages from %s to %s.',
$this->renderHandleLink($author_phid),
$old ? implode(', ', $old) : pht('Any'),
$new ? implode(', ', $new) : pht('Any'));
}
return parent::getTitle();

View file

@ -29,7 +29,7 @@ JX.behavior('repository-crossreference', function(config) {
var symbol = target.textContent || target.innerText;
var query = {
lang : lang,
projects : config.projects.join(','),
repositories : config.repositories.join(','),
jump : true
};
if (map[target.className]) {