From af4b11c563f8839521dba8f609c721e6e6add304 Mon Sep 17 00:00:00 2001 From: David Wobrock Date: Sun, 28 Jul 2019 11:56:31 +0200 Subject: [PATCH] Document (README & CHANGELOG) and rename option to 'exclude-migration-tests' --- CHANGELOG.md | 4 ++ README.rst | 44 +++++++++---------- .../management/commands/lintmigrations.py | 14 +++--- django_migration_linter/migration_linter.py | 8 ++-- django_migration_linter/sql_analyser.py | 14 ++++-- 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f160b46..a11d130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.0 + +* Add `--exclude-migration-tests` option to ignore backward incompatible migration tests. + ## 1.2.0 * Add `--unapplied-migrations` and `--applied-migrations` mutually exclusive options diff --git a/README.rst b/README.rst index c7311d3..4c8ca43 100644 --- a/README.rst +++ b/README.rst @@ -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 -================================================== =========================================================================================================================== -``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 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. -``--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). -``--verbose or -v`` Print more information during execution. -``--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. -``--no-cache`` Don't use a cache. -``--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. -``--project-root-path DJANGO_PROJECT_FOLDER`` An absolute or relative path to the django project. -================================================== =========================================================================================================================== +================================================================ =========================================================================================================================== +``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 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. +``--exclude-apps EXCLUDE_APPS [EXCLUDE_APPS ...]`` Ignore migrations that are in the specified django apps. +``--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. +``--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. +``--no-cache`` Don't use a cache. +``--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. +``--project-root-path DJANGO_PROJECT_FOLDER`` An absolute or relative path to the django project. +================================================================ =========================================================================================================================== 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 ----- diff --git a/django_migration_linter/management/commands/lintmigrations.py b/django_migration_linter/management/commands/lintmigrations.py index dbe2e3e..4607c38 100644 --- a/django_migration_linter/management/commands/lintmigrations.py +++ b/django_migration_linter/management/commands/lintmigrations.py @@ -50,11 +50,6 @@ class Command(BaseCommand): "--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.add_argument( "--cache-path", @@ -93,6 +88,13 @@ class Command(BaseCommand): 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): if options["project_root_path"]: settings_path = options["project_root_path"] @@ -112,12 +114,12 @@ class Command(BaseCommand): ignore_name=options["ignore_name"], include_apps=options["include_apps"], exclude_apps=options["exclude_apps"], - exclude_tests=options["exclude_tests"], database=options["database"], cache_path=options["cache_path"], no_cache=options["no_cache"], only_applied_migrations=options["applied_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.print_summary() diff --git a/django_migration_linter/migration_linter.py b/django_migration_linter/migration_linter.py index 714728a..e71e934 100644 --- a/django_migration_linter/migration_linter.py +++ b/django_migration_linter/migration_linter.py @@ -42,12 +42,12 @@ class MigrationLinter(object): ignore_name=None, include_apps=None, exclude_apps=None, - exclude_tests=None, database=DEFAULT_DB_ALIAS, cache_path=DEFAULT_CACHE_PATH, no_cache=False, only_applied_migrations=False, only_unapplied_migrations=False, + exclude_migration_tests=None, ): # Store parameters and options self.django_path = path @@ -55,7 +55,7 @@ class MigrationLinter(object): self.ignore_name = ignore_name or tuple() self.include_apps = include_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.cache_path = cache_path or DEFAULT_CACHE_PATH self.no_cache = no_cache @@ -120,8 +120,8 @@ class MigrationLinter(object): return sql_statements = self.get_sql(app_label, migration_name) - exclude_tests = self.exclude_tests or [] - errors = analyse_sql_statements(sql_statements, exclude_tests) + exclude_migration_tests = self.exclude_migration_tests or [] + errors = analyse_sql_statements(sql_statements, exclude_migration_tests) if not errors: print("OK") diff --git a/django_migration_linter/sql_analyser.py b/django_migration_linter/sql_analyser.py index 7ac46f2..1e654e9 100644 --- a/django_migration_linter/sql_analyser.py +++ b/django_migration_linter/sql_analyser.py @@ -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 = [] for statement in sql_statements: - for test in migration_tests: - if test["code"] not in exclude_tests and test["fn"](statement, - errors=errors): + for test in get_migration_tests(exclude_migration_tests): + if test["fn"](statement, errors=errors): logger.debug("Testing {0} -- ERROR".format(statement)) table_search = re.search("TABLE `([^`]*)`", statement, re.IGNORECASE) col_search = re.search("COLUMN `([^`]*)`", statement, re.IGNORECASE)