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

Feature Request: Ability to specify default.*() against groupChoice(). #171

Closed
colin-mackay-CH opened this issue May 5, 2020 · 2 comments · Fixed by #176
Closed

Feature Request: Ability to specify default.*() against groupChoice(). #171

colin-mackay-CH opened this issue May 5, 2020 · 2 comments · Fixed by #176

Comments

@colin-mackay-CH
Copy link

colin-mackay-CH commented May 5, 2020

I'd like to be able to specify something like the following:

class GitHubOptions : OptionGroup() {
    val provider = Provider.GitHub
    val hostAddress by option(
        "--github-host",
        help = "The host of the GitHub api"
    ).default(defaultGitHubHost)
    val apiPath by option(
        "--github-api-path",
        help = "The root path of the GitHub api"
    ).default(defaultGitHubPath)
}

class GitLabOptions : OptionGroup() {
    val provider = Provider.GitLab
    val hostAddress by option(
        "--host",
        help = "The host of the GitLab api"
    ).default(defaultGitLabHost)
    val apiPath by option(
        "--api-path",
        help = "The root path of the GitLab api"
    ).default(defaultGitLabPath)
}
    private val provider by option("--provider", help = "Whether to scan projects in Github or GitLab")
        .groupChoice(
            "github" to GitHubOptions(),
            "gitlab" to GitLabOptions()
        ).default("github")

The two option classes specify --host and --api-path - with defaults that need to differ depending on which is defined. Presently, I am forced to require the user to define a provider even though we know the default --host and --api-path for both providers in 90% of cases.

I have the additional issue that I can't actually name them --host and --api-path, they need to be unique even though they can never be specified together.

@ajalt
Copy link
Owner

ajalt commented May 11, 2020

I added defaultbyName to groupChoice/groupSwitch options in #175.

However, in your case I think groups might not be necessary. You could do something like this:

val hostAddress by option(
    "--host",
    help = "The host of the Git provider api"
)
val address get() = hostAddress ?: provider.defaultAddress()

val apiPath by option(
    "--api-path",
    help = "The root path of the Git provider api"
)
val path get() = apiPath ?: provider.defaultPath()

val provider by option("--provider", help = "Whether to scan projects in Github or GitLab")
    .enum<Provider>().default(Provider.GitHub)

This would also make the help output more understandable than having separate groups.


Option names have to be unique across a command. They're all displayed in the help message, so it would be confusing to see the same option listed twice with different help text.

More importantly, it would be ambiguous to parse. Options are finalized (have their values set and validated) in the order they appear on the command line. That's important so that we can issue error messages correctly.

But that means if you have two options named --host, if the command line looks like --host=foo --provider=github, we would have no way to know which option host belongs to when we parse it. And we can't delay finalizing --host, because if the value of --host is invalid, we need to stop parsing immediately and show an error. If --provider is invalid or not specified, we wouldn't be able to parse --host either.

@colin-mackay-CH
Copy link
Author

Beautiful, thank you!

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