summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAviskar KC <aviskarkc10@gmail.com>2019-07-04 14:31:03 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-07-18 14:26:20 -0400
commit02a1bf3454acb7b02942e246c19326630a8f9175 (patch)
tree316d647c5a0ac589b601579094a79ca5bd7d08d3
parent7cc28f542f4b1addd6b5a55d3b774ac74de6bed4 (diff)
downloadalembic-02a1bf3454acb7b02942e246c19326630a8f9175.tar.gz
Allow init into existing but empty directory
The "alembic init" command will now proceed if the target directory exists as long as it's still empty. Previously, it would not proceed if the directory existed. The new behavior is modeled from what git does, to accommodate for container or other deployments where an Alembic target directory may need to be already mounted instead of being created with alembic init. Pull request courtesy Aviskar KC. Fixes: #571 Closes: #574 Pull-request: https://github.com/sqlalchemy/alembic/pull/574 Pull-request-sha: ab7b8f342a89c752460d171cd50d1f958c7d59c9 Change-Id: I6b0cff9a7e940d9d878aa339891bda33744a2a4c
-rw-r--r--alembic/command.py17
-rw-r--r--docs/build/unreleased/571.rst12
-rw-r--r--tests/test_command.py54
3 files changed, 76 insertions, 7 deletions
diff --git a/alembic/command.py b/alembic/command.py
index 3faafdd..c02db62 100644
--- a/alembic/command.py
+++ b/alembic/command.py
@@ -37,18 +37,21 @@ def init(config, directory, template="generic"):
"""
- if os.access(directory, os.F_OK):
- raise util.CommandError("Directory %s already exists" % directory)
+ if os.access(directory, os.F_OK) and os.listdir(directory):
+ raise util.CommandError(
+ "Directory %s already exists and is not empty" % directory
+ )
template_dir = os.path.join(config.get_template_directory(), template)
if not os.access(template_dir, os.F_OK):
raise util.CommandError("No such template %r" % template)
- util.status(
- "Creating directory %s" % os.path.abspath(directory),
- os.makedirs,
- directory,
- )
+ if not os.access(directory, os.F_OK):
+ util.status(
+ "Creating directory %s" % os.path.abspath(directory),
+ os.makedirs,
+ directory,
+ )
versions = os.path.join(directory, "versions")
util.status(
diff --git a/docs/build/unreleased/571.rst b/docs/build/unreleased/571.rst
new file mode 100644
index 0000000..82c7647
--- /dev/null
+++ b/docs/build/unreleased/571.rst
@@ -0,0 +1,12 @@
+.. change::
+ :tags: usecase, commands
+ :tickets: 571
+
+ The "alembic init" command will now proceed if the target directory exists
+ as long as it's still empty. Previously, it would not proceed if the
+ directory existed. The new behavior is modeled from what git does, to
+ accommodate for container or other deployments where an Alembic target
+ directory may need to be already mounted instead of being created with
+ alembic init. Pull request courtesy Aviskar KC.
+
+
diff --git a/tests/test_command.py b/tests/test_command.py
index 653028f..746471b 100644
--- a/tests/test_command.py
+++ b/tests/test_command.py
@@ -800,3 +800,57 @@ class CommandLineTest(TestBase):
# not too long
assert len(help_text) < 80
assert not commands, "Commands without help text: %s" % commands
+
+ def test_init_file_exists_and_is_not_empty(self):
+ with mock.patch(
+ "alembic.command.os.listdir", return_value=["file1", "file2"]
+ ), mock.patch("alembic.command.os.access", return_value=True):
+ directory = "alembic"
+ assert_raises_message(
+ util.CommandError,
+ "Directory %s already exists and is not empty" % directory,
+ command.init,
+ self.cfg,
+ directory=directory,
+ )
+
+ def test_init_file_exists_and_is_empty(self):
+ def access_(path, mode):
+ if "generic" in path or path == "foobar":
+ return True
+ else:
+ return False
+
+ def listdir_(path):
+ if path == "foobar":
+ return []
+ else:
+ return ["file1", "file2", "alembic.ini.mako"]
+
+ with mock.patch(
+ "alembic.command.os.access", side_effect=access_
+ ), mock.patch("alembic.command.os.makedirs") as makedirs, mock.patch(
+ "alembic.command.os.listdir", side_effect=listdir_
+ ), mock.patch(
+ "alembic.command.ScriptDirectory"
+ ):
+ command.init(self.cfg, directory="foobar")
+ eq_(makedirs.mock_calls, [mock.call("foobar/versions")])
+
+ def test_init_file_doesnt_exist(self):
+ def access_(path, mode):
+ if "generic" in path:
+ return True
+ else:
+ return False
+
+ with mock.patch(
+ "alembic.command.os.access", side_effect=access_
+ ), mock.patch("alembic.command.os.makedirs") as makedirs, mock.patch(
+ "alembic.command.ScriptDirectory"
+ ):
+ command.init(self.cfg, directory="foobar")
+ eq_(
+ makedirs.mock_calls,
+ [mock.call("foobar"), mock.call("foobar/versions")],
+ )