From ccbf216aaf6e10d60e3138cbbed93359acfe71a2 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Wed, 28 Sep 2022 18:55:04 +0200 Subject: reorganize updater CLI This moves the updater scripts into a subfolder, which keeps them separated better from the rest of the package. In addition, we now have the "fietsupdate" command instead of using "python -m fietsboek.updater". --- fietsboek/updater/__init__.py | 4 +- fietsboek/updater/__main__.py | 137 ------------------------------------------ fietsboek/updater/cli.py | 137 ++++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 4 files changed, 140 insertions(+), 139 deletions(-) delete mode 100644 fietsboek/updater/__main__.py create mode 100644 fietsboek/updater/cli.py diff --git a/fietsboek/updater/__init__.py b/fietsboek/updater/__init__.py index 038fcd5..724defa 100644 --- a/fietsboek/updater/__init__.py +++ b/fietsboek/updater/__init__.py @@ -244,7 +244,7 @@ class Updater: ) filename = f"upd_{revision_id}.py" - filepath = Path(__file__).parent / filename + filepath = Path(__file__).parent / "scripts" / filename LOGGER.info("Writing new revision (%s) to %r", revision_id, filepath) with open(filepath, "x", encoding="utf-8") as fobj: fobj.write(revision) @@ -346,7 +346,7 @@ def _filename_to_modname(name): def _load_update_scripts(): """Loads all available import scripts.""" - files = importlib_resources.files(__name__) + files = importlib_resources.files(__name__) / "scripts" return [ UpdateScript(file.read_text(), _filename_to_modname(file.name)) for file in files.iterdir() diff --git a/fietsboek/updater/__main__.py b/fietsboek/updater/__main__.py deleted file mode 100644 index 38297d7..0000000 --- a/fietsboek/updater/__main__.py +++ /dev/null @@ -1,137 +0,0 @@ -"""Updater for Fietsboek. - -While this script does not download and install the latest Fietsboek version -itself (as this step depends on where you got Fietsboek from), it takes care of -managing migrations between Fietsboek versions. In particular, the updater -takes care of running the database migrations, migrating the data directory and -migrating the configuration. -""" -import click - -from pyramid.paster import setup_logging - -from . import Updater - - -def user_confirm(): - click.secho("Warning:", fg="yellow") - click.echo( - "Updating *may* cause data loss. Make sure to have a backup of the " - "database and the data directory!" - ) - click.echo("For more information, please consult the documentation.") - click.confirm("Proceed?", abort=True) - - -@click.group(help=__doc__) -@click.option( - "-c", "--config", - type=click.Path(exists=True, dir_okay=False), - required=True, - help="Path to the Fietsboek configuration file", -) -@click.pass_context -def cli(ctx, config): - ctx.ensure_object(dict) - setup_logging(config) - ctx.obj["INIFILE"] = config - - -@cli.command("update") -@click.option( - "-f", "--force", - is_flag=True, - help="Skip the safety question and just run the update", -) -@click.argument("VERSION", required=False) -@click.pass_context -def update(ctx, version, force): - """Run the update process. - - Make sure to consult the documentation and ensure that you have a backup - before starting the update, to prevent any data loss! - - VERSION specifies the version you want to update to. Leave empty to choose - the latest version. - """ - updater = Updater(ctx.obj["INIFILE"]) - updater.load() - if version and not updater.exists(version): - click.secho("Revision not found", fg="red") - return - version_str = ", ".join(updater.current_versions()) - click.echo(f"Current version: {version_str}") - if not version: - heads = updater.heads() - if len(heads) != 1: - click.secho("Ambiguous heads, please specify the version to update to", fg="red") - return - version = heads[0] - click.echo(f"Selected version: {version}") - if not force: - user_confirm() - updater.upgrade(version) - version_str = ", ".join(updater.current_versions()) - click.secho(f"Update succeeded, version: {version_str}", fg="green") - - -@cli.command("downgrade") -@click.option( - "-f", "--force", - is_flag=True, - help="Skip the safety question and just run the downgrade", -) -@click.argument("VERSION") -@click.pass_context -def downgrade(ctx, version, force): - """Run the downgrade process. - - Make sure to consult the documentation and ensure that you have a backup - before starting the downgrade, to prevent any data loss! - - VERSION specifies the version you want to downgrade to. - """ - updater = Updater(ctx.obj["INIFILE"]) - updater.load() - if version and not updater.exists(version): - click.secho("Revision not found", fg="red") - return - version_str = ", ".join(updater.current_versions()) - click.echo(f"Current version: {version_str}") - click.echo(f"Downgrade to version {version}") - if not force: - user_confirm() - updater.downgrade(version) - version_str = ", ".join(updater.current_versions()) - click.secho(f"Downgrade succeeded, version: {version_str}", fg="green") - - -@cli.command("revision") -@click.argument("REVISION_ID", required=False) -@click.pass_context -def revision(ctx, revision_id): - """Create a new revision. - - This automatically populates the revision dependencies and alembic - versions, based on the current state. - - This command is useful for developers who work on Fietsboek. - """ - updater = Updater(ctx.obj["INIFILE"]) - updater.load() - current = updater.current_versions() - heads = updater.heads() - if not any(version in heads for version in current): - click.secho("Warning:", fg="yellow") - click.echo("Your current revision is not a head. This will create a branch!") - click.echo( - "If this is not what you intended, make sure to update to the latest " - "version first before creating a new revision." - ) - click.confirm("Proceed?", abort=True) - filename = updater.new_revision(revision_id) - click.echo(f"Revision saved to {filename}") - - -if __name__ == "__main__": - cli() diff --git a/fietsboek/updater/cli.py b/fietsboek/updater/cli.py new file mode 100644 index 0000000..38297d7 --- /dev/null +++ b/fietsboek/updater/cli.py @@ -0,0 +1,137 @@ +"""Updater for Fietsboek. + +While this script does not download and install the latest Fietsboek version +itself (as this step depends on where you got Fietsboek from), it takes care of +managing migrations between Fietsboek versions. In particular, the updater +takes care of running the database migrations, migrating the data directory and +migrating the configuration. +""" +import click + +from pyramid.paster import setup_logging + +from . import Updater + + +def user_confirm(): + click.secho("Warning:", fg="yellow") + click.echo( + "Updating *may* cause data loss. Make sure to have a backup of the " + "database and the data directory!" + ) + click.echo("For more information, please consult the documentation.") + click.confirm("Proceed?", abort=True) + + +@click.group(help=__doc__) +@click.option( + "-c", "--config", + type=click.Path(exists=True, dir_okay=False), + required=True, + help="Path to the Fietsboek configuration file", +) +@click.pass_context +def cli(ctx, config): + ctx.ensure_object(dict) + setup_logging(config) + ctx.obj["INIFILE"] = config + + +@cli.command("update") +@click.option( + "-f", "--force", + is_flag=True, + help="Skip the safety question and just run the update", +) +@click.argument("VERSION", required=False) +@click.pass_context +def update(ctx, version, force): + """Run the update process. + + Make sure to consult the documentation and ensure that you have a backup + before starting the update, to prevent any data loss! + + VERSION specifies the version you want to update to. Leave empty to choose + the latest version. + """ + updater = Updater(ctx.obj["INIFILE"]) + updater.load() + if version and not updater.exists(version): + click.secho("Revision not found", fg="red") + return + version_str = ", ".join(updater.current_versions()) + click.echo(f"Current version: {version_str}") + if not version: + heads = updater.heads() + if len(heads) != 1: + click.secho("Ambiguous heads, please specify the version to update to", fg="red") + return + version = heads[0] + click.echo(f"Selected version: {version}") + if not force: + user_confirm() + updater.upgrade(version) + version_str = ", ".join(updater.current_versions()) + click.secho(f"Update succeeded, version: {version_str}", fg="green") + + +@cli.command("downgrade") +@click.option( + "-f", "--force", + is_flag=True, + help="Skip the safety question and just run the downgrade", +) +@click.argument("VERSION") +@click.pass_context +def downgrade(ctx, version, force): + """Run the downgrade process. + + Make sure to consult the documentation and ensure that you have a backup + before starting the downgrade, to prevent any data loss! + + VERSION specifies the version you want to downgrade to. + """ + updater = Updater(ctx.obj["INIFILE"]) + updater.load() + if version and not updater.exists(version): + click.secho("Revision not found", fg="red") + return + version_str = ", ".join(updater.current_versions()) + click.echo(f"Current version: {version_str}") + click.echo(f"Downgrade to version {version}") + if not force: + user_confirm() + updater.downgrade(version) + version_str = ", ".join(updater.current_versions()) + click.secho(f"Downgrade succeeded, version: {version_str}", fg="green") + + +@cli.command("revision") +@click.argument("REVISION_ID", required=False) +@click.pass_context +def revision(ctx, revision_id): + """Create a new revision. + + This automatically populates the revision dependencies and alembic + versions, based on the current state. + + This command is useful for developers who work on Fietsboek. + """ + updater = Updater(ctx.obj["INIFILE"]) + updater.load() + current = updater.current_versions() + heads = updater.heads() + if not any(version in heads for version in current): + click.secho("Warning:", fg="yellow") + click.echo("Your current revision is not a head. This will create a branch!") + click.echo( + "If this is not what you intended, make sure to update to the latest " + "version first before creating a new revision." + ) + click.confirm("Proceed?", abort=True) + filename = updater.new_revision(revision_id) + click.echo(f"Revision saved to {filename}") + + +if __name__ == "__main__": + cli() diff --git a/setup.py b/setup.py index ad759ef..5fd76e0 100644 --- a/setup.py +++ b/setup.py @@ -63,6 +63,7 @@ setup( ], 'console_scripts': [ 'fietsctl=fietsboek.scripts.fietsctl:main', + 'fietsupdate=fietsboek.updater.cli:cli', ], }, ) -- cgit v1.2.3