Page MenuHomePhabricator

Modernize Diviner
ClosedPublic

Authored by joshuaspence on Jun 1 2015, 1:35 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Apr 25, 12:44 AM
Unknown Object (File)
Fri, Apr 19, 2:19 AM
Unknown Object (File)
Wed, Apr 17, 6:49 PM
Unknown Object (File)
Wed, Apr 3, 10:56 PM
Unknown Object (File)
Mar 22 2024, 4:34 AM
Unknown Object (File)
Mar 19 2024, 1:40 AM
Unknown Object (File)
Mar 18 2024, 7:38 AM
Unknown Object (File)
Mar 5 2024, 9:17 AM
Subscribers

Details

Reviewers
epriestley
Group Reviewers
Blessed Reviewers
Maniphest Tasks
T4558: Make Diviner useful for third-parties
Commits
Restricted Diffusion Commit
rP6b7d7401ca6d: Modernize Diviner
Summary

Ref T4558. This diff modernizes the Diviner application. Basically:

  • Add an edit controller, accessible at /book/$BOOK/edit/.
  • Add edit/view policies.
  • Added an action menu to the DivinerBookController to expose the edit interface.
  • Allows projects to be associated with books.
  • Implement edges and transactions.
  • Implemented PhabricatorApplicationTransactionInterface in DivinerLiveBook.
Test Plan
  • Generated a Diviner book with ./bin/diviner generate.
  • Added projects to a book and ensured that they persisted.
  • Changed the view policy on a book and made sure it was effective.

Diff Detail

Repository
rP Phabricator
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

I mean that in Differential, the implicit policy ("when a revision belongs to a repository, you must be able to see the repository in order to see the revision") ends up pretty much covering every case on its own, without much need for additional policy rules. For example, there's no arc diff --view-policy X and no one has asked us for it, at least so far. We do have a default view policy in Differential, but I'm not sure we actually need it (I think I just added them to a bunch of apps all at once a while back).

It's possible that almost every Diviner book is generated from a repository, and a similar implicit policy is sufficient in the overwhelming majority of cases.

(I think this is fine to have, regardless.)

At some point relatively soon-ish there should probably be an "Edit Book" option to let you set policies/projects from the web UI explicitly.

joshuaspence edited edge metadata.

Add a whole bunch of stuff

joshuaspence retitled this revision from Add policy support to Diviner to Modernize Diviner.Jun 1 2015, 8:25 AM
joshuaspence updated this object.

Couple of minor inlines, things look good so far.

