Skip to content

Commit 42fd2d9

Browse files
Increase test coverage. (#62)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 4e272ef commit 42fd2d9

File tree

15 files changed

+302
-191
lines changed

15 files changed

+302
-191
lines changed

.github/workflows/test.yml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ jobs:
1313
build:
1414
runs-on: ${{ matrix.platform }}
1515
strategy:
16-
fail-fast: true
16+
fail-fast: false
1717
matrix:
1818
platform: [ubuntu-latest, macos-latest, windows-latest]
1919
python-version: [3.6, 3.7, 3.8, 3.9, '3.10.0-beta.1']
2020

2121
steps:
2222
- uses: actions/checkout@v2
2323
with:
24-
submodules: migration_fixer/tests/demo
24+
submodules: true
25+
fetch-depth: 0
2526

2627
- name: Set up Python ${{ matrix.python-version }}
2728
uses: actions/setup-python@v2
@@ -36,15 +37,39 @@ jobs:
3637
restore-keys: |
3738
${{ runner.os }}-${{ matrix.platform }}-pip-${{ matrix.python-version }}-
3839
40+
- name: Update branches
41+
run: |
42+
git fetch origin feature/migration-test-01:feature/migration-test-01
43+
git fetch origin feature/migration-test-02:feature/migration-test-02
44+
working-directory: migration_fixer/tests/demo
45+
3946
- name: Install dependencies
4047
run: |
4148
make install-test
4249
43-
- name: Run test
50+
- name: Checkout feature/migration-test-01
51+
run: |
52+
git checkout feature/migration-test-01
53+
working-directory: migration_fixer/tests/demo
54+
55+
- name: Run test_01
56+
run: make tox
57+
env:
58+
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
59+
PLATFORM: ${{ matrix.platform }}
60+
ENV: test_01
61+
62+
- name: Checkout feature/migration-test-01
63+
run: |
64+
git checkout feature/migration-test-01
65+
working-directory: migration_fixer/tests/demo
66+
67+
- name: Run test_02
4468
run: make tox
4569
env:
4670
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
4771
PLATFORM: ${{ matrix.platform }}
72+
ENV: test_02
4873

4974
- name: "Upload coverage to Codecov"
5075
uses: codecov/[email protected]

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ guard-%: ## Checks that env var is set else exits with non 0 mainly used in CI;
2525
# ------- Python package (pip) management commands -------
2626
# --------------------------------------------------------
2727

28-
clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
28+
clean: clean-build clean-pyc clean-test clean-docs ## remove all build, test, coverage and Python artifacts
2929

3030
clean-build: ## remove build artifacts
3131
@rm -fr build/
@@ -46,10 +46,13 @@ clean-test: ## remove test and coverage artifacts
4646
@rm -fr htmlcov/
4747
@rm -fr .pytest_cache
4848

49+
clean-docs: ## remove all doc artifacts
50+
@rm -fr site
51+
4952
lint: ## check style with flake8
5053
@flake8 restricted_fields tests
5154

52-
tox: install-test ## Run tox test
55+
tox: ## Run tox test
5356
@tox
5457

5558
coverage: ## check code coverage quickly with the default Python

conftest.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
3+
import pytest
4+
5+
6+
def pytest_addoption(parser):
7+
parser.addoption(
8+
"-E",
9+
action="store",
10+
metavar="NAME",
11+
help="only run tests matching the environment NAME.",
12+
default=os.getenv("ENV"),
13+
)
14+
15+
16+
def pytest_configure(config):
17+
# register an additional marker
18+
config.addinivalue_line(
19+
"markers", "env(name): mark test to run only on named environment"
20+
)
21+
22+
23+
def pytest_runtest_setup(item):
24+
envnames = [mark.args[0] for mark in item.iter_markers(name="env")]
25+
if envnames:
26+
if item.config.getoption("-E") not in envnames:
27+
pytest.skip("test requires env in {!r}".format(envnames))

migration_fixer/management/commands/makemigrations.py

Lines changed: 71 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
from django.core.management.commands.makemigrations import Command as BaseCommand
1212
from django.db import DEFAULT_DB_ALIAS, connections, router
1313
from django.db.migrations.loader import MigrationLoader
14+
from git import InvalidGitRepositoryError, Repo
1415

1516
from migration_fixer.utils import (
1617
fix_named_migration,
1718
fix_numbered_migration,
1819
no_translations,
19-
run_command,
2020
)
2121

2222

@@ -27,6 +27,11 @@ class Command(BaseCommand):
2727

2828
success_msg = "Successfully fixed migrations."
2929

30+
def __init__(self, *args, repo=None, **kwargs):
31+
super().__init__(*args, **kwargs)
32+
self.cwd = os.getcwd()
33+
self.repo = repo or Repo.init(self.cwd)
34+
3035
def add_arguments(self, parser):
3136
parser.add_argument(
3237
"--fix",
@@ -39,12 +44,19 @@ def add_arguments(self, parser):
3944
help="The name of the default branch.",
4045
default="main",
4146
)
47+
parser.add_argument(
48+
"-f",
49+
"--force-update",
50+
help="Force update the default branch.",
51+
action="store_true",
52+
)
4253
super().add_arguments(parser)
4354

4455
@no_translations
4556
def handle(self, *app_labels, **options):
4657
self.merge = options["merge"]
4758
self.fix = options["fix"]
59+
self.force_update = options["force_update"]
4860
self.default_branch = options["default_branch"]
4961

5062
if self.fix:
@@ -53,68 +65,50 @@ def handle(self, *app_labels, **options):
5365
except CommandError as e:
5466
[message] = e.args
5567
if "Conflicting migrations" in message:
56-
(
57-
git_setup_has_error,
58-
git_setup_output,
59-
git_setup_error,
60-
) = run_command("git status")
68+
if self.verbosity >= 2:
69+
self.stdout.write("Verifying git repository...")
70+
71+
try:
72+
self.repo.git_dir
73+
except InvalidGitRepositoryError:
74+
is_git_repo = False
75+
else:
76+
is_git_repo = True
6177

62-
if not git_setup_has_error:
78+
if not is_git_repo:
6379
raise CommandError(
6480
self.style.ERROR(
65-
f"VCS is not yet setup. "
66-
"Please run (git init) "
67-
f'\n"{git_setup_output or git_setup_error}"'
81+
f"Git repository is not yet setup. "
82+
"Please run (git init) in"
83+
f'\n"{self.cwd}"'
6884
)
6985
)
7086

71-
(
72-
get_current_branch_has_error,
73-
get_current_branch_output,
74-
get_current_branch_error,
75-
) = run_command("git branch --show-current")
87+
if self.verbosity >= 2:
88+
self.stdout.write("Retrieving the current branch...")
7689

77-
if not get_current_branch_has_error:
78-
raise CommandError(
79-
self.style.ERROR(
80-
f"Unable to determine the current branch: "
81-
f'"{get_current_branch_output or get_current_branch_error}"'
82-
)
83-
)
90+
current_branch = self.repo.active_branch.name
8491

85-
pull_command = (
86-
"git pull"
87-
if get_current_branch_output == self.default_branch
88-
else (
89-
"git fetch origin "
90-
f"{self.default_branch}:{self.default_branch}"
92+
if self.verbosity >= 2:
93+
self.stdout.write(
94+
f"Fetching git remote origin changes on: {self.default_branch}"
9195
)
92-
)
9396

94-
# Pull the last commit
95-
git_pull_has_error, git_pull_output, git_pull_error = run_command(
96-
pull_command
97-
)
97+
if current_branch == self.default_branch:
98+
self.repo.remotes[self.default_branch].origin.pull()
99+
else:
100+
for remote in self.repo.remotes:
101+
remote.fetch(self.default_branch, force=self.force_update)
98102

99-
if not git_pull_has_error:
100-
raise CommandError(
101-
self.style.ERROR(
102-
f"Error pulling branch ({self.default_branch}) changes: "
103-
f'"{git_pull_output or git_pull_error}"'
104-
)
103+
if self.verbosity >= 2:
104+
self.stdout.write(
105+
f"Retrieving the last commit sha on: {self.default_branch}"
105106
)
106107

107-
head_sha_has_error, head_sha_output, head_sha_error = run_command(
108-
f"git rev-parse {self.default_branch}"
109-
)
108+
default_branch_commit = self.repo.commit(self.default_branch)
109+
110+
current_commit = self.repo.commit(current_branch)
110111

111-
if not head_sha_has_error:
112-
raise CommandError(
113-
self.style.ERROR(
114-
f"Error determining head sha on ({self.default_branch}): "
115-
f'"{head_sha_output or head_sha_error}"'
116-
)
117-
)
118112
# Load the current graph state. Pass in None for the connection so
119113
# the loader doesn't try to resolve replaced migrations from DB.
120114
loader = MigrationLoader(None, ignore_no_migrations=True)
@@ -147,13 +141,7 @@ def handle(self, *app_labels, **options):
147141
# hard if there are any and they don't want to merge
148142
conflicts = loader.detect_conflicts()
149143

150-
app_labels = app_labels or tuple(
151-
app_label
152-
for app_label in settings.INSTALLED_APPS
153-
if app_label in conflicts
154-
)
155-
156-
for app_label in app_labels:
144+
for app_label in conflicts:
157145
conflict = conflicts.get(app_label)
158146
migration_module, _ = loader.migrations_module(app_label)
159147
migration_absolute_path = os.path.join(
@@ -164,33 +152,34 @@ def handle(self, *app_labels, **options):
164152
)
165153

166154
with migration_path:
167-
(
168-
get_changed_files_has_error,
169-
get_changed_files_output,
170-
get_changed_files_error,
171-
) = run_command(
172-
f"git diff --diff-filter=ACMUXTR --name-only {self.default_branch}"
173-
)
174-
175-
if not get_changed_files_has_error:
176-
raise CommandError(
177-
self.style.ERROR(
178-
"Error retrieving changed files on "
179-
f"({self.default_branch}): "
180-
f'"{get_changed_files_output or get_changed_files_error}"'
181-
)
155+
if self.verbosity >= 2:
156+
self.stdout.write(
157+
"Retrieving changed files between "
158+
f"the current branch and {self.default_branch}"
182159
)
160+
161+
diff_index = default_branch_commit.diff(current_commit)
162+
183163
# Files different on the current branch
184164
changed_files = [
185-
fname
186-
for fname in get_changed_files_output.split("\n")
187-
if migration_absolute_path in fname
165+
diff.b_path
166+
for diff in diff_index
167+
if migration_absolute_path
168+
in getattr(diff.a_blob, "abspath", "")
169+
or migration_absolute_path
170+
in getattr(diff.b_blob, "abspath", "")
188171
]
172+
189173
# Local migration
190174
local_filenames = [
191175
os.path.splitext(os.path.basename(p))[0]
192176
for p in changed_files
193177
]
178+
if self.verbosity >= 2:
179+
self.stdout.write(
180+
f"Retrieving the last migration on: {self.default_branch}"
181+
)
182+
194183
last_remote = [
195184
fname
196185
for fname in conflict
@@ -218,6 +207,11 @@ def handle(self, *app_labels, **options):
218207
and len(seed_split) > 1
219208
and str(seed_split[0]).isdigit()
220209
):
210+
if self.verbosity >= 2:
211+
self.stdout.write(
212+
"Fixing numbered migration..."
213+
)
214+
221215
fix_numbered_migration(
222216
app_label=app_label,
223217
migration_path=migration_path,
@@ -226,6 +220,9 @@ def handle(self, *app_labels, **options):
226220
changed_files=changed_files,
227221
)
228222
else:
223+
if self.verbosity >= 2:
224+
self.stdout.write("Fixing named migration...")
225+
229226
fix_named_migration(
230227
app_label=app_label,
231228
migration_path=migration_path,

migration_fixer/tests/base.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)