Closed (fixed)
Project:
Configuration Update Manager
Version:
8.x-1.x-dev
Component:
Drush commands
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
22 May 2018 at 22:38 UTC
Updated:
29 Nov 2019 at 04:15 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
anemirovsky commentedAnd here's the patch.
Comment #3
jhodgdonThanks for the patch! A few notes:
a) Question, is this a required part of the composer.json file? If so, we should fill it out. If not, let's just leave it out.
b) in composer.json:
c) in composer.json:
That seems wrong. Should probably be drupal/config_update_ui? And I would expect the description should be the description of the Config Update UI module, not a generic one like that?
d)
This needs to be replaced by an actual doc block for the class, not this boiler-plate doc.
e) I don't like duplicating code -- we'd have to support it now in two places. So I think either the Drush 8 commands should use this new class, or the Drush 9 commands should call the existing functions.
f) The functions in that class... should they be declared static? They seem to be static. Either that or they should ideally use dependency injection to get the services rather than using the \Drupal class? Normally we don't call \Drupal inside any class in Drupal. Can Drush use dependency injection? Hopefully...
Comment #4
jhodgdonOh, one more thing. The first line of any function/method documentation should be one line not exceeding 80 characters. These are way too long. Such as:
Comment #5
anemirovsky commentedRound 2!
I had originally gone with the approach outlined in https://weitzman.github.io/blog/port-to-drush9, which is why we ended up with some of that boilerplate and all the duplicate code. Now, instead of doing that, I'm going with the approach from http://nuvole.org/blog/2017/oct/13/how-maintain-drush-commands-drush-8-a.... This allows us to share as much of the code as we can between the Drush 8 and 9 versions of the commands. It also theoretically should make it easier to eventually add support for Drupal Console down the road, if you want.
The main thing I don't love about this approach is having to pass the $logger object around for each command. For the life of me, I could not figure out how to do it differently, though. I tried adding it as a property to the cli service object but for some reason that I wasn't able to figure out, likely having to do with the context for when the logger object is instantiated, if I did that, the logger would complain that it didn't have a success or error method.
One other change is that I've moved the commands into the config_update module as it doesn't make sense to me that you'd need config_update_ui enabled to get the drush commands.
Comment #7
anemirovsky commentedPutting this to needs review again. Not sure why the patch failed on deleting config_update_ui/config_update_ui.drush.inc.
Comment #8
jhodgdonI actually think the UI module should be where the Drush commands live. The base module just provides base classes, which are being used by several contrib modules; the UI module provides the reports and operations (including both UI and Drush versions of both). The patch is also pretty hard to review if you combine this change into the patch, because you can't really see what changed in the Drush 8 file. So... can you move it back at least for now, and if you want to move the Drush commands into the base module, file a separate issue for that? Thanks!
Comment #9
anemirovsky commentedThird time's a charm!
That makes sense about not moving the commands. This commit leaves the drush commands in place but includes utilizing the strategy outlined in http://nuvole.org/blog/2017/oct/13/how-maintain-drush-commands-drush-8-a... for sharing Drush 8 and 9 code as much as possible.
Comment #11
jhodgdonThe patch doesn't apply for me locally either... I think you need to do a git pull. The function drush_config_update_ui_config_revert() changed somewhat recently and it looks like you were patching from an older version. The issue that changed this function was
#2935395: Drush revert command does not work with non-entity config
Comment #12
anemirovsky commentedYep, that was the issue. This latest patch applies cleanly for me on the latest 8.x-1.x.
Comment #14
anemirovsky commentedLooks like tests are failing on it not being able to find drush_log(). Any thoughts on how to fix that? I know for sure drush_log() is a Drush 8 function.
Comment #15
jhodgdonIn the existing Drush tests (for D8), I had to load a special include file that mocked the Drush functions that the tests called. See
https://cgit.drupalcode.org/config_update/tree/config_update_ui/tests/sr...
Comment #16
anemirovsky commentedGreat! I just noticed the drush function stubs, too, and have added a stub for drush_log(). Thanks for pointing that out.
Also, I figured out a way to not have to pass $logger around as an argument to every function call. I think this is much cleaner, but I'm interested in your thoughts!
Comment #18
anemirovsky commentedI think this one should pass tests. Had to add a mock class for Drush\Log\LogLevel because we use a couple constants in that for the Drush 8 logger class we use in the CLI service.
Comment #19
jhodgdonThanks for the new patch! The tests pass, but there are 69 coding standards messages in your new code, so I think I'll wait to review the patch until those are fixed (probably much of my review would be things like "You need to add a documentation header here" etc.).
You can see the coding standards messages by clicking through to the test result
https://www.drupal.org/pift-ci-job/976118
Comment #20
anemirovsky commentedOk, let's see how this one does.
Comment #21
anemirovsky commented8th time's a charm!
Comment #22
anemirovsky commentedOk, I think this should take care of the last one.
Comment #23
jhodgdonThanks! Now that the coding style errors are gone, I'll give the code a review. A few notes:
a) in the drush.inc file:
Typo: The variable name here $config_update_ui_sevice should end in _service not _sevice.
b) Same file:
Normally we wouldn't want to update a member variable directly. We'd make a method.
c) same file:
- All classes mentioned in code should be fully namespaced starting with \
- Comma needed before "which".
- Stand-in should be hyphenated.
- Our Drupal coding standards normally require all classes to be in their own files, with namespaces. So this class should be moved to the src directory.
d) Inside that class:
All function docs first lines should end in a verb like Outputs, not Output. Please fix everywhere in your patch.
It seems like you aren't that familiar with Drupal coding standards. Some key pages to read:
https://www.drupal.org/docs/develop/coding-standards/api-documentation-a...
https://www.drupal.org/docs/develop/coding-standards/object-oriented-code
https://www.drupal.org/docs/develop/coding-standards/namespaces
e)
I don't know of any other instance in Drupal Core or most contributed modules where service classes have the word "Service" in the class name. Probably not a great idea here either? Also, since it's really just for Drush, maybe it makes more sense to have Drush in the class name than CLI?
f) in the Commands.php file:
Drush should be capitalized. Please fix everywhere in your patch.
g) Same file:
CLI is an acronym and should be all caps. Please fix everywhere in your patch.
h) same file:
Missing @return documentation. Several other functions in your patch with return values are missing @return docs too.
Ran out of time... that should get you started anyway.
Comment #24
anemirovsky commentedHere's another go. Unfortunately, I don't have any more time allotted for working on this task, so hopefully someone else interested in adding support for Drush 9 can step in and take it from here to get it to an acceptable place for you or I can circle back to this at a later date. Thanks for the code reviews!
a) Fixed.
b) Can you provide additional info on why it's not okay to set the member variable here directly? The only benefit I can come up with is some type checking, but we're already providing some of that via the documentation hint on the member variable. Ideally, I'd want to do this via dependency injection, but I haven't been able to figure out a way to make the dependency variable depending on how the object is instantiated. If you can think of a way to do that, that would be great.
c) This technique (and some of the code) is pulled from https://www.drupal.org/project/config_split, which does the same thing in putting the Drush 8 logger class in the same file as the Drush 8 commands. The reason I like having the Drush 8 logger class in the same file is that it's really just acting as a temporary shim for Drush 8 and should not be discoverable or used by any other code in the system. At some point, I imagine support for Drush 8 will end and jettisoning the Drush 8 specific code will be trivial as it will all be contained in this one file.
d) Fixed.
e) This naming convention is also taken from the config_split module. I'd be happy with some other alternative for Service, but I haven't been able to come up with a good option. The reason I left it as Cli instead of Drush is that it should be pretty easy for someone down the road to add support for Drupal Console, as the config_split module has it.
f) Fixed.
g) Fixed.
h) Fixed.
Comment #25
jhodgdonThanks for all your work up to this point! I can probably do the rest of the cleanup.
Comment #26
vijaycs85Here is an update:
#23.b - Fixed by adding getter/setter for logger property and made it protected.
#23.c - Fixed by moving logger to its own file and implements LoggerInterface and Traits like other core/contrib modules.
#23.e - I did n't change it, but I agree the name is bit odd and I would a) have all those methods in same command file, if that's OK otherwise b) move the class to src/Commands
Comment #28
vijaycs85Comment #30
jhodgdonThanks for continuing to work on this, and sorry I've been silent for a while -- I was on vacation for a few weeks.
So... There are 2 coding standards messages from that last patch, and then some test failures having to do with a missing drush_log() function [maybe the config_update_ui.drush_testing.inc file isn't loaded for those tests?]. I'll let you sort those out, but this is definitely getting closer!
A few other small notes:
a) In config_update_ui.drush.inc :
The verb "set" in this comment should be "sets".
b) In the new Drush commands class: It looks like there is no @usage for config:list-types -- probably should be?
c)
We don't normally start doc blocks with the name of the class. It should start with a one-line description instead.
Also, I think it would be useful to say that if you use this class, you must call the setLogger() method before doing anything else.
d) And in that same class:
I think it would be useful here to suggest which two classes can be used for Drush 8 and Drush 9, and say that if you use the one that you've added to this patch, that is how this class figures out you're using Drush 8. This is not documented anywhere, except in the code itself, and it would be good to have in the API documentation.
e) In another project, I'm extending a class that I'm using from another project... I have grown to hate "private function" declarations, because . Can you instead make them protected? You just never know if someone is going to need to override them.
f)
In docs, fully-namespaced class names should start with \ -- I noticed this one here, but there may be other instances of it.
See also comment (c) -- don't start the docs with the class name.
Comment #31
jhodgdonI went ahead and made the changes I requested in #30 to this patch.
However, in doin this I found that there is a problem with defining the D8 logger as a service (added to config_update_ui.services.yml) -- the testing platform for some reason decides to use it in non-Drush tests, and it doesn't work without Drush being available. So, I had to take a different route there. Let's see if it passes this time...
Comment #32
jhodgdonWould help if I uploaded the patch file. :)
Comment #34
jhodgdonOK, now we're getting somewhere. But the get_class() call in ConfigUpdateUiCliService::outputRows is failing because
http://us1.php.net/manual/en/function.get-class.php
it returns the full namespaced name. It's not the usual way to do things either. So let's try this.
Comment #36
jhodgdonI get a different error when I try to run this test at home (probably vendor and core are out of sync, ugh)... let's try this... just changed that one line in ConfigUpdateUiCliService where it tests the logger class to use the fully qualified namespace name. Interdiff:
Comment #38
jhodgdonHm. Not sure what to do here... The problem is in the tests, we're testing the Drush 8 functions (without Drush, just testing the PHP functions that Drush would call, with stubs in for the logger). But the new class for doing the actual work in Drush is failing to detect that we're doing D8 via either get_class() or instanceof. Maybe there is a better way? This is in function ConfigUpdateUiCliService::outputRows().
Probably we should just set a flag in the constructor, or add to the setLogger() function? That seems more reasonable. I'll try that... let's see...
Comment #40
jhodgdonAha! Finally a new error. Looks like the Drush 8 logger class isn't complete:
Drupal\Tests\config_update_ui\Functional\ConfigUpdateTest::testConfigReport
Error: Call to undefined method Drupal\config_update_ui\Logger\ConfigUpdateUiDrush8Logger::success()
I wish my environment was letting me run tests right now, this would be a lot faster... Anyway, I can't work on this today but will get back to it in a few days.
Comment #41
jhodgdonSo.... The Drush logger class in this patch implements the PSR log interface, by using the Drupal logging trait. That looks good.
But the code in ConfigUpdateUiCliService calls a method success(), which exists on
https://github.com/consolidation/log/blob/master/src/Logger.php
(the Drush logging class extends this)
but as far as I can tell, doesn't exist on any logging interface anywhere. And there is zero API documentation for the method. Doh!
So, how is this being used? It looks like in the old drush.inc file for Drush 8, we did things like:
But in the new code, it's doing
I don't actually know if that is the right thing to do here. It doesn't seem like this result should be *logged* per se. The result needs to be sent back to the user and displayed. I'm not sure if that is what the success() method does? Maybe.
Anyway, I guess what I will do is add a success() method to the Drush 8 logger class that reproduces the old drush_print, and leave it at that. Here's a new patch. Maybe this time the tests will pass...
Comment #43
jhodgdonOK, the tests passed! There's now just a coding standards message with this interdiff in the new success function:
Applying that...
Comment #44
jhodgdonOK. So the automated tests are now passing.
I think we need to test this manually with both Drush 8 and Drush 9. The automated tests verify that some of the command functions for Drush 8 work, but I think in this case since the whole Drush infrastructure has been updated, we should do a manual test at the Drush command line and make sure that:
- the commands all still appear in drush help
- the individual command help works
- the commands work, including some error or empty output cases
I will see what I can do about testing sometime soon... if anyone else wants to test manually, please do! And post here with what you tested and what worked/didn't work. Thanks!
Comment #45
jhodgdonI have completed a manual test using Drush 8. I tested "drush help" and the functionality of all of the commands, and they all are working as they used to without this patch. So, that is good!
We still need to test Drush 9.
Comment #46
jhodgdonI have tested the commands in Drush 9.
First problem: the usage lines were wrong -- they all started with "Drush" instead of "drush". That was easy to fix in the
@usagelines in the ConfigUpdateUiCommands.php file.Second problem: the output is formatted in a really annoying and/or wrong way. It is hard to read. The default output looks like this:
You can try some other formats and it is even worse for some, like:
Totally useless!
So, I think this patch needs some work. The output should not be wrapped in these "item" things. ?!?
Meanwhile here is a patch that updates the @usage lines (I didn't bother to make an interdiff).
Comment #47
jhodgdonI looked into the output formatting, which is provided for Drush by this project:
https://github.com/consolidation/output-formatters
It looks like if the data is really just a flat array of strings, the right thing to do is just to return it as an array of strings.
This simplifies the patch a bit. Now the output is more reasonable.
or without the format option:
I have now tested various commands with Drush 9 and they all seem to work fine.
Any thoughts on this new patch?
Comment #48
jhodgdonActually, this patch doesn't need the member variable drushVersion any more. Removing that...
Comment #51
jhodgdonAnd... removing
from ConfigUpdateUiCliService.php to take care of coder message.
Comment #52
jhodgdonOK, I think this latest patch is working... Any comments @vijaycs85 or @anemirovsky? I will leave this open for a week or so, and then commit it if there are no objections before then. Thanks again for all of both of your work on this issue!
Comment #53
jhodgdonUpdating issue summary.
Comment #54
dnmurray commentedJust tested against a fresh addition of the module to a drush 9 install. Worked perfectly (commands now appear in drush list). Curious about output differences though with config-diff vs what I see in the UI doing a diff on the same config name. This is probably another issue though, not for this patch.
Comment #56
jhodgdonYes, please create an issue for diff differences! Thanks for testing.
I think this has been reviewed enough now, and waited long enough for comments, and I have committed it. Thanks all!
Comment #58
chris matthews commented