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

breaking(flags): add collect option #2247

Merged
merged 14 commits into from
May 25, 2022
Merged

Conversation

c4spar
Copy link
Contributor

@c4spar c4spar commented May 18, 2022

close #2246

@c4spar c4spar requested review from bartlomieju and kt3k as code owners May 18, 2022 23:14
flags/mod.ts Outdated
Comment on lines 250 to 256
// if (hasTypes && get(o, key) !== undefined) {
// throw new Error(
// `Option "${
// name.length > 1 ? "--" : "-"
// }${name}" can be used only once.`,
// );
// }
Copy link
Member

Choose a reason for hiding this comment

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

please remove these lines

Copy link
Member

@kt3k kt3k May 23, 2022

Choose a reason for hiding this comment

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

Or should this be uncommented in the future? If so, please add TODO comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It depends on how we want to handle duplicate options. You said you would prefer to throw an error for duplicate options. But currently we have tests to make sure that options can be overwritten.
If we want to keep the current behavior, we can remove those lines.
If we want to throw an error message for duplicate options, we can uncomment them.
If we want to make it configurable, I can add a todo to do that in a separate PR.

Copy link
Member

Choose a reason for hiding this comment

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

Current behavior (overwriting) makes enough sense to me. Let's try this as first pass.

flags/mod.ts Outdated
}
}
}
}

for (const [key] of Object.entries(flags.bools)) {
Copy link
Member

@kt3k kt3k May 23, 2022

Choose a reason for hiding this comment

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

nit: I think const key of Object.keys(flags.bools) makes more sense here.

Is it ok only to loop through flags.bools? What about the case when flags.strings are set and collectable and argv doesn't have key for it?

Maybe let's add test cases for those cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah right, i changed the default value for collectible boolean args from false to []. I would also need to set default values for collectible string args. is this fine for you or would you prefer not to set default values for collectible options?

Copy link
Member

Choose a reason for hiding this comment

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

It looks fine to me to set default values to collectible options.

@kt3k
Copy link
Member

kt3k commented May 23, 2022

@bartlomieju
This change makes each key have either single value or multiple values depending on the configuration. This is going to be breaking change, especially for advanced users such as denoflare, scuttlesaurus, etc (BTW most (non-advanced) usages don't depend on this feature).

This makes the parsing behavior more explicit than implicit, and upgrading path is obvious. So I think this is worth trying. What do you think?

flags/mod.ts Outdated
@@ -52,6 +52,9 @@ export interface ParseOptions {
/** A string or array of strings argument names to always treat as strings. */
string?: string | string[];

/** A string or array of strings argument names to always treat as arrays. */
collect?: boolean | string | string[];
Copy link
Member

Choose a reason for hiding this comment

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

I guess nobody would use collect: true as most cli tools tend to have --help or --version and they shouldn't be collectable. Do you think of any use case of collect: true?

Copy link
Contributor Author

@c4spar c4spar May 23, 2022

Choose a reason for hiding this comment

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

yeah maybe it's not necessary. i can remove it.

@kt3k
Copy link
Member

kt3k commented May 23, 2022

Thanks for updating!

kt3k
kt3k previously approved these changes May 23, 2022
Copy link
Member

@kt3k kt3k 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
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

LGTM

flags/test.ts Outdated
]);

assertEquals(argv, {
foo: ["bar", "baz"],
Copy link
Member

Choose a reason for hiding this comment

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

@c4spar
Ah, I realized we still collect values for arg when there's no string, boolean, collect options are specified. What do you think about making this case "baz"?

Copy link
Member

Choose a reason for hiding this comment

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

Because we check hasCollect || hasTypes before checking collectable in setKey, setting any option name changes the parse result (see the example below):

> parse(["--foo", "bar", "--foo", "baz"])
{ _: [], foo: [ "bar", "baz" ] }
> parse(["--foo", "bar", "--foo", "baz"], { string: "x" })
{ _: [], foo: "baz" }

I think this behavior is a little hard to explain to the users. What do you think?

Copy link
Member

@kt3k kt3k May 24, 2022

Choose a reason for hiding this comment

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

How about changing hasCollect || hasTypes ? !collectable : (...) part in setKey to just !collectable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also fine for me. I just thought that we want to keep the old behavior when no options are set, so that the flags module can be still used without defining any options. But i can change it if you want.
Current behaviour is roughly described here: https://github.com/denoland/deno_std/blame/0d2ba0f223d993fd31a0d10193de769ffb4a8886/flags/README.md#L69-L83 (But there is still an open question about negatable options.)

Copy link
Member

Choose a reason for hiding this comment

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

keep the old behavior when no options are set

Changing the parse behavior based on such condition feels too complex to me.

so that the flags module can be still used without defining any options.

I think flags module is still usable without any options even if we removed the old behavior. Do you mean such change is too breaking to existing users?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think flags module is still usable without any options even if we removed the old behavior. Do you mean such change is too breaking to existing users?

i mean also with collectible args. but i think i agree, it can be confusing. i will remove it.

@kt3k kt3k dismissed their stale review May 24, 2022 04:59

stale

Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

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

@c4spar Thanks for updating. Now the implementation is much simpler and what collect does looks more straightforward to me. The docs also look great. Nice work!

LGTM

@kt3k kt3k merged commit 6a95e29 into denoland:main May 25, 2022
@c4spar c4spar deleted the flags/collect-option branch May 31, 2022 18:09
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.

Flags: Add collect option
3 participants