]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- changelog for pullrequest bitbucket:46; "alembic edit" command
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Jul 2015 18:09:47 +0000 (14:09 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Jul 2015 18:09:47 +0000 (14:09 -0400)
edits migration files using $EDITOR
- alter the edit command so that it accepts an argument in the same
way as ``alembic show``.

alembic/command.py
alembic/util/__init__.py
alembic/util/pyfiles.py
docs/build/changelog.rst
tests/test_command.py

index 13d8a570301665c8af1301077bc8f7ca1db09cac..6b2bc336a02c0dc177f550648637731da15bae97 100644 (file)
@@ -5,8 +5,6 @@ from .runtime.environment import EnvironmentContext
 from . import util
 from . import autogenerate as autogen
 
-import editor
-
 
 def list_templates(config):
     """List available templates"""
@@ -357,14 +355,29 @@ def stamp(config, revision, sql=False, tag=None):
         script.run_env()
 
 
-def edit(config):
-    """Edit the latest ervision"""
+def edit(config, rev):
+    """Edit revision script(s) using $EDITOR"""
 
     script = ScriptDirectory.from_config(config)
-    revisions = script.walk_revisions()
-    head = next(revisions)
 
-    try:
-        editor.edit(head.path)
-    except Exception as exc:
-        raise util.CommandError('Error executing editor (%s)' % (exc,))
+    if rev == "current":
+        def edit_current(rev, context):
+            if not rev:
+                raise util.CommandError("No current revisions")
+            for sc in script.get_revisions(rev):
+                util.edit(sc.path)
+            return []
+        with EnvironmentContext(
+            config,
+            script,
+            fn=edit_current
+        ):
+            script.run_env()
+    else:
+        revs = script.get_revisions(rev)
+        if not revs:
+            raise util.CommandError(
+                "No revision files indicated by symbol '%s'" % rev)
+        for sc in revs:
+            util.edit(sc.path)
+
index bd7196ce4749dc3e4930d8687b5f4aad1deb270b..ff08ad9c4fbc7f9be15e7fb4d1bbd1d4bc93cd8a 100644 (file)
@@ -5,7 +5,7 @@ from .messaging import (  # noqa
     write_outstream, status, err, obfuscate_url_pw, warn, msg, format_as_comma)
 from .pyfiles import (  # noqa
     template_to_file, coerce_resource_to_filename, simple_pyc_file_from_path,
-    pyc_file_from_path, load_python_file)
+    pyc_file_from_path, load_python_file, edit)
 from .sqla_compat import (  # noqa
     sqla_07, sqla_079, sqla_08, sqla_083, sqla_084, sqla_09, sqla_092,
     sqla_094, sqla_094, sqla_099, sqla_100, sqla_105)
index c51e18788ad5daacb752b61b74670cf238ae7bc2..c4de0710190dda279a85df52dd53b7a31cfeb47a 100644 (file)
@@ -59,6 +59,17 @@ def pyc_file_from_path(path):
         return simple_pyc_file_from_path(path)
 
 
+def edit(path):
+    """Given a source path, run the EDITOR for it"""
+
+    import editor
+    from . import CommandError
+    try:
+        editor.edit(path)
+    except Exception as exc:
+        raise CommandError('Error executing editor (%s)' % (exc,))
+
+
 def load_python_file(dir_, filename):
     """Load a file from the given path as a Python module."""
 
index 4b07c87b3cd2df02efb13e6ddd7d2ac26e7aadf1..e69732e7449a6efe86d40e2526bf5ea6ebf94c10 100644 (file)
@@ -6,6 +6,17 @@ Changelog
 .. changelog::
     :version: 0.8.0
 
+    .. change::
+      :tags: feature, commands
+      :pullreq: bitbucket:46
+
+      Added new command ``alembic edit``.  This command takes the same
+      arguments as ``alembic show``, however runs the target script
+      file within $EDITOR.  Makes use of the ``python-editor`` library
+      in order to facilitate the handling of $EDITOR with reasonable
+      default behaviors across platforms.  Pull request courtesy
+      Michel Albert.
+
     .. change::
       :tags: feature, commands
       :tickets: 311
index aaeefbcbe9365f9cad23361d0096730644ae88e6..aa8efa49cc9083c0bc7ee439ce22ec9efcdec41a 100644 (file)
@@ -434,21 +434,59 @@ class EditTest(TestBase):
     def teardown_class(cls):
         clear_staging_env()
 
-    def test_edit_latest(self):
+    def setUp(self):
+        command.stamp(self.cfg, "base")
+
+    def test_edit_head(self):
         expected_call_arg = '%s/scripts/versions/%s_revision_c.py' % (
             EditTest.cfg.config_args['here'],
             EditTest.c
         )
 
-        with mock.patch('alembic.command.editor.edit') as edit:
-            command.edit(self.cfg)
+        with mock.patch('alembic.util.edit') as edit:
+            command.edit(self.cfg, "head")
+            edit.assert_called_with(expected_call_arg)
+
+    def test_edit_b(self):
+        expected_call_arg = '%s/scripts/versions/%s_revision_b.py' % (
+            EditTest.cfg.config_args['here'],
+            EditTest.b
+        )
+
+        with mock.patch('alembic.util.edit') as edit:
+            command.edit(self.cfg, self.b[0:3])
             edit.assert_called_with(expected_call_arg)
 
     def test_edit_with_missing_editor(self):
-        with mock.patch('alembic.command.editor.edit') as edit:
-            edit.side_effect = OSError('file not found')
+        with mock.patch('editor.edit') as edit_mock:
+            edit_mock.side_effect = OSError("file not found")
             assert_raises_message(
                 util.CommandError,
                 'file not found',
-                command.edit,
-                self.cfg)
+                util.edit,
+                "/not/a/file.txt")
+
+    def test_edit_no_revs(self):
+        assert_raises_message(
+            util.CommandError,
+            "No revision files indicated by symbol 'base'",
+            command.edit,
+            self.cfg, "base")
+
+    def test_edit_no_current(self):
+        assert_raises_message(
+            util.CommandError,
+            "No current revisions",
+            command.edit,
+            self.cfg, "current")
+
+    def test_edit_current(self):
+        expected_call_arg = '%s/scripts/versions/%s_revision_b.py' % (
+            EditTest.cfg.config_args['here'],
+            EditTest.b
+        )
+
+        command.stamp(self.cfg, self.b)
+        with mock.patch('alembic.util.edit') as edit:
+            command.edit(self.cfg, "current")
+            edit.assert_called_with(expected_call_arg)