Page MenuHomePhabricator

D13070.id32318.diff
No OneTemporary

D13070.id32318.diff

diff --git a/resources/sql/autopatches/20150616.divinerrepository.sql b/resources/sql/autopatches/20150616.divinerrepository.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150616.divinerrepository.sql
@@ -0,0 +1,5 @@
+ALTER TABLE {$NAMESPACE}_diviner.diviner_livebook
+ ADD COLUMN repositoryPHID VARBINARY(64) AFTER name;
+
+ALTER TABLE {$NAMESPACE}_diviner.diviner_livesymbol
+ ADD COLUMN repositoryPHID VARBINARY(64) AFTER bookPHID;
diff --git a/src/applications/diviner/controller/DivinerAtomController.php b/src/applications/diviner/controller/DivinerAtomController.php
--- a/src/applications/diviner/controller/DivinerAtomController.php
+++ b/src/applications/diviner/controller/DivinerAtomController.php
@@ -85,6 +85,7 @@
if ($atom) {
$this->buildDefined($properties, $symbol);
$this->buildExtendsAndImplements($properties, $symbol);
+ $this->buildRepository($properties, $symbol);
$warnings = $atom->getWarnings();
if ($warnings) {
@@ -295,6 +296,15 @@
}
}
+ private function buildRepository(
+ PHUIPropertyListView $view,
+ DivinerLiveSymbol $symbol) {
+
+ $view->addProperty(
+ pht('Repository'),
+ $this->getViewer()->renderHandle($symbol->getRepositoryPHID()));
+ }
+
private function renderAtomTag(DivinerLiveSymbol $symbol) {
return id(new PHUITagView())
->setType(PHUITagView::TYPE_OBJECT)
diff --git a/src/applications/diviner/controller/DivinerBookController.php b/src/applications/diviner/controller/DivinerBookController.php
--- a/src/applications/diviner/controller/DivinerBookController.php
+++ b/src/applications/diviner/controller/DivinerBookController.php
@@ -14,6 +14,7 @@
$book = id(new DivinerBookQuery())
->setViewer($viewer)
->withNames(array($book_name))
+ ->needRepositories(true)
->executeOne();
if (!$book) {
@@ -43,6 +44,15 @@
->setEpoch($book->getDateModified())
->addActionLink($action_button);
+ // TODO: This could probably look better.
+ if ($book->getRepositoryPHID()) {
+ $header->addTag(
+ id(new PHUITagView())
+ ->setType(PHUITagView::TYPE_STATE)
+ ->setBackgroundColor(PHUITagView::COLOR_BLUE)
+ ->setName($book->getRepository()->getMonogram()));
+ }
+
$document = new PHUIDocumentView();
$document->setHeader($header);
$document->addClass('diviner-view');
diff --git a/src/applications/diviner/controller/DivinerBookEditController.php b/src/applications/diviner/controller/DivinerBookEditController.php
--- a/src/applications/diviner/controller/DivinerBookEditController.php
+++ b/src/applications/diviner/controller/DivinerBookEditController.php
@@ -75,6 +75,16 @@
->setName('projectPHIDs')
->setLabel(pht('Projects'))
->setValue($book->getProjectPHIDs()))
+ ->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource(new DiffusionRepositoryDatasource())
+ ->setName('repositoryPHIDs')
+ ->setLabel(pht('Repository'))
+ ->setDisableBehavior(true)
+ ->setLimit(1)
+ ->setValue($book->getRepositoryPHID()
+ ? array($book->getRepositoryPHID())
+ : null))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
diff --git a/src/applications/diviner/publisher/DivinerLivePublisher.php b/src/applications/diviner/publisher/DivinerLivePublisher.php
--- a/src/applications/diviner/publisher/DivinerLivePublisher.php
+++ b/src/applications/diviner/publisher/DivinerLivePublisher.php
@@ -4,7 +4,7 @@
private $book;
- private function loadBook() {
+ protected function getBook() {
if (!$this->book) {
$book_name = $this->getConfig('name');
@@ -20,7 +20,24 @@
->save();
}
- $book->setConfigurationData($this->getConfigurationData())->save();
+ $conn_w = $book->establishConnection('w');
+ $conn_w->openTransaction();
+
+ $book
+ ->setRepositoryPHID($this->getRepositoryPHID())
+ ->setConfigurationData($this->getConfigurationData())
+ ->save();
+
+ // TODO: This is gross. Without this, the repository won't be updated for
+ // atoms which have already been published.
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET repositoryPHID = %s WHERE bookPHID = %s',
+ id(new DivinerLiveSymbol())->getTableName(),
+ $this->getRepositoryPHID(),
+ $book->getPHID());
+
+ $conn_w->saveTransaction();
$this->book = $book;
id(new PhabricatorSearchIndexer())
@@ -33,7 +50,7 @@
private function loadSymbolForAtom(DivinerAtom $atom) {
$symbol = id(new DivinerAtomQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
- ->withBookPHIDs(array($this->loadBook()->getPHID()))
+ ->withBookPHIDs(array($atom->getBook()))
->withTypes(array($atom->getType()))
->withNames(array($atom->getName()))
->withContexts(array($atom->getContext()))
@@ -45,7 +62,7 @@
}
return id(new DivinerLiveSymbol())
- ->setBookPHID($this->loadBook()->getPHID())
+ ->setBookPHID($this->getBook()->getPHID())
->setType($atom->getType())
->setName($atom->getName())
->setContext($atom->getContext())
@@ -68,7 +85,7 @@
protected function loadAllPublishedHashes() {
$symbols = id(new DivinerAtomQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
- ->withBookPHIDs(array($this->loadBook()->getPHID()))
+ ->withBookPHIDs(array($this->getBook()->getPHID()))
->withGhosts(false)
->execute();
@@ -113,6 +130,7 @@
$is_documentable = $this->shouldGenerateDocumentForAtom($atom);
$symbol
+ ->setRepositoryPHID($this->getRepositoryPHID())
->setGraphHash($hash)
->setIsDocumentable((int)$is_documentable)
->setTitle($ref->getTitle())
diff --git a/src/applications/diviner/publisher/DivinerPublisher.php b/src/applications/diviner/publisher/DivinerPublisher.php
--- a/src/applications/diviner/publisher/DivinerPublisher.php
+++ b/src/applications/diviner/publisher/DivinerPublisher.php
@@ -9,6 +9,7 @@
private $config;
private $symbolReverseMap;
private $dropCaches;
+ private $repositoryPHID;
final public function setDropCaches($drop_caches) {
$this->dropCaches = $drop_caches;
@@ -163,4 +164,13 @@
return true;
}
+ final public function getRepositoryPHID() {
+ return $this->repositoryPHID;
+ }
+
+ final public function setRepositoryPHID($repository_phid) {
+ $this->repositoryPHID = $repository_phid;
+ return $this;
+ }
+
}
diff --git a/src/applications/diviner/query/DivinerAtomQuery.php b/src/applications/diviner/query/DivinerAtomQuery.php
--- a/src/applications/diviner/query/DivinerAtomQuery.php
+++ b/src/applications/diviner/query/DivinerAtomQuery.php
@@ -14,10 +14,12 @@
private $nodeHashes;
private $titles;
private $nameContains;
+ private $repositoryPHIDs;
private $needAtoms;
private $needExtends;
private $needChildren;
+ private $needRepositories;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -109,6 +111,16 @@
return $this;
}
+ public function withRepositoryPHIDs(array $repository_phids) {
+ $this->repositoryPHIDs = $repository_phids;
+ return $this;
+ }
+
+ public function needRepositories($need_repositories) {
+ $this->needRepositories = $need_repositories;
+ return $this;
+ }
+
protected function loadPage() {
$table = new DivinerLiveSymbol();
$conn_r = $table->establishConnection('r');
@@ -125,6 +137,8 @@
}
protected function willFilterPage(array $atoms) {
+ assert_instances_of($atoms, 'DivinerLiveSymbol');
+
$books = array_unique(mpull($atoms, 'getBookPHID'));
$books = id(new DivinerBookQuery())
@@ -257,6 +271,31 @@
$this->attachAllChildren($atoms, $children, $this->needExtends);
}
+ if ($this->needRepositories) {
+ $repositories = id(new PhabricatorRepositoryQuery())
+ ->setViewer($this->getViewer())
+ ->withPHIDs(mpull($atoms, 'getRepositoryPHID'))
+ ->execute();
+ $repositories = mpull($repositories, null, 'getPHID');
+
+ foreach ($atoms as $key => $atom) {
+ if ($atom->getRepositoryPHID() === null) {
+ $atom->attachRepository(null);
+ continue;
+ }
+
+ $repository = idx($repositories, $atom->getRepositoryPHID());
+
+ if (!$repository) {
+ $this->didRejectResult($atom);
+ unset($atom[$key]);
+ continue;
+ }
+
+ $atom->attachRepository($repository);
+ }
+ }
+
return $atoms;
}
@@ -381,6 +420,13 @@
$this->nameContains);
}
+ if ($this->repositoryPHIDs) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'repositoryPHID IN (%Ls)',
+ $this->repositoryPHIDs);
+ }
+
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
diff --git a/src/applications/diviner/query/DivinerAtomSearchEngine.php b/src/applications/diviner/query/DivinerAtomSearchEngine.php
--- a/src/applications/diviner/query/DivinerAtomSearchEngine.php
+++ b/src/applications/diviner/query/DivinerAtomSearchEngine.php
@@ -14,20 +14,22 @@
$saved = new PhabricatorSavedQuery();
$saved->setParameter(
+ 'repositoryPHIDs',
+ $this->readPHIDsFromRequest($request, 'repositoryPHIDs'));
+ $saved->setParameter('name', $request->getStr('name'));
+ $saved->setParameter(
'types',
$this->readListFromRequest($request, 'types'));
- $saved->setParameter('name', $request->getStr('name'));
-
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new DivinerAtomQuery());
- $types = $saved->getParameter('types');
- if ($types) {
- $query->withTypes($types);
+ $repository_phids = $saved->getParameter('repositoryPHIDs');
+ if ($repository_phids) {
+ $query->withRepositoryPHIDs($repository_phids);
}
$name = $saved->getParameter('name');
@@ -35,6 +37,11 @@
$query->withNameContains($name);
}
+ $types = $saved->getParameter('types');
+ if ($types) {
+ $query->withTypes($types);
+ }
+
return $query;
}
@@ -42,6 +49,12 @@
AphrontFormView $form,
PhabricatorSavedQuery $saved) {
+ $form->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel(pht('Name Contains'))
+ ->setName('name')
+ ->setValue($saved->getParameter('name')));
+
$all_types = array();
foreach (DivinerAtom::getAllTypes() as $type) {
$all_types[$type] = DivinerAtom::getAtomTypeNameString($type);
@@ -59,14 +72,14 @@
$name,
isset($types[$type]));
}
-
- $form
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Name Contains'))
- ->setName('name')
- ->setValue($saved->getParameter('name')))
- ->appendChild($type_control);
+ $form->appendChild($type_control);
+
+ $form->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setLabel(pht('Repositories'))
+ ->setName('repositoryPHIDs')
+ ->setDatasource(new DiffusionRepositoryDatasource())
+ ->setValue($saved->getParameter('repositoryPHIDs')));
}
protected function getURI($path) {
diff --git a/src/applications/diviner/query/DivinerBookQuery.php b/src/applications/diviner/query/DivinerBookQuery.php
--- a/src/applications/diviner/query/DivinerBookQuery.php
+++ b/src/applications/diviner/query/DivinerBookQuery.php
@@ -5,8 +5,10 @@
private $ids;
private $phids;
private $names;
+ private $repositoryPHIDs;
private $needProjectPHIDs;
+ private $needRepositories;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -23,11 +25,21 @@
return $this;
}
+ public function withRepositoryPHIDs(array $repository_phids) {
+ $this->repositoryPHIDs = $repository_phids;
+ return $this;
+ }
+
public function needProjectPHIDs($need_phids) {
$this->needProjectPHIDs = $need_phids;
return $this;
}
+ public function needRepositories($need_repositories) {
+ $this->needRepositories = $need_repositories;
+ return $this;
+ }
+
protected function loadPage() {
$table = new DivinerLiveBook();
$conn_r = $table->establishConnection('r');
@@ -46,6 +58,31 @@
protected function didFilterPage(array $books) {
assert_instances_of($books, 'DivinerLiveBook');
+ if ($this->needRepositories) {
+ $repositories = id(new PhabricatorRepositoryQuery())
+ ->setViewer($this->getViewer())
+ ->withPHIDs(mpull($books, 'getRepositoryPHID'))
+ ->execute();
+ $repositories = mpull($repositories, null, 'getPHID');
+
+ foreach ($books as $key => $book) {
+ if ($book->getRepositoryPHID() === null) {
+ $book->attachRepository(null);
+ continue;
+ }
+
+ $repository = idx($repositories, $book->getRepositoryPHID());
+
+ if (!$repository) {
+ $this->didRejectResult($book);
+ unset($books[$key]);
+ continue;
+ }
+
+ $book->attachRepository($repository);
+ }
+ }
+
if ($this->needProjectPHIDs) {
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($books, 'getPHID'))
@@ -91,6 +128,13 @@
$this->names);
}
+ if ($this->repositoryPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'repositoryPHID IN (%Ls)',
+ $this->repositoryPHIDs);
+ }
+
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
diff --git a/src/applications/diviner/search/DivinerAtomSearchIndexer.php b/src/applications/diviner/search/DivinerAtomSearchIndexer.php
--- a/src/applications/diviner/search/DivinerAtomSearchIndexer.php
+++ b/src/applications/diviner/search/DivinerAtomSearchIndexer.php
@@ -30,6 +30,12 @@
PhabricatorTime::getNow());
$doc->addRelationship(
+ PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY,
+ $atom->getRepositoryPHID(),
+ PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
+ PhabricatorTime::getNow());
+
+ $doc->addRelationship(
$atom->getGraphHash()
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
diff --git a/src/applications/diviner/search/DivinerBookSearchIndexer.php b/src/applications/diviner/search/DivinerBookSearchIndexer.php
--- a/src/applications/diviner/search/DivinerBookSearchIndexer.php
+++ b/src/applications/diviner/search/DivinerBookSearchIndexer.php
@@ -18,6 +18,12 @@
PhabricatorSearchDocumentFieldType::FIELD_BODY,
$book->getPreface());
+ $doc->addRelationship(
+ PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY,
+ $book->getRepositoryPHID(),
+ PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
+ $book->getDateCreated());
+
$this->indexTransactions(
$doc,
new DivinerLiveBookTransactionQuery(),
diff --git a/src/applications/diviner/storage/DivinerLiveBook.php b/src/applications/diviner/storage/DivinerLiveBook.php
--- a/src/applications/diviner/storage/DivinerLiveBook.php
+++ b/src/applications/diviner/storage/DivinerLiveBook.php
@@ -8,11 +8,13 @@
PhabricatorApplicationTransactionInterface {
protected $name;
+ protected $repositoryPHID;
protected $viewPolicy;
protected $editPolicy;
protected $configurationData = array();
private $projectPHIDs = self::ATTACHABLE;
+ private $repository = self::ATTACHABLE;
protected function getConfiguration() {
return array(
@@ -22,6 +24,7 @@
),
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text64',
+ 'repositoryPHID' => 'phid?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
@@ -68,6 +71,15 @@
return idx($spec, 'name', $group);
}
+ public function attachRepository(PhabricatorRepository $repository = null) {
+ $this->repository = $repository;
+ return $this;
+ }
+
+ public function getRepository() {
+ return $this->assertAttached($this->repository);
+ }
+
public function attachProjectPHIDs(array $project_phids) {
$this->projectPHIDs = $project_phids;
return $this;
@@ -98,7 +110,7 @@
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
- return false;
+ return false;
}
public function describeAutomaticCapability($capability) {
diff --git a/src/applications/diviner/storage/DivinerLiveSymbol.php b/src/applications/diviner/storage/DivinerLiveSymbol.php
--- a/src/applications/diviner/storage/DivinerLiveSymbol.php
+++ b/src/applications/diviner/storage/DivinerLiveSymbol.php
@@ -7,6 +7,7 @@
PhabricatorDestructibleInterface {
protected $bookPHID;
+ protected $repositoryPHID;
protected $context;
protected $type;
protected $name;
@@ -22,6 +23,7 @@
protected $isDocumentable = 0;
private $book = self::ATTACHABLE;
+ private $repository = self::ATTACHABLE;
private $atom = self::ATTACHABLE;
private $extends = self::ATTACHABLE;
private $children = self::ATTACHABLE;
@@ -43,6 +45,7 @@
'summary' => 'text?',
'isDocumentable' => 'bool',
'nodeHash' => 'text64?',
+ 'repositoryPHID' => 'phid?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
@@ -94,6 +97,15 @@
return $this;
}
+ public function getRepository() {
+ return $this->assertAttached($this->repository);
+ }
+
+ public function attachRepository(PhabricatorRepository $repository = null) {
+ $this->repository = $repository;
+ return $this;
+ }
+
public function getAtom() {
return $this->assertAttached($this->atom);
}
diff --git a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php
--- a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php
+++ b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php
@@ -25,6 +25,11 @@
'help' => pht('Specify a subclass of %s.', 'DivinerPublisher'),
'default' => 'DivinerLivePublisher',
),
+ array(
+ 'name' => 'repository',
+ 'param' => 'callsign',
+ 'help' => pht('Repository that the documentation belongs to.'),
+ ),
));
}
@@ -187,6 +192,24 @@
}
$publisher = newv($publisher_class, array());
+ $callsign = $args->getArg('repository');
+ $repository = null;
+ if ($callsign) {
+ $repository = id(new PhabricatorRepositoryQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withCallsigns(array($callsign))
+ ->executeOne();
+
+ if (!$repository) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ "Repository '%s' does not exist.",
+ $callsign));
+ }
+
+ $publisher->setRepositoryPHID($repository->getPHID());
+ }
+
$this->publishDocumentation($args->getArg('clean'), $publisher);
}
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -1913,7 +1913,25 @@
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
- $this->delete();
+
+ $this->delete();
+
+ $books = id(new DivinerBookQuery())
+ ->setViewer($engine->getViewer())
+ ->withRepositoryPHIDs(array($this->getPHID()))
+ ->execute();
+ foreach ($books as $book) {
+ $engine->destroyObject($book);
+ }
+
+ $atoms = id(new DivinerAtomQuery())
+ ->setViewer($engine->getViewer())
+ ->withRepositoryPHIDs(array($this->getPHID()))
+ ->execute();
+ foreach ($atoms as $atom) {
+ $engine->destroyObject($atom);
+ }
+
$this->saveTransaction();
}

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 3, 5:43 PM (19 h, 1 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6820129
Default Alt Text
D13070.id32318.diff (19 KB)

Event Timeline