Some of the changes that involves interaction with backends at display time use to be not so clean, for example #976136-12: Let backends overwrite revision field output on views using backend class. And will be useful for things like #988512-4: Properly track git's user.email and user.name as separate, first-class properties.

So we need to let backends to alter views in a cleaner way.

Comments

sdboyer’s picture

OK, here's my mini-manifesto.

When tizzo and I originally discussed this, we talked about having 'slots' for views, and the backends would override at the level of the slot. That made a lot of sense for the one view we were dealing with at that time - the administrative repository listings view, for which it is inherently guaranteed that only a single backend's data will be shown in the view (that was the whole goal of that particular bit of work, actually - see #854926: Replace admin/project/versioncontrol-repositories/list with Views-driven UI).

When I first started reflecting on this, it seemed to me that the system we'd built was actually too specific to that initial case. Certainly, the scenario it was serving is different - we were using it to build administrative repository listings, knowing that we'd use each backend's listing, and that we'd know the backend going in to retrieving the view. Even per-repository listings (inherently single-backend) aren't quite the same: the requestor isn't specifying anything about the backend they want, only the repository they want a listing from. So the backend is derived, rather than explicit.

There is a common thread, though - the notion of the view 'slot' has a lot of value. In terms of architectural patterns, we need a decorator - a container that looks like a view to client code, but introduces a layer of indirection that fetches an actual view based on some input data. Implementation-wise, we can't do anything like that, but that's the principle we need to shoot for. This doesn't require too much new from a code perspective for our current use cases, but it's very important for the long term as we think about offering up blocks/ctools content types with VCAPI content - there needs to be some sort of UI that people use to pick the view set wrapper, rather than picking a literal view, so that all of our backend-specific view-switching logic can be run.

