-
Notifications
You must be signed in to change notification settings - Fork 2
add support for arrow key selection #37
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
base: main
Are you sure you want to change the base?
Changes from all commits
902aba7
4b4f451
cf66ea7
8d53f0a
8324e99
341f19e
414728c
22fbbf1
3dfb398
f8b5065
ad2864b
df5d02d
041a864
260f4d0
8d17a7e
8cee466
d72b43b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| import sys | ||
| from typing import Any | ||
|
|
||
| import click | ||
| import questionary | ||
| from databao_context_engine import Choice, UserInputCallback | ||
|
|
||
|
|
||
|
|
@@ -15,19 +17,70 @@ def prompt( | |
| show_default: bool = default_value is not None and default_value != "" | ||
| final_type = click.Choice(type.choices) if isinstance(type, Choice) else str | ||
|
|
||
| # click goes infinite loop if user gives emptry string as an input AND default_value is None | ||
| # in order to exit this loop we need to set default value to '' (so it gets accepted) | ||
| # | ||
| # Code snippet from click: | ||
| # while True: | ||
| # value = prompt_func(prompt) | ||
| # if value: | ||
| # break | ||
| # elif default is not None: | ||
| # value = default | ||
| # break | ||
| default_value = default_value if default_value else "" if final_type is str else None | ||
| return click.prompt(text=text, default=default_value, hide_input=is_secret, type=final_type, show_default=show_default) | ||
| # Determine if this field is optional | ||
| is_optional = "(Optional)" in text | ||
|
|
||
| if isinstance(type, Choice): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hsestupin Since this is a special case that will need to be handled by every There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding this PR, just looking very briefly, the code would would benefit from extracting the code specific to Choice into its own method (ie. extract everything below into a |
||
| is_interactive = sys.stdin.isatty() and sys.stdout.isatty() | ||
| if is_interactive: | ||
| from databao_cli.labels import LABELS | ||
|
|
||
| choices = [questionary.Choice(title=LABELS.get(choice, choice), value=choice) for choice in type.choices] | ||
| result = questionary.select( | ||
| text, | ||
| choices=choices, | ||
| default=default_value if default_value is not None and default_value in type.choices else None, | ||
| ).ask() | ||
| if result is None: | ||
| raise click.Abort() | ||
| return result | ||
| else: | ||
| return click.prompt( | ||
| text=text, | ||
| default=default_value, | ||
| hide_input=is_secret, | ||
| type=click.Choice(type.choices), | ||
| show_default=show_default, | ||
| ) | ||
|
|
||
| if default_value: | ||
| final_default = default_value | ||
| elif is_optional: | ||
| final_default = "" | ||
| else: | ||
| final_default = None | ||
|
|
||
| is_interactive = sys.stdin.isatty() and sys.stdout.isatty() | ||
| if is_interactive and final_type is str: | ||
| prompt_func = questionary.password if is_secret else questionary.text | ||
|
|
||
| if not is_optional and final_default is None: | ||
| while True: | ||
| result = prompt_func(text, default=final_default or "").ask() | ||
| if result is None: | ||
| raise click.Abort() | ||
| value = str(result).strip() | ||
| if value: | ||
| return value | ||
| click.echo("This field is required and cannot be empty. Please try again.") | ||
| else: | ||
| result = prompt_func(text, default=final_default or "").ask() | ||
| if result is None: | ||
| raise click.Abort() | ||
| return str(result) | ||
| else: | ||
| if final_type is str and not is_optional and final_default is None: | ||
| while True: | ||
| value = click.prompt( | ||
| text=text, default=final_default, hide_input=is_secret, type=final_type, show_default=show_default | ||
| ) | ||
| if value and value.strip(): | ||
| return value | ||
| click.echo("This field is required and cannot be empty. Please try again.") | ||
| else: | ||
| return click.prompt( | ||
| text=text, default=final_default, hide_input=is_secret, type=final_type, show_default=show_default | ||
| ) | ||
|
|
||
| def confirm(self, text: str) -> bool: | ||
| return click.confirm(text=text) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| LABELS = { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This map should not exist. This is unmaintainable. This will break every time we update something in Config objects. |
||
| "athena": "Amazon Athena", | ||
| "bigquery": "BigQuery", | ||
| "clickhouse": "ClickHouse", | ||
| "duckdb": "DuckDB", | ||
| "mssql": "Microsoft SQL Server", | ||
| "mysql": "MySQL", | ||
| "parquet": "Parquet", | ||
| "postgres": "PostgreSQL", | ||
| "snowflake": "Snowflake", | ||
| "sqlite": "SQLite", | ||
| "BigQueryDefaultAuth": "Default auth", | ||
| "BigQueryServiceAccountJsonAuth": "Service account JSON credentials", | ||
| "BigQueryServiceAccountKeyFileAuth": "Service account key file", | ||
| "SnowflakeKeyPairAuth": "Key pair", | ||
| "SnowflakePasswordAuth": "Password", | ||
| "SnowflakeSSOAuth": "SSO", | ||
| "connection.auth.type": "Authentication type", | ||
| "connection.host": "Host", | ||
| "connection.port": "Port", | ||
| "connection.database": "Database", | ||
| "connection.schema": "Schema", | ||
| "connection.username": "Username", | ||
| "connection.password": "Password", | ||
| "connection.account": "Account", | ||
| "connection.warehouse": "Warehouse", | ||
| "connection.role": "Role", | ||
| "connection.path": "File path", | ||
| "connection.project": "Project", | ||
| "connection.dataset": "Dataset", | ||
| "connection.location": "Location", | ||
| "connection.auth.credentials_file": "Credentials file", | ||
| "connection.auth.key_file": "Key file", | ||
| "connection.auth.token": "Token", | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😱 sorry we were not providing this information...
I've made some changes yesterday and it will be included in the next version:
JetBrains/databao-context-engine#162