from . import util
from . import autogenerate as autogen
-import editor
-
def list_templates(config):
"""List available templates"""
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)
+
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)
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."""
.. 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
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)