Skip to content

Commit 4e36cbe

Browse files
committed
Add unit test for shallow clones, see #10
1 parent 582d0b3 commit 4e36cbe

File tree

2 files changed

+108
-30
lines changed

2 files changed

+108
-30
lines changed

mkdocs_git_revision_date_localized_plugin/util.py

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,31 @@
44
from datetime import datetime
55
from babel.dates import format_date
66

7+
78
class Util:
89

910
def __init__(self, path = "."):
1011
self.repo = Git(path)
12+
13+
# Checks when running builds on CI
14+
# See https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/10
15+
if is_shallow_clone(self.repo):
16+
n_commits = commit_count(self.repo)
17+
18+
if os.environ.get('GITLAB_CI') and n_commits < 50:
19+
logging.warning("""
20+
Running on a gitlab runner might lead to wrong git revision dates
21+
due to a shallow git fetch depth.
22+
Make sure to set GIT_DEPTH to 1000 in your .gitlab-ci.yml file.
23+
(see https://docs.gitlab.com/ee/user/project/pipelines/settings.html#git-shallow-clone).
24+
""")
25+
if os.environ.get('GITHUB_ACTIONS') and n_commits == 1:
26+
logging.warning("""
27+
Running on github actions might lead to wrong git revision dates
28+
due to a shallow git fetch depth.
29+
Try setting fetch-depth to 0 in your github action
30+
(see https://github.com/actions/checkout).
31+
""")
1132

