This is as much about documentation as tests, but putting here.

At the moment, it's a real pain to do documentation for hooks having to update them in CVS (I've never done this, but that's confirmation that it's a pain) - additionally, we've got an increasing number of test modules in modules/simpletest/tests - some of which implement hooks.

So here's a proposal - we create modules/simpletest/tests/hook.module - this module implements as many hooks as possible, and also provides a target for testing if there's not an appropriate target elsewhere - this gives us a few things:

1. searching for hook_foo on api.drupal.org will return documentation for hook_user instead of nothing.
2. If I add a hook, or want to change the documentation for a hook, I can patch core instead of messing with the big hooks table in CVS
3. These patches will be recognised properly by the testing bot
4. We'll have code examples of hook implementations in core which a lot of people have looked over - so we can grep core as well as/rather than contrib
5. We have a single module to patch against for miscellaneous hooks, as opposed to having to create arbitrary new modules in the simpletest directory - which could get very messy very soon.

and etc.

There's some potential for confusion here - but I think if we handled it properly, the advantages would outweight this.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

RobLoach’s picture

I like the idea of moving stuff in http://cvs.drupal.org/viewvc.py/drupal/contributions/docs/developer/ to core. Having documentation available in core is very handy, and definitely would help when visiting api.drupal.org is not an option.

drewish’s picture

The thing I like about it is that we can ensure that the documentation for hooks gets reviewed and committed and at the same as the code changes.

drewish’s picture

Wait... actually combining the two would have one big downside. The code required to check that a hook's been called for unittesting is totally not the sort of code that you'd want to show up as an example of implementing the hook.

catch’s picture

Hmm. That's a good point. Having said that, there's no reason we couldn't separate the two. We can call the simpltest specific one hook_test.module and that'd be no problem at all.

RobLoach’s picture

Status: Active » Needs review
FileSize
114.27 KB

This patch takes the hook documentation found here and sticks it in a hidden module. Not too sure where to go with the test system though. Visiting admin/build/modules doesn't display the Hook module.

sun’s picture

A certain amount of contrib modules is also implementing hooks. Instead of a hidden module in core, I'd rather like to see a unified way for including developer documentation compatible to API module. What about creating a sub-folder /hooks in each module (system for other core hooks) that contains one or multiple files?

catch’s picture

In irc, Crell suggested a module.hooks.inc - which we never actually load because module.info wouldn't specify it - and so the registry would never read it. This would allow things to show up on api.drupal.org, but I think it could be very bad DX to have a .inc that would never be loaded along with all the others that are, so I'm not convinced.

RobLoach: amaaazing, no time to look right now though, but will check it out soon.

RobLoach’s picture

Status: Needs review » Needs work
webchick’s picture

Let me preface this comment by saying +10,000 for having hook documentation in core. Moving the database schema documentation into core was one of the best things we ever did and has greatly helped to ensure that fields are a) documented at all, b) continue to be updated throughout the ages.

However, I don't like this exact approach.

a) While catch's #5 is a good point, I would prefer to find a solution that could work equally well for both core and contrib. Each module defining its own modulename.hooks.php file, or similar? Basically, see sun's #6.

b) However, the question then comes up of how to deal with hooks exposed by core include files (menu, file, etc.)? Blah.

c) I'm a little leery of using module.hook.inc, because module.*.inc is generally used for page-splitting patches and people might get confused that that's where you need to put your "implementation of X" in there. I'd prefer a clearly different naming convention altogether.

d) I prefer precision tests, such as the file and db tests, over a gigantic hook.test trying to test every nuance of every hook. Maybe I misunderstood that point.

catch’s picture

We could have a hook.hook_name/group.test for each hook - but have them all attached to hook.module Would keep things granular. The main things with hook.module is it never gets loaded anywhere except by simpletest - I'm not sure how we'd handle that with the .incs.

moshe weitzman’s picture

What about having each module ship with an api.php in its directory. Its only purpose is for api.module to scan it. That's more modular than a single hooks module and applies equally well for contrib.

webchick’s picture

I like that idea. But will API module choke on multiple files named the same thing?

webchick’s picture

I guess if it will, we could always just fix API module. ;)

catch’s picture

api.php sounds good, and is much more self documenting than module.hook.inc which was always going to confuse people.

webchick’s picture

Ok. Let's do it!

api.php in each module directory. Misc. crap in the includes directory gets put into modules/system/api.php.

GO! :)

catch’s picture

Title: Add a hook.module to core » Add api.php for every core module
RobLoach’s picture

In some contrib modules (like Views), there are multiple modules that live in the same directory. Does this mean that the api.php would include the API for all the modules in that directory? If we used modulename.api.php, then the hooks for each module in that directory could be defined all in separate files.

Will SimpleTest call these hooks during tests?

moshe weitzman’s picture

IIRC you can't have multiple modules in same directory after the registry patch. I might be remembering wrong. i'm fine with modulename.api.php (or .inc?) if needed

webchick’s picture

That Views question is interesting. Especially when you consider something like Ubercart with 50,000 sub-modules or so.

I'm starting to now lean in the other direction: A single 'hooks.php' in the root of the 'project' with /** @defgroups **/ as makes sense, with ALL of the hooks defined by that project, regardless of where they live. That's better from a DX perspective as I don't need to go traipsing through directories to get a big picture of what a thing does. It also makes this patch much easier to roll. :)

So in core, we could have @defgroup Core, Node, etc.

Views might have @defgroup View styles, View plugins, View yo momma

Does that make sense?

dman’s picture

Surely modulename.api.php is more consistent with modulename.module, modulename.info, modulename.install

webchick’s picture

Sure, I'm not too fussed about the name (other than it should not be .inc, because it's never being included anywhere). I'm more interested in whether the approach is sound.

pwolanin’s picture

if I were developing many sub-modules, I'd want the ?.api.php file to be grouped with each module - anything else would seem like a nightmare to track and fix.

moshe weitzman’s picture

Yes, one api.module in each module subdirectory. If you aren't dividing your modules into subdirectories in a project, you are not following best practices and we need not specify an api.php convention for this.

sun’s picture

I am right now in the situation of having to document Wysiwyg API. My considerations and reasoning:

First, I placed a file api.php in the module folder.
That looked at bit lost, because all other files in the folder are prefixed with the name of a module.
Renamed to wysiwyg.api.php.
Makes more sense and is more consistent now.

Also, I can see modules like Views or eCommerce that provide so many API hooks that a single file would be cumbersome.
Sure, the best practice is to have sub-modules in sub-folders.
But then again, look at Views and Views UI, both being in the module's root folder. Both may or may not provide API hooks.
Usually, core avoids too strict rules where they are not required.
If we simply define a standard like module.api.php, systems like API module or SimpleTest can search for a certain filename pattern, regardless of the file's location.
So if we would want to place all core API documentation in one folder, we could do so; i.e. node.api.php, user.api.php, etc.
The same for contrib modules.
However, we could also place node.api.php in modules/node/ - what matters is just the filename.

Hence, +1 for <module>.api.php

In the end I think that drumm should have the final word on this.

drewish’s picture

i'm in agreement with sun's reasoning in #24.

RobLoach’s picture

Where will the core hooks go that are not associated with a module? In modules/system/system.api.php? includes/api.php?

RobLoach’s picture

Status: Needs work » Needs review
FileSize
132.92 KB

I went through the hook documentation and attempted to move all the hooks to their designated module.api.php. I also placed a includes/api.php for hooks that are not quite associated to any module. Some of api.php might belong in system.api.php, however.

RobLoach’s picture

As discussed on IRC with webchick, tha_sun and add1sun, we decided to move all of includes/api.php to modules/system/system.api.php.

RobLoach’s picture

FileSize
132.99 KB

Forgot the patch....

RobLoach’s picture

FileSize
132.99 KB

Some of the descriptions were incorrect....

sun’s picture

Status: Needs review » Needs work

We can simplify this to "Hooks provided by Xyz module.":

+/**
+ * @file
+ * These are the hooks that are invoked by the Locale module.
+ */

Probably all of those are not required and can be removed:

+/**
+ * @} End of "addtogroup hooks".
+ */

hook_hook_info() in system.api.php belongs into trigger.api.php, I guess.
hook_update_index() in system.api.php belongs into search.api.php, I guess.

There are 2 @file definitions in node.api.php.

