summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/changelog.rst2
-rw-r--r--migrate/versioning/repository.py44
-rw-r--r--migrate/versioning/templates/manage.py_tmpl4
-rw-r--r--migrate/versioning/templates/manage/default.py_tmpl10
-rw-r--r--migrate/versioning/templates/manage/pylons.py_tmpl29
-rw-r--r--migrate/versioning/templates/repository/default/migrate.cfg6
-rw-r--r--migrate/versioning/templates/repository/pylons/README4
-rw-r--r--migrate/versioning/templates/repository/pylons/__init__.py (renamed from migrate/versioning/templates/repository/__init__.py)0
-rw-r--r--migrate/versioning/templates/repository/pylons/migrate.cfg20
-rw-r--r--migrate/versioning/templates/repository/pylons/versions/__init__.py (renamed from migrate/versioning/templates/repository/default/__init__.py)0
-rw-r--r--migrate/versioning/templates/script/__init__.py0
-rw-r--r--migrate/versioning/templates/script/pylons.py_tmpl11
-rw-r--r--setup.py2
-rw-r--r--test/versioning/test_cfgparse.py4
-rw-r--r--test/versioning/test_template.py1
15 files changed, 108 insertions, 29 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 39acb8f..eb533a1 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,7 +1,7 @@
0.5.5
-----
-- added option to define custom templates through option ``--templates_path``, read more in :ref:`tutorial section <custom-templates>`
+- added option to define custom templates through option ``--templates_path`` and ``--templates_theme``, read more in :ref:`tutorial section <custom-templates>`
- url parameter can also be an Engine instance (this usage is discouraged though sometimes necessary)
- added support for SQLAlchemy 0.6 (missing oracle and firebird) by Michael Bayer
- alter, create, drop column / rename table / rename index constructs now accept `alter_metadata` parameter. If True, it will modify Column/Table objects according to changes. Otherwise, everything will be untouched.
diff --git a/migrate/versioning/repository.py b/migrate/versioning/repository.py
index 0938672..55768ef 100644
--- a/migrate/versioning/repository.py
+++ b/migrate/versioning/repository.py
@@ -6,6 +6,8 @@ import shutil
import string
from pkg_resources import resource_filename
+from tempita import Template as TempitaTemplate
+
from migrate.versioning import exceptions, script, version, pathed, cfgparse
from migrate.versioning.template import Template
from migrate.versioning.base import *
@@ -83,7 +85,7 @@ class Repository(pathed.Pathed):
:raises: :exc:`InvalidRepositoryError <migrate.versioning.exceptions.InvalidRepositoryError>`
"""
- # Ensure the existance of required files
+ # Ensure the existence of required files
try:
cls.require_found(path)
cls.require_found(os.path.join(path, cls._config))
@@ -92,7 +94,7 @@ class Repository(pathed.Pathed):
raise exceptions.InvalidRepositoryError(path)
@classmethod
- def prepare_config(cls, tmpl_dir, config_file, name, **opts):
+ def prepare_config(cls, tmpl_dir, name, options=None):
"""
Prepare a project configuration file for a new project.
@@ -104,37 +106,43 @@ class Repository(pathed.Pathed):
:type name: string
:returns: Populated config file
"""
- # Prepare opts
- defaults = dict(
- version_table = 'migrate_version',
- repository_id = name,
- required_dbs = [])
+ if options is None:
+ options = {}
+ options.setdefault('version_table', 'migrate_version')
+ options.setdefault('repository_id', name)
+ options.setdefault('required_dbs', [])
+
+ tmpl = open(os.path.join(tmpl_dir, cls._config)).read()
+ ret = TempitaTemplate(tmpl).substitute(options)
- defaults.update(opts)
+ # cleanup
+ del options['__template_name__']
- tmpl = open(os.path.join(tmpl_dir, config_file)).read()
- ret = string.Template(tmpl).substitute(defaults)
return ret
@classmethod
def create(cls, path, name, **opts):
"""Create a repository at a specified path"""
cls.require_notfound(path)
- theme = opts.get('templates_theme', None)
+ theme = opts.pop('templates_theme', None)
+ t_path = opts.pop('templates_path', None)
# Create repository
- tmpl_dir = Template(opts.pop('templates_path', None)).get_repository(theme=theme)
- config_text = cls.prepare_config(tmpl_dir, cls._config, name, **opts)
+ tmpl_dir = Template(t_path).get_repository(theme=theme)
shutil.copytree(tmpl_dir, path)
# Edit config defaults
+ config_text = cls.prepare_config(tmpl_dir, name, options=opts)
fd = open(os.path.join(path, cls._config), 'w')
fd.write(config_text)
fd.close()
+ opts['repository_name'] = name
+
# Create a management script
manager = os.path.join(path, 'manage.py')
- Repository.create_manage_file(manager, theme=theme, repository=path)
+ Repository.create_manage_file(manager, templates_theme=theme,
+ templates_path=t_path, **opts)
return cls(path)
@@ -208,12 +216,12 @@ class Repository(pathed.Pathed):
"""Create a project management script (manage.py)
:param file_: Destination file to be written
- :param opts: Options that are passed to template
+ :param opts: Options that are passed to :func:`migrate.versioning.shell.main`
"""
- mng_file = Template(opts.pop('templates_path', None)).get_manage(theme=opts.pop('templates_theme', None))
- vars_ = ",".join(["%s='%s'" % var for var in opts.iteritems()])
+ mng_file = Template(opts.pop('templates_path', None))\
+ .get_manage(theme=opts.pop('templates_theme', None))
tmpl = open(mng_file).read()
fd = open(file_, 'w')
- fd.write(tmpl % dict(defaults=vars_))
+ fd.write(TempitaTemplate(tmpl).substitute(opts))
fd.close()
diff --git a/migrate/versioning/templates/manage.py_tmpl b/migrate/versioning/templates/manage.py_tmpl
deleted file mode 100644
index 93bcba2..0000000
--- a/migrate/versioning/templates/manage.py_tmpl
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env python
-from migrate.versioning.shell import main
-
-main(%(defaults)s)
diff --git a/migrate/versioning/templates/manage/default.py_tmpl b/migrate/versioning/templates/manage/default.py_tmpl
new file mode 100644
index 0000000..37c23bd
--- /dev/null
+++ b/migrate/versioning/templates/manage/default.py_tmpl
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+from migrate.versioning.shell import main
+
+{{py:
+_vars = locals().copy()
+del _vars['__template_name__']
+_vars.pop('repository_name')
+defaults = ", ".join(["%s='%s'" % var for var in _vars.iteritems()])
+}}
+main({{ defaults }})
diff --git a/migrate/versioning/templates/manage/pylons.py_tmpl b/migrate/versioning/templates/manage/pylons.py_tmpl
new file mode 100644
index 0000000..475b8ce
--- /dev/null
+++ b/migrate/versioning/templates/manage/pylons.py_tmpl
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import sys
+
+from sqlalchemy import engine_from_config
+from paste.deploy.loadwsgi import ConfigLoader
+
+from migrate.versioning.shell import main
+from {{ locals().pop('repository_name') }}.model import migrations
+
+
+if '-c' in sys.argv:
+ pos = sys.argv.index('-c')
+ conf_path = sys.argv[pos + 1]
+ del sys.argv[pos:pos + 2]
+else:
+ conf_path = 'development.ini'
+
+{{py:
+_vars = locals().copy()
+del _vars['__template_name__']
+defaults = ", ".join(["%s='%s'" % var for var in _vars.iteritems()])
+}}
+
+conf_dict = ConfigLoader(conf_path).parser._sections['app:main']
+
+# migrate supports passing url as an existing Engine instance (since 0.6.0)
+# usage: migrate -c path/to/config.ini COMMANDS
+main(url=engine_from_config(conf_dict), repository=migrations.__path__[0],{{ defaults }})
diff --git a/migrate/versioning/templates/repository/default/migrate.cfg b/migrate/versioning/templates/repository/default/migrate.cfg
index 4ad3bc5..1dc6ff6 100644
--- a/migrate/versioning/templates/repository/default/migrate.cfg
+++ b/migrate/versioning/templates/repository/default/migrate.cfg
@@ -1,13 +1,13 @@
[db_settings]
# Used to identify which repository this database is versioned under.
# You can use the name of your project.
-repository_id=${repository_id}
+repository_id={{ locals().pop('repository_id') }}
# The name of the database table used to track the schema version.
# This name shouldn't already be used by your project.
# If this is changed once a database is under version control, you'll need to
# change the table name in each database too.
-version_table=${version_table}
+version_table={{ locals().pop('version_table') }}
# When committing a change script, Migrate will attempt to generate the
# sql for all supported databases; normally, if one of them fails - probably
@@ -17,4 +17,4 @@ version_table=${version_table}
# entire commit will fail. List the databases your application will actually
# be using to ensure your updates to that database work properly.
# This must be a list; example: ['postgres','sqlite']
-required_dbs=${required_dbs}
+required_dbs={{ locals().pop('required_dbs') }}
diff --git a/migrate/versioning/templates/repository/pylons/README b/migrate/versioning/templates/repository/pylons/README
new file mode 100644
index 0000000..6218f8c
--- /dev/null
+++ b/migrate/versioning/templates/repository/pylons/README
@@ -0,0 +1,4 @@
+This is a database migration repository.
+
+More information at
+http://code.google.com/p/sqlalchemy-migrate/
diff --git a/migrate/versioning/templates/repository/__init__.py b/migrate/versioning/templates/repository/pylons/__init__.py
index e69de29..e69de29 100644
--- a/migrate/versioning/templates/repository/__init__.py
+++ b/migrate/versioning/templates/repository/pylons/__init__.py
diff --git a/migrate/versioning/templates/repository/pylons/migrate.cfg b/migrate/versioning/templates/repository/pylons/migrate.cfg
new file mode 100644
index 0000000..1dc6ff6
--- /dev/null
+++ b/migrate/versioning/templates/repository/pylons/migrate.cfg
@@ -0,0 +1,20 @@
+[db_settings]
+# Used to identify which repository this database is versioned under.
+# You can use the name of your project.
+repository_id={{ locals().pop('repository_id') }}
+
+# The name of the database table used to track the schema version.
+# This name shouldn't already be used by your project.
+# If this is changed once a database is under version control, you'll need to
+# change the table name in each database too.
+version_table={{ locals().pop('version_table') }}
+
+# When committing a change script, Migrate will attempt to generate the
+# sql for all supported databases; normally, if one of them fails - probably
+# because you don't have that database installed - it is ignored and the
+# commit continues, perhaps ending successfully.
+# Databases in this list MUST compile successfully during a commit, or the
+# entire commit will fail. List the databases your application will actually
+# be using to ensure your updates to that database work properly.
+# This must be a list; example: ['postgres','sqlite']
+required_dbs={{ locals().pop('required_dbs') }}
diff --git a/migrate/versioning/templates/repository/default/__init__.py b/migrate/versioning/templates/repository/pylons/versions/__init__.py
index e69de29..e69de29 100644
--- a/migrate/versioning/templates/repository/default/__init__.py
+++ b/migrate/versioning/templates/repository/pylons/versions/__init__.py
diff --git a/migrate/versioning/templates/script/__init__.py b/migrate/versioning/templates/script/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/migrate/versioning/templates/script/__init__.py
+++ /dev/null
diff --git a/migrate/versioning/templates/script/pylons.py_tmpl b/migrate/versioning/templates/script/pylons.py_tmpl
new file mode 100644
index 0000000..711899c
--- /dev/null
+++ b/migrate/versioning/templates/script/pylons.py_tmpl
@@ -0,0 +1,11 @@
+from sqlalchemy import *
+from migrate import *
+
+def upgrade(migrate_engine):
+ # Upgrade operations go here. Don't create your own engine; bind migrate_engine
+ # to your metadata
+ pass
+
+def downgrade(migrate_engine):
+ # Operations to reverse the above upgrade go here.
+ pass
diff --git a/setup.py b/setup.py
index d3c5295..81414bf 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ except ImportError:
pass
test_requirements = ['nose >= 0.10']
-required_deps = ['sqlalchemy >= 0.5', 'decorator']
+required_deps = ['sqlalchemy >= 0.5', 'decorator', 'tempita']
readme_file = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'README'))
setup(
diff --git a/test/versioning/test_cfgparse.py b/test/versioning/test_cfgparse.py
index 3cd0e56..e9ded6a 100644
--- a/test/versioning/test_cfgparse.py
+++ b/test/versioning/test_cfgparse.py
@@ -21,7 +21,7 @@ class TestConfigParser(fixture.Base):
def test_table_config(self):
"""We should be able to specify the table to be used with a repository"""
default_text = Repository.prepare_config(Template().get_repository(),
- Repository._config, 'repository_name')
+ 'repository_name', {})
specified_text = Repository.prepare_config(Template().get_repository(),
- Repository._config, 'repository_name', version_table='_other_table')
+ 'repository_name', {'version_table': '_other_table'})
self.assertNotEquals(default_text, specified_text)
diff --git a/test/versioning/test_template.py b/test/versioning/test_template.py
index d0c75a9..90abe36 100644
--- a/test/versioning/test_template.py
+++ b/test/versioning/test_template.py
@@ -59,5 +59,6 @@ class TestTemplate(fixture.Pathed):
# assert changes
self.assertEqual(open(new_manage_dest).read(), MANAGE_CONTENTS)
+ self.assertEqual(open(os.path.join(new_repo_dest, 'manage.py')).read(), MANAGE_CONTENTS)
self.assertEqual(open(os.path.join(new_repo_dest, 'README')).read(), README_CONTENTS)
self.assertEqual(open(os.path.join(new_repo_dest, 'versions/001_test.py')).read(), SCRIPT_FILE_CONTENTS)