Skip to content
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

Refactor getCommandAndParents() into Command._getCommandAndAncestors() and use consistently #1939

Merged
merged 3 commits into from Aug 19, 2023

Conversation

aweebit
Copy link
Contributor

@aweebit aweebit commented Aug 5, 2023

Cherry-picked from #1938.

A purely cosmetic PR Introducing no functional changes or changes visible to the user.

Replaces getCommandAndParents() with Command._getCommandAndAncestors()

  • …because an instance method is where the function logically belongs.
  • Renamed because "ancestors" is more precise than "parents".

Also changes the code to make use of the function whenever appropriate. (I thought it was a good idea after introducing currentParent replacing parent in #1938. I ended up getting rid of it and simply upgrading the parent semantics, but who knows what changes to the parent resolution could be made in the future. It is better to keep the code for getting the ancestors in one place.)

Replaces getCommandAndParents():
- turned into an instance method
- used "ancestors" instead of "parents" because it is more precise

(cherry picked from commit aa280af)
@aweebit aweebit force-pushed the feature/_getCommandAndAncestors branch from 01251dc to da5a499 Compare August 5, 2023 09:14
@aweebit
Copy link
Contributor Author

aweebit commented Aug 5, 2023

(Force push is due to a reset in order to change the commit message borrowed from aa280af so that it does not say anything about the parents array only introduced in #1938.)

@shadowspawn shadowspawn added the on hold Not a current focus due to dependencies on other PR or number of other PR label Aug 8, 2023
@shadowspawn
Copy link
Collaborator

This comment is just musing. No action items.

I had considered these when I wrote the code, but was 50/50 on a couple, and willing to change.

…because an instance method is where the function logically belongs.

Ok.

Renamed because "ancestors" is more precise than "parents".

My concern was that ancestors might be more correct but less understandable to some readers. However, ancestor is certainly tree terminology. Ok.

https://en.wikipedia.org/wiki/Tree_(data_structure)
Ancestor
A node reachable by repeated proceeding from child to parent.

@shadowspawn
Copy link
Collaborator

Also changes the code to make use of the function whenever appropriate. (...but who knows what changes to the parent resolution could be made in the future. It is better to keep the code for getting the ancestors in one place.)

No, or at least not as strong as you describe.

I did wonder about making the navigation more like an internal detail (so use the helper routine everywhere), but decided against that and have not changed my mind. The subcommand tree is navigable downwards using the .commands() links and up by using the .parent links. These are public properties and will be used in external code. It is fine to use them in code.

So using the helper routine and array methods to replace manual loops is ok when it is an improvement or at least directly equivalent. But it is not appropriate when it requires extra steps or is awkward.

@shadowspawn shadowspawn removed the on hold Not a current focus due to dependencies on other PR or number of other PR label Aug 9, 2023
lib/command.js Outdated
@@ -1743,14 +1756,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
if (flag.startsWith('--') && this._showSuggestionAfterError) {
// Looping to pick up the global options too
let candidateFlags = [];
let command = this;
do {
for (const command of this._getCommandAndAncestors()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be a forEach? (I don't like the for ( of ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could be if not for the early exit that is impossible with forEach. I guess this is one of the cases where iterating manually via .parent is more appropriate.

Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

lib/help.js Outdated
@@ -101,10 +101,10 @@ class Help {
if (!this.showGlobalOptions) return [];

const globalOptions = [];
for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
const visibleOptions = parentCmd.options.filter((option) => !option.hidden);
cmd._getCommandAndAncestors().slice(1).forEach((ancestorCmd) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

No. Having to use the slice makes this too subtle for my liking.

Copy link
Collaborator

Choose a reason for hiding this comment

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

(Ok with the active variable changing to ancestorCmd though.)

lib/help.js Outdated
}
return parentCmdNames + cmdName + ' ' + cmd.usage();
let ancestorCmdNames = '';
cmd._getCommandAndAncestors().slice(1).forEach((ancestorCmd) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

No. Having to use the slice makes this too subtle for my liking.
Ok with the active variables changing to ancestorX though.

@shadowspawn
Copy link
Collaborator

So using the helper routine and array methods to replace manual loops is ok when it is an improvement or at least directly equivalent. But it is not appropriate when it requires extra steps or is awkward.

This only ended up affecting a couple of the changes! I had seen them on first scan and feared there might be more, so wanted to explain my reasoning. Added comments on the lines of concern.

Copy link
Collaborator

@shadowspawn shadowspawn left a comment

Choose a reason for hiding this comment

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

Was dubious about this but after working through my concerns, yup, ok!

Changes requested on three of the lines.

Only call when all elements are to be iterated.
Resort to manual iteration via .parent in other cases.
Copy link
Collaborator

@shadowspawn shadowspawn left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Collaborator

@abetomo abetomo left a comment

Choose a reason for hiding this comment

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

+1

@abetomo abetomo merged commit f76a734 into tj:develop Aug 19, 2023
11 checks passed
@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Aug 22, 2023
@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Feb 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants