Document (README & CHANGELOG) and rename option to 'exclude-migration-tests'

This commit is contained in:
David Wobrock committed 2019-07-28 12:28:56 +02:00
1 parent 579e7c68b4
commit af4b11c563
5 files changed
+48 -36

No files matched your search

+4
View File
@@ -1,3 +1,7 @@
## 1.3.0
* Add `--exclude-migration-tests` option to ignore backward incompatible migration tests.
## 1.2.0 ## 1.2.0
* Add `--unapplied-migrations` and `--applied-migrations` mutually exclusive options * Add `--unapplied-migrations` and `--applied-migrations` mutually exclusive options
+22 -22
View File
@@ -43,25 +43,25 @@ Add the migration linter your ``INSTALLED_APPS``:
] ]
``python manage.py lintmigrations [GIT_COMMIT_ID] [--ignore-name-contains IGNORE_NAME_CONTAINS] [--include-apps INCLUDE_APPS [INCLUDE_APPS ...] | --exclude-apps EXCLUDE_APPS [EXCLUDE_APPS ...]] [--exclude-tests EXCLUDE_TESTS [EXCLUDE TESTS ...]] [--project-root-path DJANGO_PROJECT_FOLDER]`` ``python manage.py lintmigrations [GIT_COMMIT_ID] [--ignore-name-contains IGNORE_NAME_CONTAINS] [--include-apps INCLUDE_APPS [INCLUDE_APPS ...] | --exclude-apps EXCLUDE_APPS [EXCLUDE_APPS ...]] [--exclude-migration-tests MIGRATION_TEST_CODE [MIGRATION_TEST_CODE ...]] [--project-root-path DJANGO_PROJECT_FOLDER]``
================================================== =========================================================================================================================== ================================================================ ===========================================================================================================================
Parameter Description Parameter Description
================================================== =========================================================================================================================== ================================================================ ===========================================================================================================================
``GIT_COMMIT_ID`` If specified, only migrations since this commit will be taken into account. If not specified, all migrations will be linted. ``GIT_COMMIT_ID`` If specified, only migrations since this commit will be taken into account. If not specified, all migrations will be linted.
``--ignore-name-contains IGNORE_NAME_CONTAINS`` Ignore migrations containing this name. ``--ignore-name-contains IGNORE_NAME_CONTAINS`` Ignore migrations containing this name.
``--ignore-name IGNORE_NAME [IGNORE_NAME ...]`` Ignore migrations with exactly one of these names. ``--ignore-name IGNORE_NAME [IGNORE_NAME ...]`` Ignore migrations with exactly one of these names.
``--include-apps INCLUDE_APPS [INCLUDE_APPS ...]`` Check only migrations that are in the specified django apps. ``--include-apps INCLUDE_APPS [INCLUDE_APPS ...]`` Check only migrations that are in the specified django apps.
``--exclude-apps EXCLUDE_APPS [EXCLUDE_APPS ...]`` Ignore migrations that are in the specified django apps. ``--exclude-apps EXCLUDE_APPS [EXCLUDE_APPS ...]`` Ignore migrations that are in the specified django apps.
``--exclude-tests EXCLUDE_TESTS [EXCLUDE TES...]`` Specify tests to be ignored (e.g. ALTER_COLUMN). ``--exclude-tests MIGRATION_TEST_CODE [MIGRATION_TEST_CODE...]`` Specify backward incompatible migration tests to be ignored using the code (e.g. ALTER_COLUMN).
``--verbose or -v`` Print more information during execution. ``--verbose or -v`` Print more information during execution.
``--database DATABASE`` Specify the database for which to generate the SQL. Defaults to *default*. ``--database DATABASE`` Specify the database for which to generate the SQL. Defaults to *default*.
``--cache-path PATH`` specify a directory that should be used to store cache-files in. ``--cache-path PATH`` specify a directory that should be used to store cache-files in.
``--no-cache`` Don't use a cache. ``--no-cache`` Don't use a cache.
``--applied-migrations`` Only lint migrations that are applied to the selected database. Other migrations are ignored. ``--applied-migrations`` Only lint migrations that are applied to the selected database. Other migrations are ignored.
``--unapplied-migrations`` Only lint migrations that are not yet applied to the selected database. Other migrations are ignored. ``--unapplied-migrations`` Only lint migrations that are not yet applied to the selected database. Other migrations are ignored.
``--project-root-path DJANGO_PROJECT_FOLDER`` An absolute or relative path to the django project. ``--project-root-path DJANGO_PROJECT_FOLDER`` An absolute or relative path to the django project.
================================================== =========================================================================================================================== ================================================================ ===========================================================================================================================
Examples Examples
-------- --------
@@ -100,14 +100,14 @@ You can also ignore migrations by adding this to your migrations:
] ]
# ... # ...
Ignoring tests Ignoring migration tests
------------------- ------------------------
You can also ignore tests by adding this option during execution: You can also ignore backward incompatible migration tests by adding this option during execution:
``python manage.py lintmigrations --exclude-tests EXCLUDE_TESTS`` ``python manage.py lintmigrations --exclude-migration-tests ALTER_COLUMN``
The tests list can be found in sql_analyzer (migration_tests) The migration test codes can be found in the file ``django_migration_linter/sql_analyser.py``.
Cache Cache
----- -----
@@ -50,11 +50,6 @@ class Command(BaseCommand):
"--project-root-path", type=str, nargs="?", help="django project root path" "--project-root-path", type=str, nargs="?", help="django project root path"
) )
parser.add_argument(
"--exclude-tests", type=str, nargs="*", help="Specify tests to be ignored"
" (e.g. ALTER_COLUMN)"
)
cache_group = parser.add_mutually_exclusive_group(required=False) cache_group = parser.add_mutually_exclusive_group(required=False)
cache_group.add_argument( cache_group.add_argument(
"--cache-path", "--cache-path",
@@ -93,6 +88,13 @@ class Command(BaseCommand):
help="check only migrations that have already been applied to the database", help="check only migrations that have already been applied to the database",
) )
parser.add_argument(
"--exclude-migration-tests",
type=str,
nargs="*",
help="Specify backward incompatible migration tests to be ignored (e.g. ALTER_COLUMN)",
)
def handle(self, *args, **options): def handle(self, *args, **options):
if options["project_root_path"]: if options["project_root_path"]:
settings_path = options["project_root_path"] settings_path = options["project_root_path"]
@@ -112,12 +114,12 @@ class Command(BaseCommand):
ignore_name=options["ignore_name"], ignore_name=options["ignore_name"],
include_apps=options["include_apps"], include_apps=options["include_apps"],
exclude_apps=options["exclude_apps"], exclude_apps=options["exclude_apps"],
exclude_tests=options["exclude_tests"],
database=options["database"], database=options["database"],
cache_path=options["cache_path"], cache_path=options["cache_path"],
no_cache=options["no_cache"], no_cache=options["no_cache"],
only_applied_migrations=options["applied_migrations"], only_applied_migrations=options["applied_migrations"],
only_unapplied_migrations=options["unapplied_migrations"], only_unapplied_migrations=options["unapplied_migrations"],
exclude_migration_tests=options["exclude_migration_tests"],
) )
linter.lint_all_migrations(git_commit_id=options["commit_id"]) linter.lint_all_migrations(git_commit_id=options["commit_id"])
linter.print_summary() linter.print_summary()
+4 -4
View File
@@ -42,12 +42,12 @@ class MigrationLinter(object):
ignore_name=None, ignore_name=None,
include_apps=None, include_apps=None,
exclude_apps=None, exclude_apps=None,
exclude_tests=None,
database=DEFAULT_DB_ALIAS, database=DEFAULT_DB_ALIAS,
cache_path=DEFAULT_CACHE_PATH, cache_path=DEFAULT_CACHE_PATH,
no_cache=False, no_cache=False,
only_applied_migrations=False, only_applied_migrations=False,
only_unapplied_migrations=False, only_unapplied_migrations=False,
exclude_migration_tests=None,
): ):
# Store parameters and options # Store parameters and options
self.django_path = path self.django_path = path
@@ -55,7 +55,7 @@ class MigrationLinter(object):
self.ignore_name = ignore_name or tuple() self.ignore_name = ignore_name or tuple()
self.include_apps = include_apps self.include_apps = include_apps
self.exclude_apps = exclude_apps self.exclude_apps = exclude_apps
self.exclude_tests = exclude_tests self.exclude_migration_tests = exclude_migration_tests
self.database = database or DEFAULT_DB_ALIAS self.database = database or DEFAULT_DB_ALIAS
self.cache_path = cache_path or DEFAULT_CACHE_PATH self.cache_path = cache_path or DEFAULT_CACHE_PATH
self.no_cache = no_cache self.no_cache = no_cache
@@ -120,8 +120,8 @@ class MigrationLinter(object):
return return
sql_statements = self.get_sql(app_label, migration_name) sql_statements = self.get_sql(app_label, migration_name)
exclude_tests = self.exclude_tests or [] exclude_migration_tests = self.exclude_migration_tests or []
errors = analyse_sql_statements(sql_statements, exclude_tests) errors = analyse_sql_statements(sql_statements, exclude_migration_tests)
if not errors: if not errors:
print("OK") print("OK")
+10 -4
View File
@@ -70,12 +70,18 @@ migration_tests = (
) )
def analyse_sql_statements(sql_statements, exclude_tests): def get_migration_tests(exclude_migration_tests):
for test in migration_tests:
if test["code"] in exclude_migration_tests:
continue
yield test
def analyse_sql_statements(sql_statements, exclude_migration_tests):
errors = [] errors = []
for statement in sql_statements: for statement in sql_statements:
for test in migration_tests: for test in get_migration_tests(exclude_migration_tests):
if test["code"] not in exclude_tests and test["fn"](statement, if test["fn"](statement, errors=errors):
errors=errors):
logger.debug("Testing {0} -- ERROR".format(statement)) logger.debug("Testing {0} -- ERROR".format(statement))
table_search = re.search("TABLE `([^`]*)`", statement, re.IGNORECASE) table_search = re.search("TABLE `([^`]*)`", statement, re.IGNORECASE)
col_search = re.search("COLUMN `([^`]*)`", statement, re.IGNORECASE) col_search = re.search("COLUMN `([^`]*)`", statement, re.IGNORECASE)