Skip to content

Commit

Permalink
Remove support of Git 2.18 and earlier versions
Browse files Browse the repository at this point in the history
We maintained non-obvious code to support versions of Git that did not
have the `--only-matching` option, which appeared in Git 2.19. This
version was released in September 2018, it's time to move on.
  • Loading branch information
dbaty committed May 15, 2024
1 parent 500049f commit 7e7630d
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 76 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

- Add support of Python 3.12.

- |backward-incompatible| Remove support of Git 2.18 and earlier
version. You must now have Git 2.19 (or a more recent version).

- |backward-incompatible| Remove support of Python 3.7.

- |backward-incompatible| Remove ``--xunit-file`` argument from all
Expand Down
4 changes: 1 addition & 3 deletions docs/installation.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
Installation
============

You must have Python 3.8 or later, and a relatively recent version of
Git. Git 2.1.4 (shipped with Debian Jessie) is known to work. More
recent versions should work and are supported.
You must have Python 3.8 or later, and Git 2.19.0 or later.

Install with ``pip``, preferably in a `virtual environment`_:

Expand Down
81 changes: 20 additions & 61 deletions src/check_oldies/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
import dataclasses
import datetime
import re
import subprocess
import typing

import pkg_resources

from . import commands
from . import output

Expand Down Expand Up @@ -230,66 +227,28 @@ def get_known_future_tags(directory, annotation_regex, future_tag_regex, whiteli
return set(lines)


def git_supports_only_matching():
out = subprocess.check_output(["git", "--version"]).decode("utf-8")
# output looks like "git version 2.26.0"
git_version = pkg_resources.parse_version(out.split()[2])
# `git grep --only-matching` appeared in Git 2.19.0
# https://github.com/git/git/blob/v2.19.0/Documentation/RelNotes/2.19.0.txt#L41
minimal_version = pkg_resources.parse_version("2.19.0")
return git_version >= minimal_version


def get_all_futures(directory, future_tag_regex, whitelist):
"""Get all occurrences of FUTURE tags."""
# Old versions of Git (such as Git 2.1.4 that is shipped by Debian
# Jessie) do not support the `--only-matching` option. Pipe to
# `sed` instead.
if git_supports_only_matching():
grep = [
"git",
"grep",
"-I", # ignore binary files
"--line-number",
"--extended-regexp",
"--only-matching",
"-e",
future_tag_regex,
"--and",
"--not",
"-e",
IGNORE_PRAGMA,
]
grep.extend([f":(exclude){glob}" for glob in whitelist])
lines = commands.get_output(
grep,
cwd=directory,
valid_return_codes=(0, 1), # 0 if there are matches, 1 otherwise
)
else:
grep = [
"git",
"grep",
"-I", # ignore binary files
"--line-number",
"--extended-regexp",
"-e",
future_tag_regex,
"--and",
"--not",
"-e",
IGNORE_PRAGMA,
"--", # needed on old versions...
".", # ... of git
]
grep.extend([f":(exclude){glob}" for glob in whitelist])
sed = f'sed --regexp-extended "s/(.*?):.*?({future_tag_regex}).*?/\\1:\\2/g"'
lines = commands.get_pipe_command_output(
grep,
piped_to=sed,
cwd=directory,
valid_return_codes=(0, 1), # 0 if there are matches, 1 otherwise
)
grep = [
"git",
"grep",
"-I", # ignore binary files
"--line-number",
"--extended-regexp",
"--only-matching",
"-e",
future_tag_regex,
"--and",
"--not",
"-e",
IGNORE_PRAGMA,
]
grep.extend([f":(exclude){glob}" for glob in whitelist])
lines = commands.get_output(
grep,
cwd=directory,
valid_return_codes=(0, 1), # 0 if there are matches, 1 otherwise
)

occurrences = collections.defaultdict(list)
for line in lines:
Expand Down
12 changes: 0 additions & 12 deletions tests/test_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,3 @@ def test_get_login_from_committer_email():
assert login == "<@example.com>" # should not be the empty string
login = annotations.get_login_from_committer_email("John Smith")
assert login == "John Smith"


def test_git_supports_only_matching():
# We expect tests to run on a system that has a recent version of Git.
assert annotations.git_supports_only_matching()


@mock.patch("check_oldies.annotations.git_supports_only_matching", lambda: False)
def test_old_git_without_only_matching():
path = base.TEST_DIR_PATH / "data/project4"
futures = annotations.get_all_futures(path, base.TESTING_FUTURE_TAG, whitelist=[])
assert set(futures.keys()) == {"FEWTURE-BOOM", "FEWTURE-I-AM-AN-ORPHAN"}

0 comments on commit 7e7630d

Please sign in to comment.