diff --git a/nucypher/cli/actions/select.py b/nucypher/cli/actions/select.py index e4b6f764b..ec6d51327 100644 --- a/nucypher/cli/actions/select.py +++ b/nucypher/cli/actions/select.py @@ -14,9 +14,11 @@ from nucypher.cli.actions.migrate import migrate from nucypher.cli.literature import ( DEFAULT_TO_LONE_CONFIG_FILE, GENERIC_SELECT_ACCOUNT, + IGNORE_OLD_CONFIGURATION, MIGRATE_OLD_CONFIGURATION, NO_ACCOUNTS, NO_CONFIGURATIONS_ON_DISK, + PROMPT_TO_MIGRATE, SELECT_DOMAIN, SELECTED_ACCOUNT, ) @@ -117,11 +119,13 @@ def select_domain(emitter: StdoutEmitter, message: Optional[str] = None) -> str: return domain -def select_config_file(emitter: StdoutEmitter, - config_class: Type[CharacterConfiguration], - config_root: Optional[Path] = None, - checksum_address: str = None, - ) -> Path: +def select_config_file( + emitter: StdoutEmitter, + config_class: Type[CharacterConfiguration], + config_root: Optional[Path] = None, + checksum_address: str = None, + do_auto_migrate: bool = False, +) -> Path: """ Selects a nucypher character configuration file from the disk automatically or interactively. @@ -136,6 +140,10 @@ def select_config_file(emitter: StdoutEmitter, - If there are multiple character configurations on the disk in the same configuration root, use interactive selection. + - If the configuration file is old and: + 1. `do_auto_migration` is False then prompt user + 2. `do_auto_migration` is True then try migrating the file, and retry loading + - Aborts if there are no configurations associated with the supplied character configuration class. """ @@ -165,14 +173,27 @@ def select_config_file(emitter: StdoutEmitter, parsed_config_files.append(fp) parsed_addresses_and_filenames.append([config_checksum_address, Path(fp).name]) # store checksum & filename except config_class.OldVersion as e: - # attempt migration - emitter.echo( - MIGRATE_OLD_CONFIGURATION.format(config_file=fp, version=e.version), - color="yellow", - ) - migrate(emitter=emitter, config_file=fp) - # retry migrated file - continue + attempt_migration = True + if not do_auto_migrate: + if not click.confirm( + PROMPT_TO_MIGRATE.format(config_file=fp, version=e.version) + ): + emitter.echo( + IGNORE_OLD_CONFIGURATION.format( + config_file=fp, version=e.version + ), + color="yellow", + ) + attempt_migration = False + + if attempt_migration: + emitter.echo( + MIGRATE_OLD_CONFIGURATION.format(config_file=fp, version=e.version), + color="yellow", + ) + migrate(emitter=emitter, config_file=fp) + # retry reading migrated file + continue i += 1 diff --git a/nucypher/cli/commands/ursula.py b/nucypher/cli/commands/ursula.py index d5e7e6be2..783a4b9cb 100644 --- a/nucypher/cli/commands/ursula.py +++ b/nucypher/cli/commands/ursula.py @@ -120,9 +120,12 @@ class UrsulaConfigOptions: ) else: if not config_file: - config_file = select_config_file(emitter=emitter, - checksum_address=self.operator_address, - config_class=UrsulaConfiguration) + config_file = select_config_file( + emitter=emitter, + checksum_address=self.operator_address, + config_class=UrsulaConfiguration, + do_auto_migrate=True, + ) try: return UrsulaConfiguration.from_configuration_file( emitter=emitter, diff --git a/nucypher/cli/literature.py b/nucypher/cli/literature.py index 1a622c884..64006a581 100644 --- a/nucypher/cli/literature.py +++ b/nucypher/cli/literature.py @@ -38,9 +38,17 @@ SUCCESSFUL_DESTRUCTION = "Successfully destroyed nucypher configuration" CONFIRM_FORGET_NODES = "Permanently delete all known node data?" SUCCESSFUL_FORGET_NODES = "Removed all stored known nodes metadata and certificates" +IGNORE_OLD_CONFIGURATION = """ +Ignoring configuration file '{config_file}' whose version is too old ('{version}'). +Run `nucypher ursula config migrate --config-file '{config_file}'` to update it. +""" MIGRATE_OLD_CONFIGURATION = """ Migrating configuration file '{config_file}' whose version ('{version}') is too old. """ +PROMPT_TO_MIGRATE = """ +Detected configuration file '{config_file}' with old version ('{version}'). Would you +like to migrate this file to the newest version? +""" DEFAULT_TO_LONE_CONFIG_FILE = "Defaulting to {config_class} configuration file: '{config_file}'" # Authentication