]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Revert alembic.stamp "revisions" to "revision"
authorThomas Bechtold <tbechtold@suse.com>
Tue, 24 Sep 2019 14:27:03 +0000 (10:27 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 24 Sep 2019 15:42:40 +0000 (11:42 -0400)
Reverted the name change of the "revisions" argument to
:func:`.command.stamp` to "revision" as apparently applications are
calling upon this argument as a keyword name.  Pull request courtesy
Thomas Bechtold.  Special translations are also added to the command
line interface so that it is still known as "revisions" in the CLI.

Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com>
Fixes: #601
Closes: #602
Pull-request: https://github.com/sqlalchemy/alembic/pull/602
Pull-request-sha: 4126635e272f82ec53d630bb77c00cb6ff42cec9

Change-Id: I4312954bedc42bb4b76656a70c95b2b7280efae7

alembic/command.py
alembic/config.py
docs/build/unreleased/601.rst [new file with mode: 0644]
tests/test_command.py

index d4acfdbf12a43b69acf0d99dfd72489f92bc3fb4..7d19e3c6b61a8366026e95694dc24f27efd7b71b 100644 (file)
@@ -515,13 +515,20 @@ def current(config, verbose=False, head_only=False):
         script.run_env()
 
 
-def stamp(config, revisions, sql=False, tag=None, purge=False):
+def stamp(config, revision, sql=False, tag=None, purge=False):
     """'stamp' the revision table with the given revision; don't
     run any migrations.
 
     :param config: a :class:`.Config` instance.
 
-    :param revision: target revision.
+    :param revision: target revision or list of revisions.   May be a list
+     to indicate stamping of multiple branch heads.
+
+     .. note:: this parameter is called "revisions" in the command line
+        interface.
+
+     .. versionchanged:: 1.2  The revision may be a single revision or
+        list of revisions when stamping multiple branch heads.
 
     :param sql: use ``--sql`` mode
 
@@ -540,9 +547,9 @@ def stamp(config, revisions, sql=False, tag=None, purge=False):
     if sql:
         destination_revs = []
         starting_rev = None
-        for revision in util.to_list(revisions):
-            if ":" in revision:
-                srev, revision = revision.split(":", 2)
+        for _revision in util.to_list(revision):
+            if ":" in _revision:
+                srev, _revision = _revision.split(":", 2)
 
                 if starting_rev != srev:
                     if starting_rev is None:
@@ -552,9 +559,9 @@ def stamp(config, revisions, sql=False, tag=None, purge=False):
                             "Stamp operation with --sql only supports a "
                             "single starting revision at a time"
                         )
-            destination_revs.append(revision)
+            destination_revs.append(_revision)
     else:
-        destination_revs = util.to_list(revisions)
+        destination_revs = util.to_list(revision)
 
     def do_stamp(rev, context):
         return script._stamp_revs(util.to_tuple(destination_revs), rev)
index 2232096149ca45f879e8f56edaed990c647e2b14..b0700d56914e324b2e1182f134a51a8d2154a839 100644 (file)
@@ -296,7 +296,7 @@ class CommandLine(object):
         self._generate_args(prog)
 
     def _generate_args(self, prog):
-        def add_options(parser, positional, kwargs):
+        def add_options(fn, parser, positional, kwargs):
             kwargs_opts = {
                 "template": (
                     "-t",
@@ -454,9 +454,15 @@ class CommandLine(object):
                     parser.add_argument(*args, **kw)
 
             for arg in positional:
-                if arg == "revisions":
+                if (
+                    arg == "revisions"
+                    or fn in positional_translations
+                    and positional_translations[fn][arg] == "revisions"
+                ):
                     subparser.add_argument(
-                        arg, nargs="+", help=positional_help.get(arg)
+                        "revisions",
+                        nargs="+",
+                        help=positional_help.get("revisions"),
                     )
                 else:
                     subparser.add_argument(arg, help=positional_help.get(arg))
@@ -490,6 +496,8 @@ class CommandLine(object):
         )
         subparsers = parser.add_subparsers()
 
+        positional_translations = {command.stamp: {"revision": "revisions"}}
+
         for fn in [getattr(command, n) for n in dir(command)]:
             if (
                 inspect.isfunction(fn)
@@ -505,6 +513,12 @@ class CommandLine(object):
                     positional = spec[0][1:]
                     kwarg = []
 
+                if fn in positional_translations:
+                    positional = [
+                        positional_translations[fn].get(name, name)
+                        for name in positional
+                    ]
+
                 # parse first line(s) of helptext without a line break
                 help_ = fn.__doc__
                 if help_:
@@ -519,7 +533,7 @@ class CommandLine(object):
                 subparser = subparsers.add_parser(
                     fn.__name__, help=" ".join(help_text)
                 )
-                add_options(subparser, positional, kwarg)
+                add_options(fn, subparser, positional, kwarg)
                 subparser.set_defaults(cmd=(fn, positional, kwarg))
         self.parser = parser
 
diff --git a/docs/build/unreleased/601.rst b/docs/build/unreleased/601.rst
new file mode 100644 (file)
index 0000000..5e89f39
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, command
+    :tickets: 601
+
+    Reverted the name change of the "revisions" argument to
+    :func:`.command.stamp` to "revision" as apparently applications are
+    calling upon this argument as a keyword name.  Pull request courtesy
+    Thomas Bechtold.  Special translations are also added to the command
+    line interface so that it is still known as "revisions" in the CLI.
index e09347925b71c6b4e3002ef663c0172ef4773c02..2aeb28c8debbdd588e87068e9f095ac0bc33d614 100644 (file)
@@ -765,6 +765,41 @@ class UpgradeDowngradeStampTest(TestBase):
             "WHERE alembic_version.version_num = '%s';" % (self.c, self.a)
         ) in buf.getvalue()
 
+    def test_sql_stamp_revision_as_kw(self):
+        with capture_context_buffer() as buf:
+            command.stamp(self.cfg, revision="head", sql=True)
+        assert (
+            "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.c
+            in buf.getvalue()
+        )
+
+    def test_stamp_argparser_single_rev(self):
+        cmd = config.CommandLine()
+        options = cmd.parser.parse_args(["stamp", self.c, "--sql"])
+        with capture_context_buffer() as buf:
+            cmd.run_cmd(self.cfg, options)
+        assert (
+            "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.c
+            in buf.getvalue()
+        )
+
+    def test_stamp_argparser_multiple_rev(self):
+        cmd = config.CommandLine()
+        options = cmd.parser.parse_args(["stamp", self.b, self.c, "--sql"])
+        with capture_context_buffer() as buf:
+            cmd.run_cmd(self.cfg, options)
+        # TODO: this is still wrong, as this stamp command is putting
+        # conflicting heads into the table.   The test here is only to test
+        # that the revisions are passed as a list.
+        assert (
+            "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.b
+            in buf.getvalue()
+        )
+        assert (
+            "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.c
+            in buf.getvalue()
+        )
+
 
 class LiveStampTest(TestBase):
     __only_on__ = "sqlite"