Just ran into a PHP Fatal error: Cannot redeclare registry_rebuild_drush_command() because a site I was working on had registry_rebuild in sites/all/modules/contrib/registry_rebuild.

We should be able to know at that point that we've already loaded that extension and not try to reload it.

Comments

greg.1.anderson’s picture

Didn't double-check, but I believe that Drush already caches commandfile names, and won't load two with the same name. Do you have the same copy of registry_rebuild in both locations, and if not, do they have the same *.drush.inc filenames?

nerdcore’s picture

I have a similar issue, resulting from the colorbox module having been installed in a 'sites/all/modules/...' folder and again in 'profiles/.../modules/optional/...'.

The errors presented are:

Drush command terminated abnormally due to an unrecoverable error.
Error: Cannot redeclare colorbox_drush_command() (previously declared in
[...]/sites/all/modules/contrib/colorbox/drush/colorbox.drush.inc:29) in
[...]/profiles/[...]/modules/optional/colorbox/drush/colorbox.drush.inc, line 43

I apologize in advance if this is not a good place to bring this up, but it seems along the same topic to me.

joelcollinsdc’s picture

Version: » 7.x-5.8

We also have the same problem as above. Drush can't operate with the same module in sites/[site-name] and profiles/blah. This worked fine in drush 4.

mokitger’s picture

When you have multiple profiles, the same problem occurs. We have 4 different profiles and they all use the ctools-module.

Error: Cannot redeclare ctools_drush_command() (previously declared in
profiles/profile1/modules/contrib/ctools/drush/ctools.drush.inc:12) in
profiles/profile2/modules/contrib/ctools/drush/ctools.drush.inc, line 134

When running "drush cc all" before running "drush updb" this error doesn't appear.

greg.1.anderson’s picture

Version: 7.x-5.8 » 8.x-6.x-dev
Priority: Major » Critical

Here is the relevant code from _drush_add_commandfiles() in includes/command.inc:

          foreach ($files as $filename => $info) {
            $module = basename($filename);
            $module = preg_replace('/\.*drush[0-9]*\.inc/', '', $module);
            // Only try to bootstrap modules that we have never seen before, or that we
            // have tried to load but did not due to an unmet _drush_load() requirement.
            if (!array_key_exists($module, $evaluated) && file_exists($filename)) {
              $evaluated[$module] = TRUE;
              $list[$module] = $filename;
            }
          }

In theory, a module has to make it onto $list in order to be loaded. In theory, $evaluated is static, so it should not matter which phase of the bootstrap the file is being loaded from. In thoery, the module's basename is put into $module, so modules with the same name but different paths should still be recognized as "the same module".

If someone has time and inclination to investigate, it would be helpful to verify which of these theories are true, and which are false. In theory, it should be one of these things going wrong that is causing the observed symptoms in #4 & c.

Please test with latest dev.

greg.1.anderson’s picture

Priority: Critical » Normal

I was just thinking about the comment in #4. It seems that what is going on is that commandfiles that are found because they are in the cache do not populate the static '$evaluated' array. Therefore, if you are happily using profiles/profile1/modules/contrib/ctools/drush/ctools.drush.inc, and you then introduce profiles/profile2/modules/contrib/ctools/drush/ctools.drush.inc without running drush cc drush (n.b.: drush dl will clear the drush cache), then you will have problems.

While it might be possible to reconstruct $evaluated when adding new files, perhaps this is counter to the expected behavior of a cache, and perhaps this code now 'behaves correctly' (it is usually expected that you must clear a cache manually if you do something outside the normal flow of operations to invalidate the cache).

It might be worthwhile to investigate further, but I do not think I will spend the time myself.

greg.1.anderson’s picture

Marked #1977812: Command files can be double included when same module in two profiles during updb as a duplicate of this issue. Note that I believe I was wrong in #6: having the same module in two profiles can cause problems even though only one of them can be enabled; therefore, drush cc drush won't help here.

See also related issue #1882150: command caching is broken.

hefox’s picture

Status: Active » Needs work
StatusFileSize
new1.3 KB

This is a patch that works around the issue, haven't figured out the bug (my local couldn't reproduce anymore, but not local, needs to work, not-playground was).

Something I did notice is $deferred should likely be part of the cache key

greg.1.anderson’s picture

Don't use the comma operator to declare the included array. $deferred should not be part of the cache key, as it controls when the item is added to the cache, not what should go into the cache.

hefox’s picture

StatusFileSize
new1.27 KB

My guess is something with deferred and search path being different for same phase is producing this error... or perhaps just search path being different, meaning during phase x at one time something is found, but other times it's phase y when it's found.

Or it could just be $evaluated; $evaluated isn't updated with cached items so if retrieving from cache for the first few phases but not another, it'll not exclude the already included ones. So to test that clear cache, have a command that partially bootstraps but excluding some search paths, then do a full bootstrap command. Don't have time to try that out atm.

anyhow updated with $included on it's own line

moshe weitzman’s picture

I'm inclined to find the bug and think of a proper solution, rather than work around a symptom.

hefox’s picture

That's my preference also (thus why I put it as needs work instead of needs review; it's a bandaid). Didn't have it reproducing in the right location to debug it further at the time, but needed it fixed and figured others may get in similar situation, so added the patch.

moshe weitzman’s picture

Modules can provide multiple commandfiles. The proposed patch doesn't look quite right (even as a workaround).

hefox’s picture

$defeered is already sing the pattern $variable[$module] = $filename, so that seems wrong if that's the case?

greg.1.anderson’s picture

In the context of the function _drush_add_commandfiles, $module = basename($filename);. In other words, $module does not hold the name of the module, but the name of the commandfile. This variable would have been better off named something else, like $commandfilebasename (although that alternative is perhaps a bit too long).

I am inclined to still agree with #11, although it appears that #13 is perhaps not an issue.

sutharsan’s picture

For what it's worth. I discovered this problem in the current 8.x-6.x HEAD. But the "Cannot redeclare" problem did not occur with Drush 8.x-6.0-beta1.

greg.1.anderson’s picture

Status: Needs work » Closed (won't fix)
Issue tags: +Needs migration

This issue was marked closed (won't fix) because Drush has moved to Github.

If desired, you may copy this bug to our Github project and then post a link here to the new issue. Please also change the status of this issue to closed (duplicate).

Please ask support questions on Drupal Answers.

ergophobe’s picture

Issue summary: View changes

This is solved with current version of drush - 6.5.0 works fine

https://github.com/drush-ops/drush/pull/430