Skip to content

Commit

Permalink
Add unit test for shallow clones, see #10
Browse files Browse the repository at this point in the history
  • Loading branch information
timvink committed Feb 26, 2020
1 parent 582d0b3 commit 4e36cbe
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 30 deletions.
75 changes: 56 additions & 19 deletions mkdocs_git_revision_date_localized_plugin/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,31 @@
from datetime import datetime
from babel.dates import format_date


class Util:

def __init__(self, path = "."):
self.repo = Git(path)

# Checks when running builds on CI
# See https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/10
if is_shallow_clone(self.repo):
n_commits = commit_count(self.repo)

if os.environ.get('GITLAB_CI') and n_commits < 50:
logging.warning("""
Running on a gitlab runner might lead to wrong git revision dates
due to a shallow git fetch depth.
Make sure to set GIT_DEPTH to 1000 in your .gitlab-ci.yml file.
(see https://docs.gitlab.com/ee/user/project/pipelines/settings.html#git-shallow-clone).
""")
if os.environ.get('GITHUB_ACTIONS') and n_commits == 1:
logging.warning("""
Running on github actions might lead to wrong git revision dates
due to a shallow git fetch depth.
Try setting fetch-depth to 0 in your github action
(see https://github.com/actions/checkout).
""")

@staticmethod
def _date_formats(unix_timestamp, locale = 'en'):
Expand Down Expand Up @@ -50,27 +71,43 @@ def get_revision_date_for_file(self, path, locale = 'en'):
"""

unix_timestamp = self.repo.log(path, n=1, date='short', format='%at')



if not unix_timestamp:

if os.environ.get('GITLAB_CI'):
raise EnvironmentError("""Cannot access git commit for '%s'.
Try setting GIT_DEPTH to 1000 in your .gitlab-ci.yml file.
(see https://docs.gitlab.com/ee/user/project/pipelines/settings.html#git-shallow-clone).
Or disable mkdocs-git-revision-date-localized-plugin when using gitlab runners.
""" % path)

if os.environ.get('GITHUB_ACTIONS'):
raise EnvironmentError("""Cannot access git commit for '%s'.
Try setting fetch-depth to 1 in your github action
(see https://github.com/actions/checkout).
Or disable mkdocs-git-revision-date-localized-plugin when using github actions.
""" % path)

unix_timestamp = datetime.utcnow().timestamp()
logging.warning('%s has no git logs, using current timestamp' % path)



return self._date_formats(unix_timestamp)

def is_shallow_clone(repo):
"""
Helper function to determine if repository
is a shallow clone.
References:
https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/10
https://stackoverflow.com/a/37203240/5525118
Args:
repo (git.Repo): Repository
Returns:
bool: If a repo is shallow clone
"""
return os.path.exists(".git/shallow")


def commit_count(repo):
"""
Helper function to determine the number of commits in a repository
Args:
repo (git.Repo): Repository
Returns:
count (int): Number of commits
"""
refs = repo.for_each_ref().split('\n')
refs = [x.split()[0] for x in refs]

counts = [int(repo.rev_list(x, count=True, first_parent=True)) for x in refs]
return max(counts)
63 changes: 52 additions & 11 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import shutil
import pytest
import git
import logging

from mkdocs_git_revision_date_localized_plugin.util import Util

Expand Down Expand Up @@ -44,6 +45,8 @@ def setup_clean_mkdocs_folder(mkdocs_yml_path, output_path):

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

# Copy correct mkdocs.yml file and our test 'docs/'
Expand All @@ -62,6 +65,9 @@ def setup_commit_history(testproject_path):
Args:
testproject_path (Path): Path to test project
Returns:
repo (repo): git.Repo object
"""
assert not os.path.exists(testproject_path / '.git')

Expand All @@ -75,8 +81,19 @@ def setup_commit_history(testproject_path):
try:
repo.git.add('mkdocs.yml')
repo.git.commit(message = 'add mkdocs', author = author)

repo.git.add('docs/first_page.md')
repo.git.commit(message = 'first page', author = author)
file_name = os.path.join(testproject_path, 'docs/first_page.md')
with open(file_name, 'w+') as the_file:
the_file.write('Hello\n')
repo.git.add('docs/first_page.md')
repo.git.commit(message = 'first page update 1', author = author)
with open(file_name, 'w') as the_file:
the_file.write('# First Test Page Edited\n\nSome Lorem text')
repo.git.add('docs/first_page.md')
repo.git.commit(message = 'first page update 2', author = author)

repo.git.add('docs/second_page.md')
repo.git.commit(message = 'second page', author = author)
repo.git.add('docs/index.md')
Expand All @@ -87,6 +104,8 @@ def setup_commit_history(testproject_path):
except:
os.chdir(cwd)
raise

return repo

def build_docs_setup(testproject_path):
"""
Expand Down Expand Up @@ -225,23 +244,45 @@ def test_type_unknown(tmp_path):
tmp_path,
'tests/basic_setup/mkdocs_unknown_type.yml')

def test_low_fetch_depth(tmp_path):
def test_low_fetch_depth(tmp_path, caplog):
"""
On gitlab and github runners, a GIT might have a low fetch
depth, which means commits are not available.
This should throw informative errors.
"""

pass
testproject_path = setup_clean_mkdocs_folder('tests/basic_setup/mkdocs.yml', tmp_path)
repo = setup_commit_history(testproject_path)

# Test correct error messages when GIT is not available
#target_dir = os.path.join(tmp_path, 'nogit')
#shutil.copytree(os.path.join(os.getcwd(), 'test/basic_setup'),
# target_dir)
# Create a second, clean folder to clone to
cloned_folder = tmp_path.parent / 'clonedrepo'
if os.path.exists(cloned_folder):
shutil.rmtree(cloned_folder)
os.mkdir(cloned_folder)

# Clone the local repo with fetch depth of 1
repo = git.Repo.init(cloned_folder, bare = False)
origin = repo.create_remote('origin', testproject_path)
origin.fetch(depth=1, prune=True)
repo.create_head('master', origin.refs.master) # create local branch "master" from remote "master"
repo.heads.master.set_tracking_branch(origin.refs.master) # set local "master" to track remote "master
repo.heads.master.checkout() # checkout local "master" to working tree

# should not raise warning
result = build_docs_setup(cloned_folder)
assert result.exit_code == 0

# should raise warning
os.environ["GITLAB_CI"] = "1"
result = build_docs_setup(cloned_folder)
assert result.exit_code == 0
assert 'Running on a gitlab runner' in caplog.text

del os.environ['GITLAB_CI']
os.environ["GITHUB_ACTIONS"] = "1"
result = build_docs_setup(cloned_folder)
assert result.exit_code == 0
assert 'Running on github actions might' in caplog.text

# ...
#result = build_docs_setup(os.path.join(target_dir,'mkdocs.yml'), target_dir)

#with pytest.warns(UserWarning):
# assert result.exit_code == 0, "'mkdocs build' command failed"

# TODO: Test correct error messages when GIT is not available

0 comments on commit 4e36cbe

Please sign in to comment.