resources/sql/autopatches/20150601.divineredit.sql
6 ↗(On Diff #31607)

Since editPolicy is not nullable, this should probably be WHERE editPolicy = ''.

src/applications/diviner/controller/DivinerBookEditController.php
12

In modern Controllers, prefer to implement handleRequest() instead and access URI data with $request->getURIData('book').

(This is just trying to clean up all the willProcessRequest() stubs which rarely/never do anything useful.)

14

Prefer $viewer = $this->getViewer() too.

87

(This seems unusual?)

Implement PhabricatorApplicationTransactionInterface

Implement view/edit policies per book

joshuaspence edited the test plan for this revision. (Show Details)
joshuaspence added a reviewer: epriestley.

Set edit policy when creating a new book

Remove useless overriding methods

Disable the "Edit Book" button for users without edit permissions

joshuaspence marked 3 inline comments as done.

Implement handleRequest()

src/applications/diviner/controller/DivinerBookEditController.php
88

How so?

Index DivinerLiveBook transactions for the search index

A couple of things that I couldn't immediately work out that are maybe useful here:

  • Is there any need to implement DivinerBookPHIDType::loadNamedObjects()? I couldn't work out how this was used.
  • I wasn't sure if there was any reason to implement DivinerBookPHIDType::getPHIDTypeApplicationClass.
  • I wasn't sure of the difference between URI data and request data in AphrontRequest. For example, getURIData vs getStr.
  • Is there any need to implement DivinerBookPHIDType::loadNamedObjects()? I couldn't work out how this was used.

You don't need to implement this. It's used when you, e.g., type bin/remove destroy OBJECT to figure out what "OBJECT" means, but books don't have a monogram/object name.

  • I wasn't sure if there was any reason to implement DivinerBookPHIDType::getPHIDTypeApplicationClass.

One thing it does is gets a better icon for objects of that type in feed and typeaheads, if the type doesn't specify an icon explicitly (we can fall back to the application icon).

  • I wasn't sure of the difference between URI data and request data in AphrontRequest. For example, getURIData vs getStr.

getURIData() reads out of the route. getStr() reads out of the request parameters. For example, if you have this route:

/diviner/(?P<action>\w+)/

And load this page:

/diviner/eat/?action=drink

You'll get these values:

$request->getURIData('action'); // eat
$request->getStr('action');     // drink
joshuaspence edited edge metadata.
  • Add some translations
  • Fix atom controller
src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
1182–1185

Not sure if this is possible, but the if second parameter is singular then this should read "... but only %s is documented".

src/applications/diviner/workflow/DivinerGenerateWorkflow.php
67

Interestingly, with one book this is rendering as "Found 1 books."

  • Minor tidying
  • Call didRejectResult() in DivinerAtomQuery
src/applications/diviner/controller/DivinerBookController.php
126

I feel like this gets repeated alot... maybe this should be a method on DivinerLiveBook?

epriestley edited edge metadata.

Handful of minor inlines.

src/applications/diviner/application/PhabricatorDivinerApplication.php
58–61

Add 'template' with the PHID type for "default X capability" after T5681 / D13251. This will provide a hint about object policies which are suitable for selection in this control (this is mostly groundwork for future changes, it will have no real effect today). Something like:

'template' => DivinerLiveBookPHIDType::TYPECONST,
src/applications/diviner/controller/DivinerAtomController.php
324

Per discussion elsewhere, consider not making this or other alignment changes.

src/applications/diviner/controller/DivinerAtomListController.php
10

I wrote this weird; it should have no default (so it defaults to null), which will make the SearchEngine choose the user's first search query. As written, I'd expect this to not work correctly if you reorder saved search queries.

src/applications/diviner/controller/DivinerBookEditController.php
20–21

Should have a if !$book return 404.

22

Should have a trailing slash.

24

Oh, the 404 is here -- but needs to be above $book->getName(), or we'll fatal before we get here.

89

The "unusual" thing was the random divider control at the bottom of the form.

src/applications/diviner/publisher/DivinerLivePublisher.php
16–20

Given that we define default policies, I'd expect this to be something like DivinerLiveBook::initializeNewBook() and set the defaults, now.

src/applications/diviner/search/DivinerBookSearchIndexer.php
21–24

(I think this is automatic if you implement ApplicationTransactionInterface?)

src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
1128

Omit one level of array() to fix 1 books.

1134

Omit 1 level of array(), etc, etc.

1182–1185

Broadly, each level of array() depth corresponds to a parameter. So if you have no parameters, you have no arrays:

'apple' => 'le appelo',

If you have one parameter, you should have maximum depth of one array:

'%s apple(s)' => array(
  'an apple',
  'apples',
)

(Not two arrays, as some of the cases above do.)

If you have two parameters, you'll have a depth of two arrays, and the inner arrays will handle the second parameter:

'%s apple(s) and %s banana(s)' => array(
  array(...), // Cases with 1 apple
  array(...), // Cases with some other number of apples
);

So I'd expect these to produce the correct behavior -- one conversion, maximum depth is one array:

'You have %s apple(s).' => array(
  'You have an apple.',
  'You have %s apples.',
);

Two conversions, maximum depth is two arrays:

'You have %s apple(s) and %s banana(s).' => array(
  array(
    'You have an apple and a banana.',
    'You have an apples and %2$s bananas.',
  ),
  array(
    'You have %s apples and a banana.',
    'You have %s apples and %s bananas.',
  ),
);
This revision is now accepted and ready to land.Jun 16 2015, 2:34 PM
src/applications/diviner/controller/DivinerAtomController.php
324

Yeah sorry... got a bit carried away.

joshuaspence marked 15 inline comments as done.
joshuaspence edited edge metadata.
  • Add templates for custom capabilities
  • Remove a bunch of alignment changes
  • Remove default query from atom list controller
  • Throw a 404 if no such book is found
  • Fix $view_uri
  • Fix translation strings
src/applications/diviner/controller/DivinerBookEditController.php
89

Ah right... the inline comment doesn't line up anymore. Yeah, the divider has been removed now.

src/applications/diviner/search/DivinerBookSearchIndexer.php
21–24

I think that it should be, but it doesn't seem to be.

This revision was automatically updated to reflect the committed changes.