Reuse name input logic and allow retry in data path input (#6696)

This commit is contained in:
Jakub Kuczys
2026-04-19 22:04:05 +02:00
committed by GitHub
parent 70faa8cd52
commit 169d0eed49
2 changed files with 65 additions and 84 deletions

View File

@@ -182,32 +182,10 @@ async def _edit_owner(red, owner, no_prompt):
def _edit_instance_name(old_name, new_name, confirm_overwrite, no_prompt):
if new_name:
name = new_name
if name in _get_instance_names() and not confirm_overwrite:
name = old_name
print(
"An instance with this name already exists.\n"
"If you want to remove the existing instance and replace it with this one,"
" run this command with --overwrite-existing-instance flag."
)
name = get_name(new_name, confirm_overwrite=confirm_overwrite)
elif not no_prompt and confirm("Would you like to change the instance name?", default=False):
name = get_name("")
if name in _get_instance_names():
print(
"WARNING: An instance already exists with this name. "
"Continuing will overwrite the existing instance config."
)
if not confirm(
"Are you absolutely certain you want to continue with this instance name?",
default=False,
):
print("Instance name will remain unchanged.")
name = old_name
else:
print("Instance name updated.")
else:
print("Instance name updated.")
print()
name = get_name(confirm_overwrite=confirm_overwrite)
print("Instance name updated.\n")
else:
name = old_name
return name

View File

@@ -61,9 +61,9 @@ def save_config(name, data, remove=False):
def get_data_dir(*, instance_name: str, data_path: Optional[Path], interactive: bool) -> str:
if data_path is not None:
return str(data_path.resolve())
data_path = Path(appdir.user_data_dir) / "data" / instance_name
default_data_path = Path(appdir.user_data_dir) / "data" / instance_name
if not interactive:
return str(data_path.resolve())
return str(default_data_path.resolve())
print(
"We've attempted to figure out a sane default data location which is printed below."
@@ -71,37 +71,40 @@ def get_data_dir(*, instance_name: str, data_path: Optional[Path], interactive:
" otherwise input your desired data location."
)
print()
print("Default: {}".format(data_path))
print(f"Default: {default_data_path}")
data_path_input = input("> ")
while True:
data_path_input = input("> ")
if data_path_input != "":
data_path = Path(data_path_input)
if data_path_input != "":
data_path = Path(data_path_input)
else:
data_path = default_data_path
try:
exists = data_path.exists()
except OSError:
print(
"We were unable to check your chosen directory."
" Provided path may contain an invalid character."
)
sys.exit(ExitCodes.INVALID_CLI_USAGE)
if not exists:
try:
data_path.mkdir(parents=True, exist_ok=True)
exists = data_path.exists()
except OSError:
print(
"We were unable to create your chosen directory."
" You may need to create the directory and set proper permissions"
" for it manually before it can be used as the data directory."
"We were unable to check your chosen directory."
" Provided path may contain an invalid character."
)
sys.exit(ExitCodes.INVALID_CLI_USAGE)
continue
if not exists:
try:
data_path.mkdir(parents=True, exist_ok=True)
except OSError:
print(
"We were unable to create your chosen directory."
" You may need to create the directory and set proper permissions"
" for it manually before it can be used as the data directory."
)
sys.exit(ExitCodes.INVALID_CLI_USAGE)
print(f"You have chosen {str(data_path)!r} to be your data directory.")
if click.confirm("Please confirm", default=True):
break
print("You have chosen {} to be your data directory.".format(data_path))
if not click.confirm("Please confirm", default=True):
print("Please start the process over.")
sys.exit(ExitCodes.CRITICAL)
return str(data_path.resolve())
@@ -132,18 +135,20 @@ def get_storage_type(backend: Optional[str], *, interactive: bool):
return storage_dict[storage]
def get_name(name: str) -> str:
INSTANCE_NAME_RE = re.compile(
r"""
[a-z0-9] # starts with letter or digit
(?:
(?!.*[_\.\-]{2}) # ensure no consecutive dots, hyphens, or underscores
[a-z0-9_\.\-]* # match allowed characters
[a-z0-9] # ensure string ends with letter or digit
)? # optional to allow strings of length 1
""",
re.VERBOSE | re.IGNORECASE,
)
INSTANCE_NAME_RE = re.compile(
r"""
[a-z0-9] # starts with letter or digit
(?:
(?!.*[_\.\-]{2}) # ensure no consecutive dots, hyphens, or underscores
[a-z0-9_\.\-]* # match allowed characters
[a-z0-9] # ensure string ends with letter or digit
)? # optional to allow strings of length 1
""",
re.VERBOSE | re.IGNORECASE,
)
def get_name(name: str = "", *, confirm_overwrite: bool = False) -> str:
if name:
if INSTANCE_NAME_RE.fullmatch(name) is None:
print(
@@ -152,9 +157,17 @@ def get_name(name: str) -> str:
" and non-consecutive underscores (_) and periods (.)."
)
sys.exit(ExitCodes.INVALID_CLI_USAGE)
if name in instance_data and not confirm_overwrite:
print(
"An instance with this name already exists.\n"
"If you want to remove the existing instance and replace it with this one,"
" run this command with --overwrite-existing-instance flag."
)
sys.exit(ExitCodes.INVALID_CLI_USAGE)
return name
while len(name) == 0:
name = ""
while not name:
print(
"Please enter a name for your instance,"
" it will be used to run your bot from here on out.\n"
@@ -177,6 +190,16 @@ def get_name(name: str) -> str:
default=False,
):
name = ""
elif name in instance_data and not confirm_overwrite:
print(
"WARNING: An instance already exists with this name."
" Continuing will overwrite the existing instance config."
)
if not click.confirm(
"Are you absolutely certain you want to continue with this instance name?",
default=False,
):
name = ""
print() # new line for aesthetics
return name
@@ -206,7 +229,7 @@ def basic_setup(
"Hello! Before we begin, we need to gather some initial information"
" for the new instance."
)
name = get_name(name)
name = get_name(name, confirm_overwrite=overwrite_existing_instance)
default_data_dir = get_data_dir(
instance_name=name, data_path=data_path, interactive=interactive
@@ -221,26 +244,6 @@ def basic_setup(
driver_cls = get_driver_class(storage_type)
default_dirs["STORAGE_DETAILS"] = driver_cls.get_config_details()
if name in instance_data:
if overwrite_existing_instance:
pass
elif interactive:
print(
"WARNING: An instance already exists with this name. "
"Continuing will overwrite the existing instance config."
)
if not click.confirm(
"Are you absolutely certain you want to continue?", default=False
):
print("Not continuing")
sys.exit(ExitCodes.SHUTDOWN)
else:
print(
"An instance with this name already exists.\n"
"If you want to remove the existing instance and replace it with this one,"
" run this command with --overwrite-existing-instance flag."
)
sys.exit(ExitCodes.INVALID_CLI_USAGE)
save_config(name, default_dirs)
if interactive: