-
Notifications
You must be signed in to change notification settings - Fork 95
Add pluck and patch subcommands #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pluck and patch subcommands #24
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start! Left a few comments inline
features/post-meta.feature
Outdated
""" | ||
And I run `wp post meta set 1 meta-key --format=json < input.json` | ||
When I run `wp post meta pluck 1 meta-key foo.bar.baz` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if this were space limited? e.g.
wp post meta pluck 1 meta-key foo bar baz
I think space delimited is closer to existing WP-CLI patterns, unless there's a specific reason you're using periods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that. My initial thought was to use a single string for it and make the delimiter configurable which is how it is now. A space could still be used as it is but it would require wrapping in quotes. The command is a little lengthy with arguments as it is, I think the dot-notation it's a little easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the preferred approach should be to accept an arbitrary number of positional arguments with each one representing one level.
The benefit is that you can have both periods and spaces be part of the keys:
# foo -> bar -> baz
wp post meta pluck 1 meta-key foo bar baz
# foo.bar -> baz
wp post meta pluck 1 meta-key foo.bar baz
# foo bar -> baz
wp post meta pluck 1 meta-key "foo bar" baz
Any mechanism which needs you to provide all levels in one positional argument will force you to have one arbitrary character be impossible to use as a key identifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea. For patch
then, should we use an associative argument for the new value or continue to use the last positional argument as the new value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For
patch
then, should we use an associative argument for the new value or continue to use the last positional argument as the new value?
Last positional argument seems reasonable to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will the Synopsis parser allow a <parts...> [<value>]
?
""" | ||
When I try `wp post meta pluck 1 meta-key foo` | ||
Then STDOUT should be empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should set an explicit check for return code here too:
And the return code should be 1
* default: . | ||
* --- | ||
* | ||
* [--format=<format>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these formats correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly copied from the existing get
subcommand. The table output is a misnomer for sure as it does not output as a table.
It runs through \WP_CLI::print_value
so it should probably be updated with the options it supports.
src/WP_CLI/CommandWithMeta.php
Outdated
* default: . | ||
* --- | ||
* | ||
* [--mode=<mode>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user supplies a new value but uses --mode=unset
, what's the behavior?
Would it make more sense to have a separate method for deleting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test for this yet but it would unset the key which is different than say wp post meta patch 1 meta-key foo.bar ''
and just setting it to an empty value.
I like the idea of using a separate command but can't think of a good name to use for that. I think that it can work under the umbrella of patch
as it is still a nested value modification unless we can come up with a verb that makes more sense? It's "patching" the value with the key removed.
I was also thinking that there may be a merge
mode a merge of data rather than just replacing, but I pulled back on it as it probably wouldn't be very practical.
bin/test.sh
Outdated
|
||
set -ex | ||
|
||
phpunit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should make this a part of the default package scaffold too: wp-cli/scaffold-package-command#121
Commands have been updated to use positional args as the target key path, and the concept of a delimiter has been removed. I also updated the assertions to use JSON for consistency with the input. We still need to come to a decision as to how By default, the command errors out if the key does not exist. If we want to create the key with the value (ie. insert it) then we need a way to set that in the command. This is where I am looking for feedback from you guys. I'm not a big fan of using/keeping the |
This is my sentiment too. I don't have a strong opinion one way or another at this point ( Another idea would be: |
How does this work with numerically indexed values? |
I like this the most out of all the options so far 👍
Good question! The argument will be interpreted as a string I believe and will check for a key with a loose comparison. The traverser can obviously handle any valid type as keys to navigate, the limitation is more on taking the input from the command args where the type will have to be inferred. I don't think there will be a perfect solution here, but I think the only situation where it would be problematic is if a key existed for both the string and numeric value. E.g. array(
1 => 'int one',
'1' => 'string one',
) This seems like an edge case that isn't worth handling, but it is something we should look into and make sure that it works reasonably well with numeric keys. I'll add some tests for this and keep this in mind when building out |
Great, thanks. I don't think we need a solution for the ambiguous scenario either, but it would be good to have a test with explicit assertions of behavior. |
This reverts commit f2c2e3f.
Update! Pluck and patch are functionally complete for meta commands 🎉 Patch now requires the action to be set as the first argument More tests have been added for everything, including the behavior with indexed keys. I thought indexed keys would be more of a pain than they were, but it turns out we only needed to cast them to integers (when they look like one) and everything just works. I tried to create a scenario for the edge case where I was expecting this to fail using a string integer for the key, but found this quite hard to do. Both JSON and PHP convert string integers to integers when serializing. serialize( ["0" => "foo"] )
// string(20) "a:1:{i:0;s:3:"foo";}" Who knew!? 😁 The question now is whether this looks good enough to start replicating to the rest of the entities? |
Sweet :) Looking good on my end. Given the amount of code landing, I'd like for @schlessera to give it a review too.
Yes, I think this would be a good idea.
Correct, and sounds good. |
* default: plaintext | ||
* options: | ||
* - plaintext | ||
* - json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get a couple useful ## EXAMPLES
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaemnnosttv Bump here.
* default: plaintext | ||
* options: | ||
* - plaintext | ||
* - json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get a couple useful ## EXAMPLES
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaemnnosttv Bump here
Hey guys, I just pushed another update with many things addressed. One big improvement is that I found a way to reliably test if STDIN was passed or not which eliminates the possibility of the last argument being mistakenly used for the value if the STDIN is empty. I added a method on a new I still need to add a few extra functional test cases that were requested, but I think we're really close to something that can be replicated to other commands. |
Yes, let's keep the function within |
breaks relative namespacing to WP_CLI\Utils functions
@aaemnnosttv Aside from the couple remaining small nits, are you happy enough with this to land it? @schlessera Can you give this one final review? |
/** | ||
* Unset the value at the given key path. | ||
* | ||
* @param $key_path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type hint missing. string|int|array
?
*/ | ||
public function exists( $key ) { | ||
return ( is_array( $this->data ) && array_key_exists( $key, $this->data ) ) || ( is_object( $this->data ) && property_exists( $this->data, $key ) ); | ||
return ( is_array( $this->data ) && array_key_exists( $key, $this->data ) ) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of readability, pushing the operator to the next line is preferable, i.e.:
if ( $condition1
|| $condition2
|| $condition3 ) {
}
Bump @aaemnnosttv |
@danielbachhuber I'm much happier with it now that it does not have the edge case that @schlessera mentioned. I'm guessing there may be a few small abstractions to make which might come up when replicating to the other commands, but I think it's in a good spot. Do you guys feel like it's functionally ready to start rolling it out to other entities? |
@aaemnnosttv Yes, I think the functionality is good now. Feel free to attack the other commands as well, while abstracting as needed to keep the code DRY. |
@aaemnnosttv Let's go ahead and merge this then and handle the others in subsequent PRs. |
Created a new issue for @aaemnnosttv As far as I can think of, |
|
Good call re: |
Hey guys,
I thought I would post this here for some feedback before I go on and do much more.
I've started with the meta commands as it seemed like the easiest way to affect the most commands.
I added some things like PHPUnit which helped a lot with testing the class I added; that OK?
I expect some things will need to change but let me know if we're on the right track here, or if you'd like me to be doing something different while things are more flexible.
Resolves wp-cli/ideas#42