1
0
Fork 0

Merging upstream version 0.18.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 06:06:24 +01:00
parent 0453b640a2
commit 129d2ce1fc
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
118 changed files with 4146 additions and 2087 deletions

View file

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# pylint: disable=too-many-function-args,unexpected-keyword-arg
import io
import os
from qa.shell import echo, git, gitlint
from qa.base import BaseTestCase
@ -8,7 +6,7 @@ from qa.utils import DEFAULT_ENCODING
class IntegrationTests(BaseTestCase):
""" Simple set of integration tests for gitlint """
"""Simple set of integration tests for gitlint"""
def test_successful(self):
# Test for STDIN with and without a TTY attached
@ -17,8 +15,8 @@ class IntegrationTests(BaseTestCase):
self.assertEqualStdout(output, "")
def test_successful_gitconfig(self):
""" Test gitlint when the underlying repo has specific git config set.
In the past, we've had issues with gitlint failing on some of these, so this acts as a regression test. """
"""Test gitlint when the underlying repo has specific git config set.
In the past, we've had issues with gitlint failing on some of these, so this acts as a regression test."""
# Different commentchar (Note: tried setting this to a special unicode char, but git doesn't like that)
git("config", "--add", "core.commentchar", "$", _cwd=self.tmp_git_repo)
@ -27,8 +25,8 @@ class IntegrationTests(BaseTestCase):
self.assertEqualStdout(output, "")
def test_successful_merge_commit(self):
# Create branch on master
self.create_simple_commit("Cömmit on master\n\nSimple bödy")
# Create branch on main
self.create_simple_commit("Cömmit on main\n\nSimple bödy")
# Create test branch, add a commit and determine the commit hash
git("checkout", "-b", "test-branch", _cwd=self.tmp_git_repo)
@ -37,10 +35,10 @@ class IntegrationTests(BaseTestCase):
self.create_simple_commit(f"{commit_title}\n\nSïmple body")
hash = self.get_last_commit_hash()
# Checkout master and merge the commit
# Checkout main and merge the commit
# We explicitly set the title of the merge commit to the title of the previous commit as this or similar
# behavior is what many tools do that handle merges (like github, gerrit, etc).
git("checkout", "master", _cwd=self.tmp_git_repo)
git("checkout", "main", _cwd=self.tmp_git_repo)
git("merge", "--no-ff", "-m", f"Merge '{commit_title}'", hash, _cwd=self.tmp_git_repo)
# Run gitlint and assert output is empty
@ -54,18 +52,14 @@ class IntegrationTests(BaseTestCase):
def test_fixup_commit(self):
# Create a normal commit and assert that it has a violation
test_filename = self.create_simple_commit("Cömmit on WIP master\n\nSimple bödy that is long enough")
test_filename = self.create_simple_commit("Cömmit on WIP main\n\nSimple bödy that is long enough")
output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1])
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\n"
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP main\"\n"
self.assertEqualStdout(output, expected)
# Make a small modification to the commit and commit it using fixup commit
with io.open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh:
# Wanted to write a unicode string, but that's obnoxious if you want to do it across Python 2 and 3.
# https://stackoverflow.com/questions/22392377/
# error-writing-a-file-with-file-write-in-python-unicodeencodeerror
# So just keeping it simple - ASCII will here
fh.write("Appending some stuff\n")
with open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh:
fh.write("Appending söme stuff\n")
git("add", test_filename, _cwd=self.tmp_git_repo)
@ -78,13 +72,44 @@ class IntegrationTests(BaseTestCase):
# Make sure that if we set the ignore-fixup-commits option to false that we do still see the violations
output = gitlint("-c", "general.ignore-fixup-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2])
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"fixup! Cömmit on WIP master\"\n" + \
expected = (
"1: T5 Title contains the word 'WIP' (case-insensitive): \"fixup! Cömmit on WIP main\"\n"
"3: B6 Body message is missing\n"
)
self.assertEqualStdout(output, expected)
def test_fixup_amend_commit(self):
# Create a normal commit and assert that it has a violation
test_filename = self.create_simple_commit("Cömmit on WIP main\n\nSimple bödy that is long enough")
output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1])
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP main\"\n"
self.assertEqualStdout(output, expected)
# Make a small modification to the commit and commit it using fixup=amend commit
with open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh:
fh.write("Appending söme stuff\n")
git("add", test_filename, _cwd=self.tmp_git_repo)
# We have to use --no-edit to avoid git starting $EDITOR to modify the commit message that is being amended
git("commit", "--no-edit", f"--fixup=amend:{self.get_last_commit_hash()}", _cwd=self.tmp_git_repo)
# Assert that gitlint does not show an error for the fixup commit
output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True)
# No need to check exit code, the command above throws an exception on > 0 exit codes
self.assertEqualStdout(output, "")
# Make sure that if we set the ignore-fixup-commits option to false that we do still see the violations
output = gitlint(
"-c", "general.ignore-fixup-amend-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]
)
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"amend! Cömmit on WIP main\"\n"
self.assertEqualStdout(output, expected)
def test_revert_commit(self):
self.create_simple_commit("WIP: Cömmit on master.\n\nSimple bödy")
self.create_simple_commit("WIP: Cömmit on main.\n\nSimple bödy")
hash = self.get_last_commit_hash()
git("revert", hash, _cwd=self.tmp_git_repo)
@ -93,21 +118,22 @@ class IntegrationTests(BaseTestCase):
self.assertEqualStdout(output, "")
# Assert that we do see the error if we disable the ignore-revert-commits option
output = gitlint("-c", "general.ignore-revert-commits=false",
_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1])
output = gitlint(
"-c", "general.ignore-revert-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]
)
self.assertEqual(output.exit_code, 1)
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Revert \"WIP: Cömmit on master.\"\"\n"
expected = '1: T5 Title contains the word \'WIP\' (case-insensitive): "Revert "WIP: Cömmit on main.""\n'
self.assertEqualStdout(output, expected)
def test_squash_commit(self):
# Create a normal commit and assert that it has a violation
test_filename = self.create_simple_commit("Cömmit on WIP master\n\nSimple bödy that is long enough")
test_filename = self.create_simple_commit("Cömmit on WIP main\n\nSimple bödy that is long enough")
output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1])
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\n"
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP main\"\n"
self.assertEqualStdout(output, expected)
# Make a small modification to the commit and commit it using squash commit
with io.open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh:
with open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh:
# Wanted to write a unicode string, but that's obnoxious if you want to do it across Python 2 and 3.
# https://stackoverflow.com/questions/22392377/
# error-writing-a-file-with-file-write-in-python-unicodeencodeerror
@ -124,10 +150,13 @@ class IntegrationTests(BaseTestCase):
self.assertEqualStdout(output, "")
# Make sure that if we set the ignore-squash-commits option to false that we do still see the violations
output = gitlint("-c", "general.ignore-squash-commits=false",
_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2])
expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"squash! Cömmit on WIP master\"\n" + \
"3: B5 Body message is too short (14<20): \"Töo short body\"\n"
output = gitlint(
"-c", "general.ignore-squash-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2]
)
expected = (
"1: T5 Title contains the word 'WIP' (case-insensitive): \"squash! Cömmit on WIP main\"\n"
'3: B5 Body message is too short (14<20): "Töo short body"\n'
)
self.assertEqualStdout(output, expected)
@ -139,11 +168,11 @@ class IntegrationTests(BaseTestCase):
def test_msg_filename(self):
tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename test.")
output = gitlint("--msg-filename", tmp_commit_msg_file, _tty_in=True, _ok_code=[3])
output = gitlint("--msg-filename", tmp_commit_msg_file, _tty_in=True, _cwd=self.tmp_git_repo, _ok_code=[3])
self.assertEqualStdout(output, self.get_expected("test_gitlint/test_msg_filename_1"))
def test_msg_filename_no_tty(self):
""" Make sure --msg-filename option also works with no TTY attached """
"""Make sure --msg-filename option also works with no TTY attached"""
tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO TTY test.")
# We need to set _err_to_out explicitly for sh to merge stdout and stderr output in case there's
@ -151,34 +180,51 @@ class IntegrationTests(BaseTestCase):
# http://amoffat.github.io/sh/sections/special_arguments.html?highlight=_tty_in#err-to-out
# We need to pass some whitespace to _in as sh will otherwise hang, see
# https://github.com/amoffat/sh/issues/427
output = gitlint("--msg-filename", tmp_commit_msg_file, _in=" ",
_tty_in=False, _err_to_out=True, _ok_code=[3])
output = gitlint(
"--msg-filename",
tmp_commit_msg_file,
_cwd=self.tmp_git_repo,
_in=" ",
_tty_in=False,
_err_to_out=True,
_ok_code=[3],
)
self.assertEqualStdout(output, self.get_expected("test_gitlint/test_msg_filename_no_tty_1"))
def test_no_git_name_set(self):
""" Ensure we print out a helpful message if user.name is not set """
"""Ensure we print out a helpful message if user.name is not set"""
tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO name test.")
# Name is checked before email so this isn't strictly
# necessary but seems good for consistency.
env = self.create_tmp_git_config("[user]\n email = test-emåil@foo.com\n")
output = gitlint("--staged", "--msg-filename", tmp_commit_msg_file,
_ok_code=[self.GIT_CONTEXT_ERROR_CODE],
_env=env)
output = gitlint(
"--staged",
"--msg-filename",
tmp_commit_msg_file,
_ok_code=[self.GIT_CONTEXT_ERROR_CODE],
_env=env,
_cwd=self.tmp_git_repo,
)
expected = "Missing git configuration: please set user.name\n"
self.assertEqualStdout(output, expected)
def test_no_git_email_set(self):
""" Ensure we print out a helpful message if user.email is not set """
"""Ensure we print out a helpful message if user.email is not set"""
tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO email test.")
env = self.create_tmp_git_config("[user]\n name = test åuthor\n")
output = gitlint("--staged", "--msg-filename", tmp_commit_msg_file,
_ok_code=[self.GIT_CONTEXT_ERROR_CODE],
_env=env)
output = gitlint(
"--staged",
"--msg-filename",
tmp_commit_msg_file,
_ok_code=[self.GIT_CONTEXT_ERROR_CODE],
_env=env,
_cwd=self.tmp_git_repo,
)
expected = "Missing git configuration: please set user.email\n"
self.assertEqualStdout(output, expected)
def test_git_errors(self):
def test_git_empty_repo(self):
# Repo has no commits: caused by `git log`
empty_git_repo = self.create_tmp_git_repo()
output = gitlint(_cwd=empty_git_repo, _tty_in=True, _ok_code=[self.GIT_CONTEXT_ERROR_CODE])
@ -186,7 +232,36 @@ class IntegrationTests(BaseTestCase):
expected = "Current branch has no commits. Gitlint requires at least one commit to function.\n"
self.assertEqualStdout(output, expected)
# Repo has no commits: caused by `git rev-parse`
output = gitlint(echo("WIP: Pïpe test."), "--staged", _cwd=empty_git_repo, _tty_in=False,
_err_to_out=True, _ok_code=[self.GIT_CONTEXT_ERROR_CODE])
def test_git_empty_repo_staged(self):
"""When repo is empty, we can still use gitlint when using --staged flag and piping a message into it"""
empty_git_repo = self.create_tmp_git_repo()
expected = (
'1: T3 Title has trailing punctuation (.): "WIP: Pïpe test."\n'
"1: T5 Title contains the word 'WIP' (case-insensitive): \"WIP: Pïpe test.\"\n"
"3: B6 Body message is missing\n"
)
output = gitlint(
echo("WIP: Pïpe test."), "--staged", _cwd=empty_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3]
)
self.assertEqualStdout(output, expected)
def test_commit_binary_file(self):
"""When committing a binary file, git shows somewhat different output in diff commands,
this test ensures gitlint deals with that correctly"""
binary_filename = self.create_simple_commit("Sïmple commit", file_contents=bytes([0x48, 0x00, 0x49, 0x00]))
output = gitlint(
"--debug",
_ok_code=1,
_cwd=self.tmp_git_repo,
)
expected_kwargs = self.get_debug_vars_last_commit()
expected_kwargs.update(
{
"changed_files": [binary_filename],
"changed_files_stats": (f"{binary_filename}: None additions, None deletions"),
}
)
expected = self.get_expected("test_gitlint/test_commit_binary_file_1", expected_kwargs)
self.assertEqualStdout(output, expected)