From e39789009828b398a47d58d783dfdfd11e388967 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 29 Dec 2025 12:49:39 -0600 Subject: [PATCH] feat: add support for `--comment` CLI param, to set versioning comment only relevant if Wutta-Continuum is enabled --- src/wuttasync/cli/base.py | 4 +++- src/wuttasync/cli/import_versions.py | 9 +-------- src/wuttasync/importing/handlers.py | 27 ++++++++++++++++++++++++--- src/wuttasync/importing/versions.py | 11 ++--------- tests/cli/test_base.py | 12 ++++++++++-- tests/importing/test_handlers.py | 8 ++++++++ tests/importing/test_versions.py | 16 +--------------- 7 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/wuttasync/cli/base.py b/src/wuttasync/cli/base.py index 032131a..34be0e7 100644 --- a/src/wuttasync/cli/base.py +++ b/src/wuttasync/cli/base.py @@ -129,9 +129,11 @@ class ImportCommandHandler(GenericHandler): # all params from caller will be passed along kw = dict(ctx.params) - # runas user also, but it comes from root/parent command + # runas user and comment also, but they come from root command if username := ctx.parent.params.get("runas_username"): kw["runas_username"] = username + if comment := ctx.parent.params.get("comment"): + kw["transaction_comment"] = comment # sort out which models to process models = kw.pop("models") diff --git a/src/wuttasync/cli/import_versions.py b/src/wuttasync/cli/import_versions.py index 11c9863..0057e88 100644 --- a/src/wuttasync/cli/import_versions.py +++ b/src/wuttasync/cli/import_versions.py @@ -37,14 +37,7 @@ from .base import import_command, ImportCommandHandler @wutta_typer.command() @import_command -def import_versions( # pylint: disable=unused-argument - ctx: typer.Context, - comment: Annotated[ - str, - typer.Option("--comment", "-m", help="Comment to set on the transaction."), - ] = "import catch-up versions", - **kwargs, -): +def import_versions(ctx: typer.Context, **kwargs): # pylint: disable=unused-argument """ Import latest data to version tables, for Wutta DB """ diff --git a/src/wuttasync/importing/handlers.py b/src/wuttasync/importing/handlers.py index 6ae09ba..384fbd3 100644 --- a/src/wuttasync/importing/handlers.py +++ b/src/wuttasync/importing/handlers.py @@ -172,6 +172,12 @@ class ImportHandler(GenericHandler): # pylint: disable=too-many-public-methods mostly used for Continuum versioning. """ + transaction_comment = None + """ + Optional comment to apply to the transaction, where applicable. + This is mostly used for Continuum versioning. + """ + importers = None """ This should be a dict of all importer/exporter classes available @@ -425,6 +431,9 @@ class ImportHandler(GenericHandler): # pylint: disable=too-many-public-methods if "runas_username" in kwargs: self.runas_username = kwargs.pop("runas_username") + if "transaction_comment" in kwargs: + self.transaction_comment = kwargs.pop("transaction_comment") + return kwargs def begin_transaction(self): @@ -959,18 +968,26 @@ class ToWuttaHandler(ToSqlalchemyHandler): calling :meth:`~wuttjamaican:wuttjamaican.app.AppHandler.make_session()`. + It then may "customize" the session slightly. These + customizations only are relevant if Wutta-Continuum versioning + is enabled: + If :attr:`~ImportHandler.runas_username` is set, the responsible user (``continuum_user_id``) will be set for the - new session as well. This info is only used if the - Wutta-Continuum versioning feature is enabled. + new session as well. + + Similarly, if :attr:`~ImportHandler.transaction_comment` is + set, it (``continuum_comment``) will also be set for the new + session. :returns: :class:`~wuttjamaican:wuttjamaican.db.sess.Session` instance. """ + model = self.app.model session = self.app.make_session() + # set runas user in case continuum versioning is enabled if self.runas_username: - model = self.app.model if user := ( session.query(model.User) .filter_by(username=self.runas_username) @@ -980,4 +997,8 @@ class ToWuttaHandler(ToSqlalchemyHandler): else: log.warning("runas username not found: %s", self.runas_username) + # set comment in case continuum versioning is enabled + if self.transaction_comment: + session.info["continuum_comment"] = self.transaction_comment + return session diff --git a/src/wuttasync/importing/versions.py b/src/wuttasync/importing/versions.py index cda77c9..d558c36 100644 --- a/src/wuttasync/importing/versions.py +++ b/src/wuttasync/importing/versions.py @@ -92,13 +92,6 @@ class FromWuttaToVersions(FromWuttaHandler, ToWuttaHandler): See also :attr:`continuum_uow`. """ - continuum_comment = None - - def consume_kwargs(self, kwargs): - kwargs = super().consume_kwargs(kwargs) - self.continuum_comment = kwargs.pop("comment", None) - return kwargs - def begin_target_transaction(self): # pylint: disable=line-too-long """ @@ -128,8 +121,8 @@ class FromWuttaToVersions(FromWuttaHandler, ToWuttaHandler): self.continuum_txn = self.continuum_uow.create_transaction(self.target_session) - if self.continuum_comment: - self.continuum_txn.meta = {"comment": self.continuum_comment} + if self.transaction_comment: + self.continuum_txn.meta = {"comment": self.transaction_comment} def get_importer_kwargs(self, key, **kwargs): """ diff --git a/tests/cli/test_base.py b/tests/cli/test_base.py index 367eaea..2370bdd 100644 --- a/tests/cli/test_base.py +++ b/tests/cli/test_base.py @@ -53,11 +53,19 @@ class TestImportCommandHandler(DataTestCase): self.__dict__.update(kw) with patch.object(handler, "import_handler") as import_handler: - parent = Mock(params={"runas_username": "fred"}) + parent = Mock( + params={ + "runas_username": "fred", + "comment": "hello world", + } + ) # TODO: why can't we just use Mock here? the parent attr is problematic ctx = Object(params={"models": []}, parent=parent) handler.run(ctx) - import_handler.process_data.assert_called_once_with(runas_username="fred") + import_handler.process_data.assert_called_once_with( + runas_username="fred", + transaction_comment="hello world", + ) def test_list_models(self): handler = self.make_handler( diff --git a/tests/importing/test_handlers.py b/tests/importing/test_handlers.py index 2bcbfbb..21fcaeb 100644 --- a/tests/importing/test_handlers.py +++ b/tests/importing/test_handlers.py @@ -198,6 +198,14 @@ class TestImportHandler(DataTestCase): self.assertNotIn("runas_username", kw) self.assertEqual(handler.runas_username, "fred") + # transaction_comment (consumed) + self.assertIsNone(handler.transaction_comment) + kw["transaction_comment"] = "hello world" + result = handler.consume_kwargs(kw) + self.assertIs(result, kw) + self.assertNotIn("transaction_comment", kw) + self.assertEqual(handler.transaction_comment, "hello world") + def test_define_importers(self): handler = self.make_handler() importers = handler.define_importers() diff --git a/tests/importing/test_versions.py b/tests/importing/test_versions.py index 2cd4ec0..eea6171 100644 --- a/tests/importing/test_versions.py +++ b/tests/importing/test_versions.py @@ -14,20 +14,6 @@ class TestFromWuttaToVersions(VersionTestCase): def make_handler(self, **kwargs): return mod.FromWuttaToVersions(self.config, **kwargs) - def test_consume_kwargs(self): - - # no comment by default - handler = self.make_handler() - kw = handler.consume_kwargs({}) - self.assertEqual(kw, {}) - self.assertIsNone(handler.continuum_comment) - - # but can provide one - handler = self.make_handler() - kw = handler.consume_kwargs({"comment": "yeehaw"}) - self.assertEqual(kw, {}) - self.assertEqual(handler.continuum_comment, "yeehaw") - def test_begin_target_transaction(self): model = self.app.model txncls = continuum.transaction_class(model.User) @@ -44,7 +30,7 @@ class TestFromWuttaToVersions(VersionTestCase): # with comment handler = self.make_handler() - handler.continuum_comment = "yeehaw" + handler.transaction_comment = "yeehaw" handler.begin_target_transaction() self.assertIn("comment", handler.continuum_txn.meta) self.assertEqual(handler.continuum_txn.meta["comment"], "yeehaw")