The original plan:
Following OOP aproach, the versioncontrol submodules, like commitlog, could be converted to interfaces, that the backend could implement.
The wiki plan:
Conversion to interfaces(July 17th - July 26th)
* make backend capabilities interfaces
* convert commitlog class interaction to an interface where it's applicable(commitlog have lots of code that will remain on module file)
Nor the first plan, neither the updated fit on what we have on vc api. So, I tried to list here all the points where we would want to take a look before think on interfaces.
backend capabilities array(VERSIONCONTROL_CAPABILITY_*)
// Able to retrieve a file or its revision number based on a global
// revision identifier.
VERSIONCONTROL_CAPABILITY_ATOMIC_COMMITS
- on Item::fetchCommitOperations, let fetch by revision id instead of fetch by operation/item association
- on commitlog theme_commitlog_item, let display the revision next to the path on backends with no atomic commits
// Able to cancel commits if the committer lacks permissions
// to commit to specific paths and/or branches.
VERSIONCONTROL_CAPABILITY_COMMIT_RESTRICTIONS
- on commit_restrictions versioncontrol-repository-form alter, show allowed_paths textfield, deny_undefined_paths checkbox and forbidden_paths textfield; so then on repo
hook_versioncontrol_repository_submit()values can be retrieved and set. Those values are used to implementhook_versioncontrol_write_access().
// Able to cancel branch or tag assignments if the committer lacks
// permissions to create/update/delete those.
VERSIONCONTROL_CAPABILITY_BRANCH_TAG_RESTRICTIONS
- on commit_restrictions versioncontrol-repository-form alter, show valid_branch_tag_paths, valid_branches and valid_tags textfields and process them on
hook_versioncontrol_repository_submit(), called also fromhook_versioncontrol_write_access()likeVERSIONCONTROL_CAPABILITY_COMMIT_RESTRICTIONSworkflow.
// The version control system assigns revisions not only to files
// but also to directories.
VERSIONCONTROL_CAPABILITY_DIRECTORY_REVISIONS
- on
Item::getParentItemto either assign or not a revision to the new parent item object
backend flags array
// versioncontrol_insert_repository() will automatically insert
// array elements from $repository['[xxx]_specific'] into
// {versioncontrol_[xxx]_repositories} and versioncontrol_get_repositories()
// will automatically fetch it from there.
// (Deprecated, to be replaced by $repository['data'][$module].)
VERSIONCONTROL_FLAG_AUTOADD_REPOSITORIES,
- on repository _amend_repositories(called from getter), update, insert and delete to manage the own vcs specific repository table; but this is going to disappear with the $repository['data'][$module] like it's mentioned
versioncontrol_backend_implements/_versioncontrol_call_backend
versioncontrol_backend_implements, from its definition: Determine if a given backend module implements a specific backend function.
The function looks like 'versioncontrol_'. $vcs .'_'. $function
- import_accounts / export_accounts
- on
hook_menuto either define or notadmin/project/versioncontrol-accounts/[import|export|export/%versioncontrol_repository] - on
versioncontrol_admin_account_import_formto filter the backends that can be imported - on
versioncontrol_admin_account_export_pageto verify is repository passed can export - on
versioncontrol_admin_account_export_formto filter the backends that can be exported
- on
- format_revision_identifier
- on
versioncontrol_format_revision_identifierto return a simple $revision string or some formated-by-the-backend string(ex. 7-chars cut SHA1 instead of complete 64-char on git backend)
- on
- operation
- on
operation::insert, actually after main values are on DB, to notify actual backend before all other modules - on
operation::delete, just before read operation delete, let backend delete its own stuff
- on
- alter_repositories
- on
repository::_amend_repositories(called from getter), let add own backend stuff to the repos
- on
- repository
- on repository update, insert and delete, let the backend manage its own stuff to the repos
- account_username_suggestion
- on
account::usernameSuggestionto get, if possible a backend aligned username; now depends on repository, but maybe it can be changed to depends on the backend
- on
- is_account_username_valid
- on
account::isUsernameValidto get, if possible, a backend desition about username validity
- on
- account
- on account update, insert and delete, to let the backend to manage its own stuff about accout data
On item class, getParallelItems(get_parallel_items), getDirectoryContents(get_directory_contents), exportFile(export_file), exportDirectory(export_directory), getFileAnnotation(get_file_annotation) there is a direct callback(no versioncontrol_backend_implements verification, so it should be before the call)
Propose
So, here my intial propose:
- all
VERSIONCONTROL_CAPABILITies are used in a way that anyone of them need a function/method behind, they only change how VC API(who _know how to deal all cases_) is gonna use the backend; so it makes no sense to convert it into interfaces - there is only one vc flag,
VERSIONCONTROL_FLAG_AUTOADD_REPOSITORIES, and it's used to manage own backend repo table; so it makes no sense to convert to an interface - import and export vc callbacks could be repository class interfaces
- format_revision_identifier, is_account_username_valid and account_username_suggestion vc callbacks can be converted on threee backend class interfaces
- operation, account and repository vc callbacks can be converted in three operation, account and repository class interfaces; but here I think it's more natural to convert that callbacks on unimplemented methods on operation and repository classes.. in that way for example git backend would implement a
VersioncontrolGitRepository::[insert|update|delete]if needed - alter_repositories vc callbak can also be an unimplemented method on repository class
- not sure about direct callbacks on item class, one interface in the class per feature seems like too much, but they seems also independent; so guide me here please :-p
Comments
Comment #1
sdboyer commentedLemme first note that it was my mistake before to suggest that capabilities == interfaces. That's just too much of a generalization. It would be quite a stretch to make
VERSIONCONTROL_CAPABILITY_ATOMIC_COMMITS, for example, handle all of its differences simply by adding methods. It's the wrong approach because, as you point out, the capabilities information is about changing logic in how the API runs, often outside the scope of any particular method we might be able to place on a backend-specific object.There's another way in which interfaces are wrong, as you've pointed out. While commit atomicity is a clear case of something that cannot be elegantly expressed via interfaces, inheritance, or any other OO goodness,
VERSIONCONTROL_FLAG_AUTOADD_REPOSITORIESis a great example of something that should (and with my recent changes, already has) go away, as the role it plays can be managed entirely by class inheritance. And still no need for interfaces.While I can see a way that we might use interfaces to handle commit restrictions, it may well be more trouble than it's worth. So at this point, I think I'm going to back off my original advocacy for using interfaces all over the place, and suggest that we continue to proceed as we have thus far - continue porting stuff over to OO, and handle the potential to use interfaces on a case-by-case basis. So, wrt to that, I'll address your bullets one by one:
method_exists(). If, however, the presence/absence of that interface has bearing on the behavior of external code in some way that's larger than whether or not one of the interface's methods get called, it probably does deserve to be an interface.Let's keep on chuggin!
Comment #2
marvil07 commentedwooo
following the bullet answers :-D (yep, I'm happy because I have one solution working) .. please take a look at my github oop branch ;-)
- getParallelItems(get_parallel_items), getDirectoryContents(get_directory_contents), exportFile(export_file), exportDirectory(export_directory), getFileAnnotation(get_file_annotation) are now interfaces because each vcs may implement it differently and they are all optional.
Comment #3
marvil07 commentedmarking this as fixed as pending work in on #595930: from github to d.o cvs(aka start 6.x-2.0-dev and get access)