1233
@staticmethod
1334
def _date_formats(unix_timestamp, locale = 'en'):
@@ -50,27 +71,43 @@ def get_revision_date_for_file(self, path, locale = 'en'):
5071
"""
5172

5273
unix_timestamp = self.repo.log(path, n=1, date='short', format='%at')
53-
54-
74+
5575
if not unix_timestamp:
56-
57-
if os.environ.get('GITLAB_CI'):
58-
raise EnvironmentError("""Cannot access git commit for '%s'.
59-
Try setting GIT_DEPTH to 1000 in your .gitlab-ci.yml file.
60-
(see https://docs.gitlab.com/ee/user/project/pipelines/settings.html#git-shallow-clone).
61-
Or disable mkdocs-git-revision-date-localized-plugin when using gitlab runners.
62-
""" % path)
63-
64-
if os.environ.get('GITHUB_ACTIONS'):
65-
raise EnvironmentError("""Cannot access git commit for '%s'.
66-
Try setting fetch-depth to 1 in your github action
67-
(see https://github.com/actions/checkout).
68-
Or disable mkdocs-git-revision-date-localized-plugin when using github actions.
69-
""" % path)
70-
7176
unix_timestamp = datetime.utcnow().timestamp()
7277
logging.warning('%s has no git logs, using current timestamp' % path)
73-
74-
7578

7679
return self._date_formats(unix_timestamp)
80+
81+
def is_shallow_clone(repo):
82+
"""
83+
Helper function to determine if repository
84+
is a shallow clone.
85+
86+
References:
87+
https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/10
88+
https://stackoverflow.com/a/37203240/5525118
89+
90+
Args:
91+
repo (git.Repo): Repository
92+
93+
Returns:
94+
bool: If a repo is shallow clone
95+
"""
96+
return os.path.exists(".git/shallow")
97+
98+
99+
def commit_count(repo):
100+
"""
101+
Helper function to determine the number of commits in a repository
102+
103+
Args:
104+
repo (git.Repo): Repository
105+
106+
Returns:
107+
count (int): Number of commits
108+
"""
109+
refs = repo.for_each_ref().split('\n')
110+
refs = [x.split()[0] for x in refs]
111+
112+
counts = [int(repo.rev_list(x, count=True, first_parent=True)) for x in refs]
113+
return max(counts)

tests/test_basic.py

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import shutil
1616
import pytest
1717
import git
18+
import logging
1819

1920
from mkdocs_git_revision_date_localized_plugin.util import Util
2021

@@ -44,6 +45,8 @@ def setup_clean_mkdocs_folder(mkdocs_yml_path, output_path):
4445

4546
# Create empty 'testproject' folder
4647
if os.path.exists(testproject_path):
48+
logging.warning("""This command does not work on windows.
49+
Refactor your test to use setup_clean_mkdocs_folder() only once""")
4750
shutil.rmtree(testproject_path)
4851

4952
# Copy correct mkdocs.yml file and our test 'docs/'
@@ -62,6 +65,9 @@ def setup_commit_history(testproject_path):
6265
6366
Args:
6467
testproject_path (Path): Path to test project
68+
69+
Returns:
70+
repo (repo): git.Repo object
6571
"""
6672
assert not os.path.exists(testproject_path / '.git')
6773

@@ -75,8 +81,19 @@ def setup_commit_history(testproject_path):
7581
try:
7682
repo.git.add('mkdocs.yml')
7783
repo.git.commit(message = 'add mkdocs', author = author)
84+
7885
repo.git.add('docs/first_page.md')
7986
repo.git.commit(message = 'first page', author = author)
87+
file_name = os.path.join(testproject_path, 'docs/first_page.md')
88+
with open(file_name, 'w+') as the_file:
89+
the_file.write('Hello\n')
90+
repo.git.add('docs/first_page.md')
91+
repo.git.commit(message = 'first page update 1', author = author)
92+
with open(file_name, 'w') as the_file:
93+
the_file.write('# First Test Page Edited\n\nSome Lorem text')
94+
repo.git.add('docs/first_page.md')
95+
repo.git.commit(message = 'first page update 2', author = author)
96+
8097
repo.git.add('docs/second_page.md')
8198
repo.git.commit(message = 'second page', author = author)
8299
repo.git.add('docs/index.md')
@@ -87,6 +104,8 @@ def setup_commit_history(testproject_path):
87104
except:
88105
os.chdir(cwd)
89106
raise
107+
108+
return repo
90109

91110
def build_docs_setup(testproject_path):
92111
"""
@@ -225,23 +244,45 @@ def test_type_unknown(tmp_path):
225244
tmp_path,
226245
'tests/basic_setup/mkdocs_unknown_type.yml')
227246

228-
def test_low_fetch_depth(tmp_path):
247+
def test_low_fetch_depth(tmp_path, caplog):
229248
"""
230249
On gitlab and github runners, a GIT might have a low fetch
231250
depth, which means commits are not available.
232251
This should throw informative errors.
233252
"""
234253

235-
pass
254+
testproject_path = setup_clean_mkdocs_folder('tests/basic_setup/mkdocs.yml', tmp_path)
255+
repo = setup_commit_history(testproject_path)
236256

237-
# Test correct error messages when GIT is not available
238-
#target_dir = os.path.join(tmp_path, 'nogit')
239-
#shutil.copytree(os.path.join(os.getcwd(), 'test/basic_setup'),
240-
# target_dir)
257+
# Create a second, clean folder to clone to
258+
cloned_folder = tmp_path.parent / 'clonedrepo'
259+
if os.path.exists(cloned_folder):
260+
shutil.rmtree(cloned_folder)
261+
os.mkdir(cloned_folder)
262+
263+
# Clone the local repo with fetch depth of 1
264+
repo = git.Repo.init(cloned_folder, bare = False)
265+
origin = repo.create_remote('origin', testproject_path)
266+
origin.fetch(depth=1, prune=True)
267+
repo.create_head('master', origin.refs.master) # create local branch "master" from remote "master"
268+
repo.heads.master.set_tracking_branch(origin.refs.master) # set local "master" to track remote "master
269+
repo.heads.master.checkout() # checkout local "master" to working tree
270+
271+
# should not raise warning
272+
result = build_docs_setup(cloned_folder)
273+
assert result.exit_code == 0
274+
275+
# should raise warning
276+
os.environ["GITLAB_CI"] = "1"
277+
result = build_docs_setup(cloned_folder)
278+
assert result.exit_code == 0
279+
assert 'Running on a gitlab runner' in caplog.text
280+
281+
del os.environ['GITLAB_CI']
282+
os.environ["GITHUB_ACTIONS"] = "1"
283+
result = build_docs_setup(cloned_folder)
284+
assert result.exit_code == 0
285+
assert 'Running on github actions might' in caplog.text
241286

242-
# ...
243-
#result = build_docs_setup(os.path.join(target_dir,'mkdocs.yml'), target_dir)
244287

245-
#with pytest.warns(UserWarning):
246-
# assert result.exit_code == 0, "'mkdocs build' command failed"
247-
288+
# TODO: Test correct error messages when GIT is not available

0 commit comments

Comments
 (0)