EDIT: Oh, and did I say: AWESOME! ? ;)

catch’s picture

hook_hook_info() - isn't this provided by core actions, which are independent of trigger?

hook_update_index() should be search though yeah.

webchick’s picture

Title: Add api.php for every core module » UNSTABLE-4 blocker: Add api.php for every core module

I'd like to get this in in UNSTABLE-4. It's starting to get annoying tracking all the various follow-up issues and request for documentation after the fact for new/modified hooks.

dmitrig01’s picture

Title: UNSTABLE-4 blocker: Add api.php for every core module » Add api.php for every core module

also nodeapi is now out of date

dmitrig01’s picture

Title: Add api.php for every core module » UNSTABLE-4 blocker: Add api.php for every core module

sorry for title change

drewish’s picture

Status: Needs work » Needs review
FileSize
132.89 KB

Updated this a bit:

  • Updated to grab the latest changes to the docs: addition of hook_js_alter() and hook_taxonomy broken out by op, and REQUEST_TIME.
  • Moved hook_update_index() to search.api.php.
  • Moved hook_hook_info() to trigger.api.php because it sure looks like trigger is the primary consumer of that info and all the actions hooks are in there.
  • "These are the hooks that are invoked by the Xyz module." -> "Hooks provided by Xyz module."

Didn't mess with the hook_nodeapi docs at this point.

catch’s picture

Status: Needs review » Reviewed & tested by the community

Different bits of hook_nodeapi are in line for slicing by at least three patches at the moment - so let's fix that once it's in core so as not to hold this up - will have to patch them for the forthcoming API changes anyway, at worst we fix it at the same time then. And this saves docs getting out of date ever again.

Patch applies and passes tests, so I'm going to RTBC this.

webchick’s picture

+/**
+ * @file
+ * These hooks are defined by node modules, modules that define a new kind
+ * of node.
+ *
+ * If you don't need to make a new node type but rather extend the existing
+ * ones, you should instead investigate using hook_nodeapi().
+ *
+ * Node hooks are typically called by node.module using node_invoke().
+ */
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+

that extra hunk should be taken out... was a remnant of when node hooks were in hooks/node.php instead.

drewish’s picture

FileSize
136.86 KB

here's a re-roll without the wierd @file chunk in the middle of node.api.php.

RobLoach’s picture

Thanks a lot, Drewish. Looks great! RTBC * 2.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

Awesome. Apart from some desperately needed clean-up we have left in some of this documentation, this looks really great, and will ensure that all future hook changes and additions aren't committed until they update the API documentation. It will also help people frequently on planes who don't keep a checkout of contributions/docs/developer/hooks with them.

Committed to HEAD. Thanks! :D

We need some upgrade documentation, please.

Dave Reid’s picture

I don't understand why there are changes to system.test and system.module in this patch that was committed... It is related to temporary file cleanup and not related to apis at all.

drewish’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
4.53 KB

That was my bad... I'd accidentally rolled #330633: Temporary file cleanup needs some love (UnitTest included!) in.

Here's a reversal of http://cdn1.drupal.org/files/issues/file_330633_2.patch which should do the trick.

RobLoach’s picture

Yup! Dave Reid has ninja eyes that are better then both webchick's crazy eagle eyes and my lack-of-coffee eyes.

Damien Tournoud’s picture

Priority: Normal » Critical

Bumped to critical: the code that sneaked in broke PostgreSQL installation with message:

PDOException: SELECT fid FROM {files} WHERE status & :permanent != :permanent AND timestamp < :timestamp - Array ( [:permanent] => 1 [:timestamp] => 1227604875 ) SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $2 in system_cron() (line 1511 of /var/www/drupal/revamp/modules/system/system.module).
Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

RobLoach’s picture

Component: tests » documentation
Dave Reid’s picture

Should we delete all the files in the contributions/docs/developer/hooks/ now?

drewish’s picture

I think it'd be a good idea since api.drupal.org is using the new .api.php files: http://api.drupal.org/api/group/node_access/7

Dave Reid’s picture

I removed all the files from the directory. If we notice missing documentation once api.drupal.org regenerates, we'll have to file separate issue to put it in our new core api.php files!

Status: Fixed » Closed (fixed)

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