Skip to content

Conversation

@danielthegray
Copy link
Contributor

This was an attempt to fix #1250 following the proposal there, but this causes other test failures. I am leaving this on a branch/PR for further examination if you think it is salvageable.

Copy link
Owner

@remkop remkop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally had a chance to review the PR in detail. First of all, many thanks!

With a small change, all tests pass: in processSubcommand, instead of passing the initialized set as is to the subcommand, we pass an empty list and use that to collect the args (and associated original/ancestor args) that were initialized by the subcommand. If we use this set for validation and setting defaults in the parent command, it works as intended. See my comment on that change for details.

If you make that change the PR can be merged. It would be good if we can have additional tests for named options similar to SubcommandTest::testInheritedParameter.

I also have an idea to improve the implementation even further: instead of doing a best-effort lookup with our findOriginal method, we can add a ancestor() method to the ArgSpec class that returns the original for an inherited ArgSpec (and null for non-inherited args). See my comment on that change for details. We can either make that improvement part of this PR if you want, or do this separately. Please let me know if you are interested in working on that.

@remkop remkop added this to the 4.6 milestone Nov 8, 2020
@remkop remkop added type: bug 🐛 theme: parser An issue or change related to the parser labels Nov 8, 2020
@danielthegray
Copy link
Contributor Author

First of all, @remkop thanks a lot for the work you put into reviewing this PR, and for doing it so quickly! You have been one of the most responsive maintainers that I have interacted with, and had several great ideas! I'm in a bit of a tight stretch work-wise, I'll try to have a look at your suggestions tomorrow or the day after, but I am interested in implementing the improvements you mention.
Thanks again!

@remkop
Copy link
Owner

remkop commented Nov 10, 2020

@danielthegray That is great, thanks for helping out with this!

Thinking about some details that may come up during the implementation:

  • an alternative name to ancestor() may be root(): the meaning is very similar to CommandSpec::root, so using the same name exposes less API surface to users and makes it easier to learn
  • for the top-level ArgSpec (the one that has scope = INHERIT), there is no ancestor/root, and I suggest that it returns itself rather than null (also similar to how CommandSpec::root behaves)
  • for ArgSpec objects that are not inherited, the ancestor()/root() method should probably return null

@codecov-io
Copy link

codecov-io commented Nov 10, 2020

Codecov Report

Merging #1254 (12b26df) into master (755ef48) will decrease coverage by 0.12%.
The diff coverage is 75.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #1254      +/-   ##
============================================
- Coverage     93.81%   93.68%   -0.13%     
  Complexity      458      458              
============================================
  Files             2        2              
  Lines          6753     6789      +36     
  Branches       1823     1835      +12     
============================================
+ Hits           6335     6360      +25     
- Misses          126      129       +3     
- Partials        292      300       +8     
Impacted Files Coverage Δ Complexity Δ
src/main/java/picocli/CommandLine.java 93.48% <75.00%> (-0.14%) 317.00 <0.00> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 755ef48...5f4d4e8. Read the comment docs.

@remkop
Copy link
Owner

remkop commented Nov 10, 2020

I saw you pushed a change. Do you want me to merge this, and do any further changes in a separate PR?

The best-effort matching search to add the root element was changed to
simply wire up the root ArgSpec to each of the inherited arguments.

Arguments which are not inheritable will have a null root, and
inheritable arguments (options or positional parameters) will have a
root() method that returns the root argument, or the argument itself if
it is already at the root.

Unit tests have also been added to check that this behavior is
maintained.
@danielthegray
Copy link
Contributor Author

danielthegray commented Nov 11, 2020

I essentially rebased the previous work off master (now that the annoying line endings problem was gone, making it easier to switch branches without being left in an un-workable state).

I have implemented your suggestion, with a small change which I will detail in the relevant review thread, to allow for infinitely nested subcommands. Let me know what your thoughts are! From my side, this is ready to merge.

@danielthegray danielthegray marked this pull request as ready for review November 11, 2020 15:36
@danielthegray
Copy link
Contributor Author

If you make that change the PR can be merged. It would be good if we can have additional tests for named options similar to SubcommandTest::testInheritedParameter.

I missed this during my last check, I will add these as well.

@remkop remkop merged commit d9f2af3 into remkop:master Nov 12, 2020
remkop added a commit that referenced this pull request Nov 12, 2020
remkop added a commit that referenced this pull request Nov 12, 2020
@remkop
Copy link
Owner

remkop commented Nov 12, 2020

Merged with some minor changes.
Thank you very much for the contribution!

@danielthegray
Copy link
Contributor Author

@remkop Thank you very much! That was a great catch, that the .root(original.root()) is not needed. I have removed a javadoc comment that I added to that effect, which would be good to merge in as well, I think.

@remkop
Copy link
Owner

remkop commented Nov 12, 2020

Ok, can you paste a diff/patch of your change here? Since this PR has already been merged I don't think it is possible to merge any subsequent changes.

@danielthegray
Copy link
Contributor Author

Sure!

diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java
index 02dd44c2..ca21e508 100644
--- a/src/main/java/picocli/CommandLine.java
+++ b/src/main/java/picocli/CommandLine.java
@@ -9060,7 +9060,6 @@ public class CommandLine {
                 public T hidden(boolean hidden)              { this.hidden = hidden; return self(); }
 
                 /** Sets whether this option is inherited from a parent command, and returns this builder.
-                 * <b>Do not forget to also set {@link #root()} when setting this, to ensure that it always can track back to the root element.</b>
                  * @since 4.3.0 */
                 public T inherited(boolean inherited)        { this.inherited = inherited; return self(); }

remkop added a commit that referenced this pull request Nov 12, 2020
@remkop
Copy link
Owner

remkop commented Nov 12, 2020

Merged. Thank you for the attention to details!

@danielthegray
Copy link
Contributor Author

Thank you again for getting this merged so quickly!

MarkoMackic pushed a commit to MarkoMackic/picocli that referenced this pull request Nov 13, 2020
MarkoMackic pushed a commit to MarkoMackic/picocli that referenced this pull request Nov 13, 2020
MarkoMackic pushed a commit to MarkoMackic/picocli that referenced this pull request Nov 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

theme: parser An issue or change related to the parser type: API 🔌 type: bug 🐛

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inherited positional parameter gets overridden by default value if placed after subcommand

3 participants