Repository: meltano/meltano

Issue:
Consistently use hyphens in CLI parameter names rather than underscores
Migrated from GitLab: https://gitlab.com/meltano/meltano/-/issues/2297

Originally created by @DouweM on 2020-08-21 18:02:10

---

Culprits:
- `meltano init` `--no_usage_stats`
- ~~`meltano elt` and `meltano schedule` `--job_id`~~ Changed to state-id
- `meltano upgrade` `--pip_url`


Discussion:
[View 1 previous comment from the original issue on GitLab](https://gitlab.com/meltano/meltano/-/issues/2297)
This has been marked as stale because it is unassigned, and has not had recent activity. It will be closed after 21 days if no further activity occurs. If this should never go stale, please add the `evergreen` label, or request that it be added.

We should be able to address this without any breaking changes by using `token_normalize_func` as described here:
- https://github.com/pallets/click/issues/1123#issuecomment-589989721

Then we can simply replace the CLI options that uses underscores with hyphens, and any users who continue to use underscores will silently have the CLI option they provide normalized to use hyphens instead when the option is initially not found.

Resolving patch:
diff --git a/src/meltano/cli/cli.py b/src/meltano/cli/cli.py
--- a/src/meltano/cli/cli.py
+++ b/src/meltano/cli/cli.py
@@ -47,6 +47,11 @@ def main(self, *args, **kwargs) -> t.NoReturn:
     cls=NoWindowsGlobbingGroup,
     invoke_without_command=True,
     no_args_is_help=True,
+    # For backwards compatibility, accept CLI options that use underscores
+    # instead of hyphens.
+    # https://github.com/pallets/click/issues/1123#issuecomment-589989721
+    # NOTE: This CLI option normalization applies to all subcommands.
+    context_settings={"token_normalize_func": lambda x: x.replace("_", "-")},
 )
 @click.option("--log-level", type=click.Choice(LEVELS.keys()))
 @click.option(
diff --git a/src/meltano/cli/initialize.py b/src/meltano/cli/initialize.py
--- a/src/meltano/cli/initialize.py
+++ b/src/meltano/cli/initialize.py
@@ -26,7 +26,7 @@
 @click.pass_context
 @click.argument("project_directory", required=False, type=path_type)
 @click.option(
-    "--no_usage_stats",
+    "--no-usage-stats",
     help="Do not send anonymous usage stats.",
     is_flag=True,
 )
diff --git a/src/meltano/cli/upgrade.py b/src/meltano/cli/upgrade.py
--- a/src/meltano/cli/upgrade.py
+++ b/src/meltano/cli/upgrade.py
@@ -43,7 +43,7 @@ def upgrade(ctx, project):
     short_help="Upgrade Meltano and your entire project to the latest version.",
 )
 @click.option(
-    "--pip_url",
+    "--pip-url",
     type=str,
     envvar="MELTANO_UPGRADE_PIP_URL",
     help="Meltano pip URL.",
@@ -114,7 +114,7 @@ def all(ctx, pip_url, force, skip_package):
 
 @upgrade.command(cls=InstrumentedCmd, short_help="Upgrade the Meltano package only.")
 @click.option(
-    "--pip_url",
+    "--pip-url",
     type=str,
     envvar="MELTANO_UPGRADE_PIP_URL",
     help="Meltano pip URL.",


Test patch:
diff --git a/tests/meltano/cli/test_initialize.py b/tests/meltano/cli/test_initialize.py
--- a/tests/meltano/cli/test_initialize.py
+++ b/tests/meltano/cli/test_initialize.py
@@ -18,7 +18,7 @@ def test_init(self, cli_runner, tmp_path_factory, pushd):  # noqa: WPS210
             Project.find()
 
         # Create a project with the CLI
-        cli_runner.invoke(cli, ["init", "test_project", "--no_usage_stats"])
+        cli_runner.invoke(cli, ["init", "test_project", "--no-usage-stats"])
 
         pushd("test_project")
         project = Project.find()
@@ -71,7 +71,7 @@ def test_init_existing_empty_directory(self, cli_runner, tmp_path_factory, pushd
         project_dir.mkdir()
         assert project_dir.exists()
 
-        result = cli_runner.invoke(cli, ["init", "test_project", "--no_usage_stats"])
+        result = cli_runner.invoke(cli, ["init", "test_project", "--no_usage-stats"])
         assert "Creating project files...\n  test_project/" in result.output
         assert "cd test_project" in result.output