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

Environment variable name generation from command name is broken #1253

Closed
gpakosz opened this issue Mar 8, 2019 · 6 comments
Closed

Environment variable name generation from command name is broken #1253

gpakosz opened this issue Mar 8, 2019 · 6 comments
Milestone

Comments

@gpakosz
Copy link
Contributor

gpakosz commented Mar 8, 2019

When command names contain a - character, automatic environment variable name generation is broken

#!/usr/bin/env python3

import click

@click.group()
@click.option('--debug/--no-debug')
def cli(debug):
    click.echo('Debug mode is %s' % ('on' if debug else 'off'))

@click.command(name="greet-me")
@click.option('--username', show_envvar=True)
def greet(username):
    click.echo('Hello %s!' % username)

if __name__ == '__main__':
    cli.add_command(greet)
    cli(auto_envvar_prefix='GREETER')
$ pipenv run python ./test.py greet-me  --help
Loading .env environment variables…
Debug mode is off
Usage: test.py greet-me [OPTIONS]

Options:
  --username TEXT  [env var: GREETER_GREET-ME_USERNAME]
  --help           Show this message and exit.

This seems to be solved by changing core.py:329 to

       # If there is no envvar prefix yet, but the parent has one and
        # the command on this level has a name, we can expand the envvar
        # prefix automatically.
        if auto_envvar_prefix is None:
            if parent is not None \
               and parent.auto_envvar_prefix is not None and \
               self.info_name is not None:
                auto_envvar_prefix = '%s_%s' % (parent.auto_envvar_prefix,
                                           self.info_name.upper().replace("-", "_"))

I'm not opening a pull request though as I'm not familiar with click's codebase and

  • I'm not sure the modification above is general enough as there are other instances of <something>.name.upper() found in core.py
  • I'm not sure replacing - with _ covers all the tricky cases
@gpakosz
Copy link
Contributor Author

gpakosz commented Mar 9, 2019

In fact, it also happens when not setting the command name explicitly but letting click renaming function names with underscore to command names.

#!/usr/bin/env python3

import click

@click.group()
@click.option('--debug/--no-debug')
def cli(debug):
    click.echo('Debug mode is %s' % ('on' if debug else 'off'))

@cli.command()
@click.option('--username', show_envvar=True)
def greet_me(username, foo):
    click.echo('Hello %s!' % username)

if __name__ == '__main__':
    cli(auto_envvar_prefix='GREETER')
$ pipenv run python ./test.py greet-me --help
Loading .env environment variables…
Debug mode is off
Usage: test.py greet-me [OPTIONS]

Options:
  --username TEXT  [env var: GREETER_GREET-ME_USERNAME]
  --help           Show this message and exit.

@gpakosz gpakosz changed the title Environment variable name from automatic prefix for commands which name contains a dash are broken Environment variable name generation from command name is broken Mar 15, 2019
@kathychurch
Copy link

kathychurch commented Apr 4, 2019

This issue is causing me problems as well. Thank you @gpakosz for submitting a fix!

@gpakosz
Copy link
Contributor Author

gpakosz commented Apr 12, 2019

I guess it's related to 5d1df0e

@gpakosz
Copy link
Contributor Author

gpakosz commented May 15, 2019

@davidism can this be added to the next milestone by chance?

@nobodyinperson
Copy link

nobodyinperson commented Jul 22, 2019

Stumbled over this today as well. Maybe Command Aliases might be a workaround until #1261 is merged?

@nobodyinperson
Copy link

nobodyinperson commented Jul 22, 2019

Unfortunately, Command Aliases can not be used as a workaround here (at least not how I am doing it):

import click


# this Group allows specifying both "greet_me" and "greet-me"
# (https://click.palletsprojects.com/en/7.x/advanced/?highlight=alias#command-aliases)
class AliasedGroup(click.Group):
    def get_command(self, ctx, cmd_name):
        rv = click.Group.get_command(self, ctx, cmd_name)
        if rv is not None:
            return rv
        matches = [
            x
            for x in self.list_commands(ctx)
            if x in (cmd_name, cmd_name.replace("-", "_"))
        ]
        if not matches:
            return None
        elif len(matches) == 1:
            return click.Group.get_command(self, ctx, matches[0])


@click.group(
    cls=AliasedGroup,
    # setting the auto_envvar_prefix here works better with
    # setuptools/console_scripts
    context_settings={"auto_envvar_prefix": "GREETER"},
)
def cli():
    click.echo("click version {}".format(click.__version__))


@cli.command(name="greet_me")  # force the name to include the underscore
@click.option("--username", show_envvar=True)
def greet_me(username):
    click.echo("Hello %s!" % username)


if __name__ == "__main__":
    cli()

This can be invoked both with greet_me and greet-me. However, using the dash still results in the broken environment variable:

python3 -m test greet_me --help
click version 7.0
Usage: test.py greet_me [OPTIONS]

Options:
  --username TEXT  [env var: GREETER_GREET_ME_USERNAME]
  --help           Show this message and exit.
python3 -m test greet-me --help
click version 7.0
Usage: test.py greet-me [OPTIONS]

Options:
  --username TEXT  [env var: GREETER_GREET-ME_USERNAME]
  --help           Show this message and exit.

gpakosz added a commit to gpakosz/click that referenced this issue Jan 6, 2020
@davidism davidism added this to the 7.1 milestone Feb 20, 2020
davidism added a commit that referenced this issue Feb 22, 2020
Prevent environment variables from containing '-' characters
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants