Closed (fixed)
Project:
Drush
Version:
All-versions-4.x-dev
Component:
Base system (internal API)
Priority:
Normal
Category:
Bug report
Assigned:
Reporter:
Created:
24 Jan 2012 at 20:28 UTC
Updated:
4 Jun 2012 at 13:41 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
q0rban commentedComment #2
apotek commentedGlad to find this. Was scratching my head with a very similar issue. The drush command (with --debug and -v) says it finds the command
But the callback for that command is never executed. If I error_log(__FUNCTION__); in there, I get nothing. I can even put a call in to an undefined function "nofunction();" and there is no PHP crash. So the command is found, but the callback is never actually called. Odd that there is no debugging or error output for this situation.
Comment #3
q0rban commentedcross post. :)
Comment #4
greg.1.anderson commentedIn Drush-5.x, under the conditions you describe, the following code should fire:
In other words, if you do not define any valid hooks, then Drush will print all of the available hooks that were considered so that you can choose one to implement.
Marking this as 'patch to be ported' for consideration for backporting to 4.x. Probably won't do this myself, so please close if you don't want to do it.
Comment #5
q0rban commentedInteresting. Looks like that code exists in drush 4.5. If I print out $all_available_hooks there, I get a huge array of functions that don't exist. Looks like this code is the culprit (notice the else statement):
In light of this, switching to a bug report, since it sounds like this is supposed to work as I expected it to. Also, if I'm reading things right, it looks like this might be a bug in the 5.x branch as well.
Comment #6
q0rban commentedUpdating title, and working on a patch now.
Comment #7
q0rban commentedAttached patches fix it for me.
Comment #8
greg.1.anderson commentedYou are right. The condition (in 5.x) should have been $completed, not $all_available_hooks.
Try the following fix for Drush-5.x. I also improved the output so that it shows only the most interesting function name unless --show-invoke is specified.
Comment #9
q0rban commentedHmm, I tried running the tests against this, and I get errors for all sorts of core commands. For example:
Comment #10
q0rban commentedAlso, what is the difference between $functions and $completed? I don't see them being used anywhere else. It seems like $completed should only contain functions that didn't fall into here:
But, I don't see that happening anywhere. If I'm reading it right, $functions and $completed would contain the exact same thing.
Comment #11
q0rban commentedYeah, now that I'm using this patch more, it seems there's something else wrong with the logic in here. Here's some output on a drush cc all call:
Comment #12
greg.1.anderson commentedAll tests pass for me. This patch is for Drush-5; are you perhaps applying it to Drush-4?
The practical difference between $functions and $completed is that $functions has an inner scope, whereas $completed is still in-scope where it is needed. You are correct that $functions is residual, though, and currently unused. It is residual, and could go away.
Comment #13
moshe weitzman commentedCode looks good. Lets remove residual code. drush_invoke() in particular needs to stay grokkable
Comment #14
q0rban commentedAh, nevermind, I see the difference between $functions and $completed, and I see why my patch isn't working.
Comment #15
q0rban commentedSetting to needs work, per moshe: "Lets remove residual code."
Also, I think we should add in a test for this, so this doesn't happen again. I'm going to work on this some today.
Comment #16
greg.1.anderson commentedCommitted with residual code removed. Please re-open or make a new issue to submit tests.
Comment #17
q0rban commentedUmm.. that kinda sucked. :)
I had assigned this to me, and said I was working on a patch. Then I go to create the patch and get conflicts b/c you already committed a patch. The commit message also only says your name in the credits.
If you're going to work on something that someone has assigned to them, I would at least try to find them in IRC and tell them to stop working on it. :)
Comment #18
q0rban commentedNow that I'm getting into the test, I'm thinking the exit code should be 1 when this happens. Setting this to needs work again based on that. I'm working on a patch for this. No really, I am. :P
Comment #19
q0rban commentedOk, here goes.
Comment #20
q0rban commentedComment #21
moshe weitzman commentedI wish I could remember why, but I think it is a warning for a reason. I'm not eager to make this an error, until drush6 at the earliest.
Comment #22
q0rban commentedAt a very basic level, why wouldn't the exit code be 1 for a drush command that didn't actually run?
Also, I'm not sure how to write the test without testing on the exit code. $this->getOutput() doesn't have anything in it, so I can't assert anything there.
Comment #23
moshe weitzman commentedDrush commands can all other drush commands. You don't know that the outermost command failed.
Comment #24
q0rban commentedYeah, I understand. That's actually what got me here in the first place, though. The command that started this issue is actually a command that calls other commands. If commands call other commands and those commands fail, the outer command should determine how to deal with the failure. I understand that may be a lot to ask, and maybe that's why you say "Drush 6". In my opinion, a command that can't find a callback function is a very big problem, and may be even more so when you are talking about nested commands. If I have an outer custom migration command (which is how this all started), and one of those commands fails, that can be the cause of some SERIOUS problems down the line. :)
But aside from that, can someone give me some tips on how I would write a test for this if exit status is 0?
Comment #25
greg.1.anderson commented@q0rban: Sorry about that. I should slow down in the queue -- making some errors of fact and judgment lately.
I can't think of any reason why this could not be an error; no function should ever exist without at least one callback function. I think there was a tmie when --show-invoke returned an error; that did cause a problem, because sometimes you want to use --show-invoke with a functional command. I think it's safe to return drush_set_error if $completed is empty.
That said, if the command does not return an error when there is no command callback, you could still test it in a unit test by calling the empty command via backend invoke and checking the contents of $values['output'] for the error message.
Comment #26
greg.1.anderson commenteddrush_invoke_hooks should return FALSE if you call drush_set_error. Try
$return = drush_set_error(...)to effect that. It would also be an improvement to roll the two adjacent messages into the drush_set_error, so that you don't have a drush_set_error immediately followed by a drush_log on the next line (minor).I do think it is best for drush_invoke_hooks to call drush_set_error when the command has no hooks; this is a degenerate case, and it seems like when this happens, we should force the outermost command to fail. In the rare case that the outermost command wants to suppress this error, it can reset the drush error explicitly. Also, there is some chance that the value of 'integrate' might affect how errors are propagated in backend invoke, but I didn't really investigate this; setting the error just seems like the right thing to do.
Comment #27
moshe weitzman commentedYou guys are right - we should throw an error when there are no hooks. Greg can commit this when he is satisfied.
Comment #28
q0rban commentedGreg, thanks for the awesome feedback, and no worries about the earlier commit. You can't win if you have people complaining about committing something too fast, eh? :)
I'll work on this and re-roll the patch.
Comment #29
q0rban commentedChanges include setting $return to drush_set_error(), and combining the subsequent warning into the error message.
Comment #30
q0rban commentedAny feedback on this latest patch?
Comment #31
greg.1.anderson commentedYeah, it is good; I will test and commit. I've just been really busy lately.
Comment #32
greg.1.anderson commentedTested and committed.
Comment #33
q0rban commentedComment #34
greg.1.anderson commentedYes, this could go in Drush-4.
Comment #35
msonnabaum commentedTried cherry-picking these commits but the test didn't pass. I'll try to look into it further tomorrow, but if someone wants to provide a 4.x patch it will have a better chance of making the 4.6 release.
Comment #36
greg.1.anderson commentedI thought about it, but I'm just not that interested in seeing this in 4.x. Sure, it's useful, but it's primarily of educational / informative value. Now that Drush-5 is out, folks writing new Drush commands (esp. people not already familiar w/ writing Drush commands) should be doing it on 5.x, not 4.x, and this patch doesn't help any other class of user. Unless a patch comes from another quarter, I'd say just skip it.
Comment #37
msonnabaum commentedI think I agree. Marking as fixed for now unless someone wants to reopen with a patch.
Comment #38.0
(not verified) commentedClarified a sentence.