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

Adding validation for mutually exclusive option groups #265

Closed
e-g-hategan opened this issue Jan 11, 2021 · 4 comments · Fixed by #267
Closed

Adding validation for mutually exclusive option groups #265

e-g-hategan opened this issue Jan 11, 2021 · 4 comments · Fixed by #267

Comments

@e-g-hategan
Copy link

e-g-hategan commented Jan 11, 2021

I'm using mutually exclusive option groups as described here
https://ajalt.github.io/clikt/options/#mutually-exclusive-option-groups

but would like to also do parameter validation with validate
https://ajalt.github.io/clikt/parameters/#validate

This doesn't seem to be supported as the returned types are not compatible as far as I can see.

If I'm wrong and this is in fact possible, please provide an example.

@ajalt ajalt changed the title Convert and validate not working Adding validation for mutually exclusive option groups Jan 11, 2021
@ajalt
Copy link
Owner

ajalt commented Jan 11, 2021

There aren't built-in validate or check extensions for MutuallyExclusiveOptions right now, although you can validate the options in the group individually. Can you share an example of your use case? What are you trying to validate, and what would you want to error message to look like if the validation failed?

The main reason this doesn't exist yet is because I'm not sure if there's a general solution for an error message. For a single option, we print out something like Invalid option --foo: your error message. But with an option group, would we add the names of all options to the message? Just the ones you use? It depends on what the specific error message is, which is why there isn't a built-in for this right now.

@e-g-hategan
Copy link
Author

e-g-hategan commented Jan 14, 2021

I am only interested in validating the options in the group individually, here's my example:

    sealed class Strategy {
        data class NameBased(val name: String) : Strategy()
        data class IdBased(val id: String) : Strategy()
    }

    private val strategy: Strategy? by mutuallyExclusiveOptions(
        option(
            "--id",
            help = "Name"
        ).convert { Strategy.IdBased(it) }
        // validation required
        ,
        option(
            "--name",
            help = "Id"
        ).convert { Strategy.NameBased(it) }
        // validation required
    ).single()

Are you suggesting I can in fact validate these individually?

My error messages whould be something like "name too long" if over a certain length, similar for id.

@ajalt
Copy link
Owner

ajalt commented Jan 14, 2021

Yes, although you'll need to specify types explicitly, since the mutuallyExclusiveOptions parameters are invariant.

private val strategy: Strategy? by mutuallyExclusiveOptions(
    option("--id", help = "Name")
        .convert<String, Strategy> { Strategy.IdBased(it) }
        .check { (it as Strategy.IdBased).id.isNotEmpty() },
    option("--name", help = "Id")
        .convert<String, Strategy> { Strategy.NameBased(it) }
        .validate { require((it as Strategy.NameBased).name.isNotEmpty()) { "name too short" } }
).single()

@ajalt
Copy link
Owner

ajalt commented Jan 14, 2021

Ok, I made the parameters covariant in #267, so with that change you'll be able to validate individual options without explicitly specifying the types. Let me know if that solves your problem.

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 a pull request may close this issue.

2 participants