That's the high level, but let's get a little more concrete. There are three basic types of extension that we need to do:

  1. Backend-specific handling of shared fields (e.g., git's specific needs vs. the generic handler for #970244: Create a views handler to map operation author/committer to their drupal user)
  2. Backends wanting to add non-shared fields to the view. (e.g., git has a 'parent commit' that we'll want to roll into its views.)
  3. Third-party code wanting to add fields to the view. (e.g., versioncontrol_project wanting to show the human-readable project name instead of VCAPI's internal name for a repository).

Of the three, the first is by far the most complicated. The complication arises from the fact that we need to have a mechanism for consulting the corresponding backend for the row result that's being processed, which means such field handlers need to act as passthroughs - ick. Plus, we need to figure out which backend to call for each row.

The other two are taken care of quite nicely by a view set system. The second doesn't take any conceptual leaps to get to - we do it right now with the admin repositories listing view. The third will take a little elbow grease from where the code base is right now, though. The easiest way to let third-party code add fields to the view is to take view sets out of literal strings in code, and replace them with a hookable, UI-driven system. Any module can register a view set via a hook (which will basically just be reserving a string namespace). Default views can be specified (either by the creator of the set, or by the backends, if appropriate), but the key will be a global administrative UI where site admins click-together the views each backend should use for each set. Ultimately this means that we can have base/default views provided by the system, but there's a single interface in which the site administrator can control which actual views should be used in different situations. And it's all exportable.

Wow, on re-reading that, it seems very difficult to follow. I'll just code it up and show the UI, then it'll make more sense.

marvil07’s picture

Wow, on re-reading that, it seems very difficult to follow. I'll just code it up and show the UI, then it'll make more sense.

sdboyer++

marvil07’s picture

grrr dup :-(

sdboyer’s picture

Issue tags: +git sprint 6

Somehow, this didn't get tagged...

sdboyer’s picture

OK, I finally have this most of the way done. Here's a shot of the admin UI I've built:

Only local images are allowed.

I'm hoping the workflow suggested there will clarify most of what I have in mind for this. What remains to be done:

  • I haven't written any of the submit handler for this form (which does all the db insertions).
  • Need to let views set owners specify defaults to be used for backends, as a convenience. This is a small thing.
  • The description under the 'use default' checkbox is currently static, and needs to be made dynamic (per what I wrote on the skitch)
  • The ahahification of the views select list noted on the skitch

Comment quick, cuz I'm gonna commit this as soon as it's done :)

sdboyer’s picture

StatusFileSize
new13.19 KB

Oh yeah. And a patch. :)

marvil07’s picture

Status: Active » Needs work

The patch looks good.

I only have one concern: why is it possible to overwrite views that we can not guarantee are backend specific?

I mean: Global commit log and Per-user commit log views can have more than one backend active, so it really do not make sense to have this configuration, unless we show separately each backend(as repo admin does).

Maybe I am missing something :-p

sdboyer’s picture

Status: Needs work » Needs review
StatusFileSize
new16.45 KB

OK, updated patch. This thing is pretty much ready, but I'm gonna let it percolate in my head while I eat dinner.

marvil07’s picture

Assigned: Unassigned » sdboyer
Status: Needs review » Needs work
+++ includes/VersioncontrolBackend.php
@@ -182,22 +177,24 @@ abstract class VersioncontrolBackend {
+    return empty($set[$this->type]) ? $set['base'] : $set[$this->type];

I am getting one warning per backend here.

+++ versioncontrol.admin.inc
@@ -82,6 +82,152 @@ function versioncontrol_admin_settings_submit($form, &$form_state) {
+  if ($do_insert) {

Please initialize $do_insert as FALSE to avoid a warning.

I do not still really understand how my question in #7 is answered in the last patch :-/

Powered by Dreditor.

sdboyer’s picture

Assigned: sdboyer » Unassigned
Status: Needs work » Needs review

You get the warning per backend because there's an accompanying change that has to be made to backends - they need to specify their machine-name string as VersioncontrolBackend::$type. I've added a default empty string to VersioncontrolBackend that might help with it, but it really requires the backends to catch up.

As to your question in #7 - I'm not 100% sure what you're referring to, but I think it's the global commit view, or per-author commit view, which both have the the potential to interleave commits from different backends together. Yep, my initial thought was that those should be excluded from this system, as they should always use the generic view.

...except in the quite common case where you only have one backend installed. We've already got the same kind of logic in the controllers, and this is another ideal case for it.

Truth is that this whole system probably needs a better fetcher for the views, probably one that can take a VersioncontrolEntity object + a view set name as an argument, and return a view name. But we can add that later if it really becomes necessary.

Any other issues, before I commit?

marvil07’s picture

Status: Needs review » Needs work

You get the warning per backend because there's an accompanying change that has to be made to backends - they need to specify their machine-name string as VersioncontrolBackend::$type. I've added a default empty string to VersioncontrolBackend that might help with it, but it really requires the backends to catch up.

Ok, then at least the test backend must have it working correctly. And also we need to add $type data member to the VersioncontrolBackend class with some documentation.

As to your question in #7 - I'm not 100% sure what you're referring to, but I think it's the global commit view, or per-author commit view, which both have the the potential to interleave commits from different backends together. Yep, my initial thought was that those should be excluded from this system, as they should always use the generic view.

...except in the quite common case where you only have one backend installed. We've already got the same kind of logic in the controllers, and this is another ideal case for it.

You got it right. So the real thing to do here probably will be providing a different UI if we have more than one backend active(avoid those two views, maybe by adding one more field to the view set to indicate if it is backend specific or not).

Any other issues, before I commit?

+++ versioncontrol.admin.inc
@@ -82,6 +82,152 @@ function versioncontrol_admin_settings_submit($form, &$form_state) {
+  if ($do_insert) {

Please initialize $do_insert as FALSE to avoid a warning.

Still need one line change.

PS: maybe a missing patch at #10?

sdboyer’s picture

Yes, I didn't include a patch, but fixed locally - I was expecting to just commit. But patch attached - it fixes the tests, the $do_insert, and adding the property to VersioncontrolBackend.

I don't really understand this, or where the benefit is above the simpler, unified, and adequate system I've written here:

You got it right. So the real thing to do here probably will be providing a different UI if we have more than one backend active(avoid those two views, maybe by adding one more field to the view set to indicate if it is backend specific or not).

But I want to talk about it in IRC, because I don't want to waste time waiting for responses at this late hour.

sdboyer’s picture

StatusFileSize
new17.3 KB

Damn, forgot the patch.

sdboyer’s picture

Double-damn. Really need to add some more to this to handle the argument, custom mapping process...basically, this:

Truth is that this whole system probably needs a better fetcher for the views, probably one that can take a VersioncontrolEntity object + a view set name as an argument, and return a view name. But we can add that later if it really becomes necessary.

Which means another ctools plugin. Gonna rejigger this.

sdboyer’s picture

Status: Needs work » Needs review
StatusFileSize
new25.32 KB

OK, rejiggered to make views sets into ctools plugins. It's pretty lacking in docs, but I wanted to get the code up. Seems to be working from my quick tests.

sdboyer’s picture

StatusFileSize
new25.65 KB

Ugh, forgot to update the admin repositories listing to the new system. Patch in #15 is no good, use this one.

eliza411’s picture

Issue tags: +git sprint 7

Tagging for Git Sprint 7.

sdboyer’s picture

Status: Needs review » Fixed

GAH no, this is ready to commit. I just kept on neglecting to do it before. It's in.

sdboyer’s picture

Issue tags: -git sprint 7

removing sprint 7 tag, this was done sprint 6.

Status: Fixed » Closed (fixed)
Issue tags: -git phase 2, -git sprint 6

Automatically closed -- issue fixed for 2 weeks with no activity.

  • Commit 7bf3cad on repository-families, drush-vc-sync-unlock by sdboyer:
    Issue #990644: improve backend interaction with Views by introducing...

  • Commit 7bf3cad on repository-families by sdboyer:
    Issue #990644: improve backend interaction with Views by introducing...