Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test_run_hook_edit is not portable #196

Open
l0b0 opened this issue Jul 28, 2021 · 2 comments
Open

test_run_hook_edit is not portable #196

l0b0 opened this issue Jul 28, 2021 · 2 comments
Assignees
Labels
development Issues that are not user-facing but related to gitlint development
Milestone

Comments

@l0b0
Copy link
Contributor

l0b0 commented Jul 28, 2021

test_run_hook_edit relies on the default $EDITOR value of the CI environment, which is not portable. For example, on Arch Linux the test fails with the following error:

E           AssertionError: expected call not found.
E           Expected: shell('vim -n /tmp/tmpj8g6mqhp/hür')
E           Actual: shell('vim /tmp/tmpj8g6mqhp/hür')

The test which doesn't set an editor should probably be removed, so that the test suite is more portable.

@jorisroovers
Copy link
Owner

Actually, that test isn't meant to depend on the environment, it overrides os.environ['EDITOR'] here:

set_editors = [None, "myeditor"]
expected_editors = ["vim -n", "myeditor"]
commit_messages = ["WIP: höok edit 1", "WIP: höok edit 2"]
for i in range(0, len(set_editors)):
if set_editors[i]:
os.environ['EDITOR'] = set_editors[i]

That first set_editor[0] set to None in particular is meant to test for the default test case where no $EDITOR is set and gitlint falls back to vim -n, see following 2 snippets.

DEFAULT_COMMIT_MSG_EDITOR = "vim -n"

editor = os.environ.get("EDITOR", DEFAULT_COMMIT_MSG_EDITOR)

I'm not sure why this test is failing for you then, there might be something wrong in my testing logic. Would need to dig in a bit deeper.

FYI that I do have it on the roadmap to respect git config core.editor instead of having a hard coded $EDITOR fallback, just haven't gotten around to that.

@l0b0
Copy link
Contributor Author

l0b0 commented Aug 16, 2021

Interesting! FWIW, here's an extract of my settings:

  • git config core.editor is not set
  • $EDITOR is just vim
  • Up-to-date version of Arch Linux
  • Python 3.8.10

Test results on your current main branch (commit 1a0ed8d, "Bump arrow from 1.0.3 to 1.1.1 (#210)"), of which it looks like many more are not portable:

$ ./run_tests.sh --all
### PYTHON (Python 3.8.10, /home/victor/dev/gitlint/.venv/bin/python) ###
# UNIT TESTS (Python 3.8.10, /home/victor/dev/gitlint/.venv/bin/python) #
Cleaning the *.pyc, site/, build/, dist/ and all __pycache__ directories...DONE
=========================================== test session starts ============================================
platform linux -- Python 3.8.10, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/victor/dev/gitlint
collected 174 items                                                                                        

gitlint/tests/test_cache.py ..
gitlint/tests/test_display.py ..
gitlint/tests/test_hooks.py .....
gitlint/tests/test_lint.py .............
gitlint/tests/test_options.py .......
gitlint/tests/test_utils.py ...
gitlint/tests/cli/test_cli.py ...........................
gitlint/tests/cli/test_cli_hooks.py ....F.........
gitlint/tests/config/test_config.py ...........
gitlint/tests/config/test_config_builder.py ...........
gitlint/tests/config/test_config_precedence.py ...
gitlint/tests/config/test_rule_collection.py ...
gitlint/tests/contrib/test_contrib_rules.py ....
gitlint/tests/contrib/rules/test_conventional_commit.py ..
gitlint/tests/contrib/rules/test_signedoff_by.py ..
gitlint/tests/git/test_git.py .....
gitlint/tests/git/test_git_commit.py .................
gitlint/tests/git/test_git_context.py ..
gitlint/tests/rules/test_body_rules.py ..........
gitlint/tests/rules/test_configuration_rules.py ...
gitlint/tests/rules/test_meta_rules.py ..
gitlint/tests/rules/test_rules.py ...
gitlint/tests/rules/test_title_rules.py ........
gitlint/tests/rules/test_user_rules.py ...............

================================================= FAILURES =================================================
_____________________________________ CLIHookTests.test_run_hook_edit ______________________________________

self = <test_cli_hooks.CLIHookTests testMethod=test_run_hook_edit>
shell = <MagicMock name='shell' id='139628048481056'>

    @patch('gitlint.cli.shell')
    def test_run_hook_edit(self, shell):
        """ Test for run-hook subcommand, answering 'e(dit)' after commit-hook """
    
        set_editors = [None, "myeditor"]
        expected_editors = ["vim -n", "myeditor"]
        commit_messages = ["WIP: höok edit 1", "WIP: höok edit 2"]
    
        for i in range(0, len(set_editors)):
            if set_editors[i]:
                os.environ['EDITOR'] = set_editors[i]
    
            with self.patch_input(['e', 'e', 'n']):
                with self.tempdir() as tmpdir:
                    msg_filename = os.path.realpath(os.path.join(tmpdir, "hür"))
                    with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f:
                        f.write(commit_messages[i] + "\n")
    
                    with patch('gitlint.display.stderr', new=StringIO()) as stderr:
                        result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"])
                        self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_edit_1_stdout',
                                                                          {"commit_msg": commit_messages[i]}))
                        expected = self.get_expected("cli/test_cli_hooks/test_hook_edit_1_stderr",
                                                     {"commit_msg": commit_messages[i]})
                        self.assertEqual(stderr.getvalue(), expected)
    
                        # exit code = number of violations
                        self.assertEqual(result.exit_code, 2)
    
>                       shell.assert_called_with(expected_editors[i] + " " + msg_filename)

gitlint/tests/cli/test_cli_hooks.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock name='shell' id='139628048481056'>, args = ('vim -n /tmp/tmp73os0w2w/hür',), kwargs = {}
expected = (('vim -n /tmp/tmp73os0w2w/hür',), {}), actual = call('vim /tmp/tmp73os0w2w/hür')
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x7efdb064b040>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher((args, kwargs))
        actual = self._call_matcher(self.call_args)
        if expected != actual:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: shell('vim -n /tmp/tmp73os0w2w/hür')
E           Actual: shell('vim /tmp/tmp73os0w2w/hür')

../../.pyenv/versions/3.8.10/lib/python3.8/unittest/mock.py:913: AssertionError
====================================== 1 failed, 173 passed in 1.29s =======================================
Name                                           Stmts   Miss Branch BrPart  Cover   Missing
------------------------------------------------------------------------------------------
gitlint/__init__.py                                1      0      0      0   100%
gitlint/cache.py                                  19      0      6      0   100%
gitlint/cli.py                                   256      8     76      3    95%   73, 131-139, 182->exit, 403->352
gitlint/config.py                                296      0     85      0   100%
gitlint/contrib/__init__.py                        0      0      0      0   100%
gitlint/contrib/rules/__init__.py                  0      0      0      0   100%
gitlint/contrib/rules/conventional_commit.py      20      0      6      0   100%
gitlint/contrib/rules/signedoff_by.py              9      0      4      0   100%
gitlint/display.py                                22      0      6      0   100%
gitlint/exception.py                               2      0      0      0   100%
gitlint/git.py                                   217      0     18      0   100%
gitlint/hooks.py                                  42      0      8      0   100%
gitlint/lint.py                                   67      0     32      0   100%
gitlint/options.py                                89      1     26      0    99%   43
gitlint/rule_finder.py                            64      0     44      1    99%   134->140
gitlint/rules.py                                 273      1     74      1    99%   30->33, 91
gitlint/shell.py                                  42     35      6      1    17%   14-15, 24-77
gitlint/utils.py                                  33      0     10      0   100%
------------------------------------------------------------------------------------------
TOTAL                                           1452     45    401      6    97%
# INTEGRATION TESTS (Python 3.8.10, /home/victor/dev/gitlint/.venv/bin/python) #
Cleaning the *.pyc, site/, build/, dist/ and all __pycache__ directories...DONE

gitlint, version 0.16.0dev
Using /home/victor/dev/gitlint/.venv/bin/gitlint

=========================================== test session starts ============================================
platform linux -- Python 3.8.10, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/victor/dev/gitlint
collected 44 items                                                                                         

qa/test_commits.py ...FF..
qa/test_config.py F.F....
qa/test_contrib.py ...
qa/test_gitlint.py ..........F.
qa/test_hooks.py .FFF.
qa/test_named_rules.py ..
qa/test_stdin.py ...
qa/test_user_defined.py .FFFF

================================================= FAILURES =================================================
________________________________ CommitsTests.test_lint_staged_msg_filename ________________________________

self = <qa.test_commits.CommitsTests testMethod=test_lint_staged_msg_filename>

    def test_lint_staged_msg_filename(self):
        """ Tests linting a staged commit. Gitint should lint the passed commit message andfetch additional meta-data
            from the underlying repository. The easiest way to test this is by inspecting `--debug` output.
            This is the equivalent of doing:
            gitlint --msg-filename /tmp/my-commit-msg --staged --debug
        """
        # Create a commit first, before we stage changes. This ensures the repo is properly initialized.
        self.create_simple_commit("Sïmple title.\n")
    
        # Add some files, stage them: they should show up in the debug output as changed file
        filename1 = self.create_file(self.tmp_git_repo)
        git("add", filename1, _cwd=self.tmp_git_repo)
        filename2 = self.create_file(self.tmp_git_repo)
        git("add", filename2, _cwd=self.tmp_git_repo)
    
        tmp_commit_msg_file = self.create_tmpfile("WIP: from fïle test.")
    
        output = gitlint("--msg-filename", tmp_commit_msg_file, "--staged", "--debug",
                         _cwd=self.tmp_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3])
    
        # Determine variable parts of expected output
        expected_kwargs = self.get_debug_vars_last_commit()
        expected_kwargs.update({'changed_files': sorted([filename1, filename2])})
    
        # It's not really possible to determine the "Date: ..." line that is part of the debug output as this date
        # is not taken from git but instead generated by gitlint itself. As a workaround, we extract the date from the
        # gitlint output using a regex, parse the date to ensure the format is correct, and then pass that as an
        # expected variable.
        matches = re.search(r'^Date:\s+(.*)', str(output), re.MULTILINE)
        if matches:
            expected_date = arrow.get(str(matches.group(1)), "YYYY-MM-DD HH:mm:ss Z").format("YYYY-MM-DD HH:mm:ss Z")
            expected_kwargs['staged_date'] = expected_date
    
        expected = self.get_expected("test_commits/test_lint_staged_msg_filename_1", expected_kwargs)
>       self.assertEqualStdout(output, expected)

qa/test_commits.py:124: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: 'DEBU[2481 chars][\'main\']\nChanged Files: [\'test-fïle-16ec33[321 chars] 3\n' != 'DEBU[2481 chars][\'master\']\nChanged Files: [\'test-fïle-16ec[323 chars] 3\n'
E     DEBUG: gitlint.cli To report issues, please visit https://github.com/jorisroovers/gitlint/issues
E     DEBUG: gitlint.cli Platform: Linux-5.10.56-1-lts-x86_64-with-glibc2.33
E     DEBUG: gitlint.cli Python version: 3.8.10 (default, Jul  7 2021, 14:29:06) 
E     [GCC 11.1.0]
E     DEBUG: gitlint.git ('--version',)
E     DEBUG: gitlint.cli Git version: git version 2.32.0
E     DEBUG: gitlint.cli Gitlint version: 0.16.0dev
E     DEBUG: gitlint.cli GITLINT_USE_SH_LIB: [NOT SET]
E     DEBUG: gitlint.cli DEFAULT_ENCODING: UTF-8
E     DEBUG: gitlint.cli Configuration
E     config-path: None
E     [GENERAL]
E     extra-path: None
E     contrib: []
E     ignore: 
E     ignore-merge-commits: True
E     ignore-fixup-commits: True
E     ignore-squash-commits: True
E     ignore-revert-commits: True
E     ignore-stdin: False
E     staged: True
E     verbosity: 3
E     debug: True
E     target: /tmp/gitlint-test-20210816-152125-050593
E     [RULES]
E       I1: ignore-by-title
E          ignore=all
E          regex=None
E       I2: ignore-by-body
E          ignore=all
E          regex=None
E       I3: ignore-body-lines
E          regex=None
E       T1: title-max-length
E          line-length=72
E       T2: title-trailing-whitespace
E       T6: title-leading-whitespace
E       T3: title-trailing-punctuation
E       T4: title-hard-tab
E       T5: title-must-not-contain-word
E          words=WIP
E       T7: title-match-regex
E          regex=None
E       T8: title-min-length
E          min-length=5
E       B1: body-max-line-length
E          line-length=80
E       B5: body-min-length
E          min-length=20
E       B6: body-is-missing
E          ignore-merge-commits=True
E       B2: body-trailing-whitespace
E       B3: body-hard-tab
E       B4: body-first-line-empty
E       B7: body-changed-file-mention
E          files=
E       B8: body-match-regex
E          regex=None
E       M1: author-valid-email
E          regex=[^@ ]+@[^@ ]+\.[^@ ]+
E     
E     DEBUG: gitlint.cli Fetching additional meta-data from staged commit
E     DEBUG: gitlint.cli Using --msg-filename.
E     DEBUG: gitlint.git ('config', '--get', 'core.commentchar')
E     DEBUG: gitlint.cli Linting 1 commit(s)
E     DEBUG: gitlint.lint Linting commit [SHA UNKNOWN]
E     DEBUG: gitlint.git ('config', '--get', 'user.name')
E     DEBUG: gitlint.git ('config', '--get', 'user.email')
E     DEBUG: gitlint.git ('rev-parse', '--abbrev-ref', 'HEAD')
E     DEBUG: gitlint.git ('diff', '--staged', '--name-only', '-r')
E     DEBUG: gitlint.lint Commit Object
E     --- Commit Message ----
E     WIP: from fïle test.
E     --- Meta info ---------
E     Author: gitlint-test-user <[email protected]>
E     Date:   2021-08-16 15:21:25 +1200
E     is-merge-commit:  False
E     is-fixup-commit:  False
E     is-squash-commit: False
E     is-revert-commit: False
E   - Branches: ['main']
E   ?               ^^
E   + Branches: ['master']
E   ?               ^^^^
E     Changed Files: ['test-fïle-16ec3372-9d3e-4cc0-8996-9616415a8c95', 'test-fïle-817da5ca-8929-4b0d-b2a6-0ca961dc10ca']
E     -----------------------
E     1: T3 Title has trailing punctuation (.): "WIP: from fïle test."
E     1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: from fïle test."
E     3: B6 Body message is missing
E     DEBUG: gitlint.cli Exit Code = 3
___________________________________ CommitsTests.test_lint_staged_stdin ____________________________________

self = <qa.test_commits.CommitsTests testMethod=test_lint_staged_stdin>

    def test_lint_staged_stdin(self):
        """ Tests linting a staged commit. Gitint should lint the passed commit message andfetch additional meta-data
            from the underlying repository. The easiest way to test this is by inspecting `--debug` output.
            This is the equivalent of doing:
            echo "WIP: Pïpe test." | gitlint --staged --debug
        """
        # Create a commit first, before we stage changes. This ensures the repo is properly initialized.
        self.create_simple_commit("Sïmple title.\n")
    
        # Add some files, stage them: they should show up in the debug output as changed file
        filename1 = self.create_file(self.tmp_git_repo)
        git("add", filename1, _cwd=self.tmp_git_repo)
        filename2 = self.create_file(self.tmp_git_repo)
        git("add", filename2, _cwd=self.tmp_git_repo)
    
        output = gitlint(echo("WIP: Pïpe test."), "--staged", "--debug",
                         _cwd=self.tmp_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3])
    
        # Determine variable parts of expected output
        expected_kwargs = self.get_debug_vars_last_commit()
        expected_kwargs.update({'changed_files': sorted([filename1, filename2])})
    
        # It's not really possible to determine the "Date: ..." line that is part of the debug output as this date
        # is not taken from git but instead generated by gitlint itself. As a workaround, we extract the date from the
        # gitlint output using a regex, parse the date to ensure the format is correct, and then pass that as an
        # expected variable.
        matches = re.search(r'^Date:\s+(.*)', str(output), re.MULTILINE)
        if matches:
            expected_date = arrow.get(str(matches.group(1)), "YYYY-MM-DD HH:mm:ss Z").format("YYYY-MM-DD HH:mm:ss Z")
            expected_kwargs['staged_date'] = expected_date
    
>       self.assertEqualStdout(output, self.get_expected("test_commits/test_lint_staged_stdin_1", expected_kwargs))

qa/test_commits.py:87: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: 'DEBU[2556 chars][\'main\']\nChanged Files: [\'test-fïle-0c87a1[311 chars] 3\n' != 'DEBU[2556 chars][\'master\']\nChanged Files: [\'test-fïle-0c87[313 chars] 3\n'
E     DEBUG: gitlint.cli To report issues, please visit https://github.com/jorisroovers/gitlint/issues
E     DEBUG: gitlint.cli Platform: Linux-5.10.56-1-lts-x86_64-with-glibc2.33
E     DEBUG: gitlint.cli Python version: 3.8.10 (default, Jul  7 2021, 14:29:06) 
E     [GCC 11.1.0]
E     DEBUG: gitlint.git ('--version',)
E     DEBUG: gitlint.cli Git version: git version 2.32.0
E     DEBUG: gitlint.cli Gitlint version: 0.16.0dev
E     DEBUG: gitlint.cli GITLINT_USE_SH_LIB: [NOT SET]
E     DEBUG: gitlint.cli DEFAULT_ENCODING: UTF-8
E     DEBUG: gitlint.cli Configuration
E     config-path: None
E     [GENERAL]
E     extra-path: None
E     contrib: []
E     ignore: 
E     ignore-merge-commits: True
E     ignore-fixup-commits: True
E     ignore-squash-commits: True
E     ignore-revert-commits: True
E     ignore-stdin: False
E     staged: True
E     verbosity: 3
E     debug: True
E     target: /tmp/gitlint-test-20210816-152125-050593
E     [RULES]
E       I1: ignore-by-title
E          ignore=all
E          regex=None
E       I2: ignore-by-body
E          ignore=all
E          regex=None
E       I3: ignore-body-lines
E          regex=None
E       T1: title-max-length
E          line-length=72
E       T2: title-trailing-whitespace
E       T6: title-leading-whitespace
E       T3: title-trailing-punctuation
E       T4: title-hard-tab
E       T5: title-must-not-contain-word
E          words=WIP
E       T7: title-match-regex
E          regex=None
E       T8: title-min-length
E          min-length=5
E       B1: body-max-line-length
E          line-length=80
E       B5: body-min-length
E          min-length=20
E       B6: body-is-missing
E          ignore-merge-commits=True
E       B2: body-trailing-whitespace
E       B3: body-hard-tab
E       B4: body-first-line-empty
E       B7: body-changed-file-mention
E          files=
E       B8: body-match-regex
E          regex=None
E       M1: author-valid-email
E          regex=[^@ ]+@[^@ ]+\.[^@ ]+
E     
E     DEBUG: gitlint.cli Fetching additional meta-data from staged commit
E     DEBUG: gitlint.cli Stdin data: 'WIP: Pïpe test.
E     '
E     DEBUG: gitlint.cli Stdin detected and not ignored. Using as input.
E     DEBUG: gitlint.git ('config', '--get', 'core.commentchar')
E     DEBUG: gitlint.cli Linting 1 commit(s)
E     DEBUG: gitlint.lint Linting commit [SHA UNKNOWN]
E     DEBUG: gitlint.git ('config', '--get', 'user.name')
E     DEBUG: gitlint.git ('config', '--get', 'user.email')
E     DEBUG: gitlint.git ('rev-parse', '--abbrev-ref', 'HEAD')
E     DEBUG: gitlint.git ('diff', '--staged', '--name-only', '-r')
E     DEBUG: gitlint.lint Commit Object
E     --- Commit Message ----
E     WIP: Pïpe test.
E     --- Meta info ---------
E     Author: gitlint-test-user <[email protected]>
E     Date:   2021-08-16 15:21:26 +1200
E     is-merge-commit:  False
E     is-fixup-commit:  False
E     is-squash-commit: False
E     is-revert-commit: False
E   - Branches: ['main']
E   ?               ^^
E   + Branches: ['master']
E   ?               ^^^^
E     Changed Files: ['test-fïle-0c87a183-8cdd-447e-a370-51d5ebb923b6', 'test-fïle-0da051ea-aa00-47ca-9b3d-86e90090fcb7']
E     -----------------------
E     1: T3 Title has trailing punctuation (.): "WIP: Pïpe test."
E     1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: Pïpe test."
E     3: B6 Body message is missing
E     DEBUG: gitlint.cli Exit Code = 3
_____________________________________ ConfigTests.test_config_from_env _____________________________________

self = <qa.test_config.ConfigTests testMethod=test_config_from_env>

    def test_config_from_env(self):
        """ Test for configuring gitlint from environment variables """
    
        # We invoke gitlint, configuring it via env variables, we can check whether gitlint picks these up correctly
        # by comparing the debug output with what we'd expect
        target_repo = self.create_tmp_git_repo()
        commit_msg = "WIP: Thïs is a title thåt is a bit longer.\nContent on the second line\n" + \
                     "This line of the body is here because we need it"
        filename = self.create_simple_commit(commit_msg, git_repo=target_repo)
        env = self.create_environment({"GITLINT_DEBUG": "1", "GITLINT_VERBOSITY": "2",
                                       "GITLINT_IGNORE": "T1,T2", "GITLINT_CONTRIB": "CC1,CT1",
                                       "GITLINT_IGNORE_STDIN": "1", "GITLINT_TARGET": target_repo,
                                       "GITLINT_COMMITS": self.get_last_commit_hash(git_repo=target_repo)})
        output = gitlint(_env=env, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[5])
        expected_kwargs = self.get_debug_vars_last_commit(git_repo=target_repo)
        expected_kwargs.update({'changed_files': [filename]})
    
>       self.assertEqualStdout(output, self.get_expected("test_config/test_config_from_env_1", expected_kwargs))

qa/test_config.py:89: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: "DEBU[2925 chars] ['main']\nChanged Files: ['test-fïle-1bde5185[382 chars] 5\n" != "DEBU[2925 chars] ['master']\nChanged Files: ['test-fïle-1bde51[384 chars] 5\n"
E     DEBUG: gitlint.cli To report issues, please visit https://github.com/jorisroovers/gitlint/issues
E     DEBUG: gitlint.cli Platform: Linux-5.10.56-1-lts-x86_64-with-glibc2.33
E     DEBUG: gitlint.cli Python version: 3.8.10 (default, Jul  7 2021, 14:29:06) 
E     [GCC 11.1.0]
E     DEBUG: gitlint.git ('--version',)
E     DEBUG: gitlint.cli Git version: git version 2.32.0
E     DEBUG: gitlint.cli Gitlint version: 0.16.0dev
E     DEBUG: gitlint.cli GITLINT_USE_SH_LIB: [NOT SET]
E     DEBUG: gitlint.cli DEFAULT_ENCODING: UTF-8
E     DEBUG: gitlint.cli Configuration
E     config-path: None
E     [GENERAL]
E     extra-path: None
E     contrib: ['CC1', 'CT1']
E     ignore: T1,T2
E     ignore-merge-commits: True
E     ignore-fixup-commits: True
E     ignore-squash-commits: True
E     ignore-revert-commits: True
E     ignore-stdin: True
E     staged: False
E     verbosity: 2
E     debug: True
E     target: /tmp/gitlint-test-20210816-152126-521300
E     [RULES]
E       I1: ignore-by-title
E          ignore=all
E          regex=None
E       I2: ignore-by-body
E          ignore=all
E          regex=None
E       I3: ignore-body-lines
E          regex=None
E       T1: title-max-length
E          line-length=72
E       T2: title-trailing-whitespace
E       T6: title-leading-whitespace
E       T3: title-trailing-punctuation
E       T4: title-hard-tab
E       T5: title-must-not-contain-word
E          words=WIP
E       T7: title-match-regex
E          regex=None
E       T8: title-min-length
E          min-length=5
E       B1: body-max-line-length
E          line-length=80
E       B5: body-min-length
E          min-length=20
E       B6: body-is-missing
E          ignore-merge-commits=True
E       B2: body-trailing-whitespace
E       B3: body-hard-tab
E       B4: body-first-line-empty
E       B7: body-changed-file-mention
E          files=
E       B8: body-match-regex
E          regex=None
E       M1: author-valid-email
E          regex=[^@ ]+@[^@ ]+\.[^@ ]+
E       CC1: contrib-body-requires-signed-off-by
E       CT1: contrib-title-conventional-commits
E          types=fix,feat,chore,docs,style,refactor,perf,test,revert,ci,build
E     
E     DEBUG: gitlint.cli No --msg-filename flag, no or empty data passed to stdin. Using the local repo.
E     DEBUG: gitlint.git ('rev-list', '3b73fe612b1d188affc2f7f4e47cdaa13070c8e4')
E     DEBUG: gitlint.cli Linting 1 commit(s)
E     DEBUG: gitlint.git ('log', '3b73fe612b1d188affc2f7f4e47cdaa13070c8e4', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B')
E     DEBUG: gitlint.git ('config', '--get', 'core.commentchar')
E     DEBUG: gitlint.lint Linting commit 3b73fe612b1d188affc2f7f4e47cdaa13070c8e4
E     DEBUG: gitlint.git ('branch', '--contains', '3b73fe612b1d188affc2f7f4e47cdaa13070c8e4')
E     DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', '3b73fe612b1d188affc2f7f4e47cdaa13070c8e4')
E     DEBUG: gitlint.lint Commit Object
E     --- Commit Message ----
E     WIP: Thïs is a title thåt is a bit longer.
E     Content on the second line
E     This line of the body is here because we need it
E     
E     --- Meta info ---------
E     Author: gitlint-test-user <[email protected]>
E     Date:   2021-08-16 15:21:26 +1200
E     is-merge-commit:  False
E     is-fixup-commit:  False
E     is-squash-commit: False
E     is-revert-commit: False
E   - Branches: ['main']
E   ?               ^^
E   + Branches: ['master']
E   ?               ^^^^
E     Changed Files: ['test-fïle-1bde5185-b179-4766-ae90-bf69c060c8ee']
E     -----------------------
E     1: CC1 Body does not contain a 'Signed-off-by' line
E     1: CT1 Title does not start with one of fix, feat, chore, docs, style, refactor, perf, test, revert, ci, build
E     1: T3 Title has trailing punctuation (.)
E     1: T5 Title contains the word 'WIP' (case-insensitive)
E     2: B4 Second line is not empty
E     DEBUG: gitlint.cli Exit Code = 5
_________________________________ ConfigTests.test_config_from_file_debug __________________________________

self = <qa.test_config.ConfigTests testMethod=test_config_from_file_debug>

    def test_config_from_file_debug(self):
        # Test both on existing and new repo (we've had a bug in the past that was unique to empty repos)
        repos = [self.tmp_git_repo, self.create_tmp_git_repo()]
        for target_repo in repos:
            commit_msg = "WIP: Thïs is a title thåt is a bit longer.\nContent on the second line\n" + \
                        "This line of the body is here because we need it"
            filename = self.create_simple_commit(commit_msg, git_repo=target_repo)
            config_path = self.get_sample_path("config/gitlintconfig")
            output = gitlint("--config", config_path, "--debug", _cwd=target_repo, _tty_in=True, _ok_code=[5])
    
            expected_kwargs = self.get_debug_vars_last_commit(git_repo=target_repo)
            expected_kwargs.update({'config_path': config_path, 'changed_files': [filename]})
>           self.assertEqualStdout(output, self.get_expected("test_config/test_config_from_file_debug_1",
                                                             expected_kwargs))

qa/test_config.py:69: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: "DEBU[2807 chars] ['main']\nChanged Files: ['test-fïle-a2bc7ce9[311 chars] 5\n" != "DEBU[2807 chars] ['master']\nChanged Files: ['test-fïle-a2bc7c[313 chars] 5\n"
E     DEBUG: gitlint.cli To report issues, please visit https://github.com/jorisroovers/gitlint/issues
E     DEBUG: gitlint.cli Platform: Linux-5.10.56-1-lts-x86_64-with-glibc2.33
E     DEBUG: gitlint.cli Python version: 3.8.10 (default, Jul  7 2021, 14:29:06) 
E     [GCC 11.1.0]
E     DEBUG: gitlint.git ('--version',)
E     DEBUG: gitlint.cli Git version: git version 2.32.0
E     DEBUG: gitlint.cli Gitlint version: 0.16.0dev
E     DEBUG: gitlint.cli GITLINT_USE_SH_LIB: [NOT SET]
E     DEBUG: gitlint.cli DEFAULT_ENCODING: UTF-8
E     DEBUG: gitlint.cli Configuration
E     config-path: /home/victor/dev/gitlint/qa/samples/config/gitlintconfig
E     [GENERAL]
E     extra-path: None
E     contrib: []
E     ignore: title-trailing-punctuation,B2
E     ignore-merge-commits: True
E     ignore-fixup-commits: True
E     ignore-squash-commits: True
E     ignore-revert-commits: True
E     ignore-stdin: False
E     staged: False
E     verbosity: 2
E     debug: True
E     target: /tmp/gitlint-test-20210816-152126-501806
E     [RULES]
E       I1: ignore-by-title
E          ignore=all
E          regex=None
E       I2: ignore-by-body
E          ignore=all
E          regex=None
E       I3: ignore-body-lines
E          regex=None
E       T1: title-max-length
E          line-length=20
E       T2: title-trailing-whitespace
E       T6: title-leading-whitespace
E       T3: title-trailing-punctuation
E       T4: title-hard-tab
E       T5: title-must-not-contain-word
E          words=WIP,thåt
E       T7: title-match-regex
E          regex=None
E       T8: title-min-length
E          min-length=5
E       B1: body-max-line-length
E          line-length=30
E       B5: body-min-length
E          min-length=20
E       B6: body-is-missing
E          ignore-merge-commits=True
E       B2: body-trailing-whitespace
E       B3: body-hard-tab
E       B4: body-first-line-empty
E       B7: body-changed-file-mention
E          files=
E       B8: body-match-regex
E          regex=None
E       M1: author-valid-email
E          regex=[^@ ]+@[^@ ]+\.[^@ ]+
E     
E     DEBUG: gitlint.cli No --msg-filename flag, no or empty data passed to stdin. Using the local repo.
E     DEBUG: gitlint.git ('log', '-1', '--pretty=%H')
E     DEBUG: gitlint.cli Linting 1 commit(s)
E     DEBUG: gitlint.git ('log', '5746815314ad9037a678ab0ac8c6daa4db8b7642', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B')
E     DEBUG: gitlint.git ('config', '--get', 'core.commentchar')
E     DEBUG: gitlint.lint Linting commit 5746815314ad9037a678ab0ac8c6daa4db8b7642
E     DEBUG: gitlint.git ('branch', '--contains', '5746815314ad9037a678ab0ac8c6daa4db8b7642')
E     DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', '5746815314ad9037a678ab0ac8c6daa4db8b7642')
E     DEBUG: gitlint.lint Commit Object
E     --- Commit Message ----
E     WIP: Thïs is a title thåt is a bit longer.
E     Content on the second line
E     This line of the body is here because we need it
E     
E     --- Meta info ---------
E     Author: gitlint-test-user <[email protected]>
E     Date:   2021-08-16 15:21:26 +1200
E     is-merge-commit:  False
E     is-fixup-commit:  False
E     is-squash-commit: False
E     is-revert-commit: False
E   - Branches: ['main']
E   ?               ^^
E   + Branches: ['master']
E   ?               ^^^^
E     Changed Files: ['test-fïle-a2bc7ce9-c4cf-4b4a-bafd-6dd379dabd0c']
E     -----------------------
E     1: T1 Title exceeds max length (42>20)
E     1: T5 Title contains the word 'WIP' (case-insensitive)
E     1: T5 Title contains the word 'thåt' (case-insensitive)
E     2: B4 Second line is not empty
E     3: B1 Line exceeds max length (48>30)
E     DEBUG: gitlint.cli Exit Code = 5
______________________________ IntegrationTests.test_successful_merge_commit _______________________________

self = <qa.test_gitlint.IntegrationTests testMethod=test_successful_merge_commit>

    def test_successful_merge_commit(self):
        # Create branch on master
        self.create_simple_commit("Cömmit on master\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)
        git("checkout", "test-branch", _cwd=self.tmp_git_repo)
        commit_title = "Commit on test-brånch with a pretty long title that will cause issues when merging"
        self.create_simple_commit(f"{commit_title}\n\nSïmple body")
        hash = self.get_last_commit_hash()
    
        # Checkout master 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)

qa/test_gitlint.py:43: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.8/site-packages/sh.py:1520: in __call__
    return RunningCommand(cmd, call_args, stdin, stdout, stderr)
.venv/lib/python3.8/site-packages/sh.py:784: in __init__
    self.wait()
.venv/lib/python3.8/site-packages/sh.py:841: in wait
    self.handle_command_exit_code(exit_code)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = , code = 1

    def handle_command_exit_code(self, code):
        """ here we determine if we had an exception, or an error code that we
        weren't expecting to see.  if we did, we create and raise an exception
        """
        ca = self.call_args
        exc_class = get_exc_exit_code_would_raise(code, ca["ok_code"], ca["piped"])
        if exc_class:
            exc = exc_class(self.ran, self.process.stdout, self.process.stderr, ca["truncate_exc"])
>           raise exc
E           sh.ErrorReturnCode_1: 
E           
E             RAN: /usr/bin/git checkout master
E           
E             STDOUT:
E           
E           
E             STDERR:
E           error: pathspec 'master' did not match any file(s) known to git

.venv/lib/python3.8/site-packages/sh.py:865: ErrorReturnCode_1
___________________________________ HookTests.test_commit_hook_continue ____________________________________

self = <qa.test_hooks.HookTests testMethod=test_commit_hook_continue>

    def test_commit_hook_continue(self):
        self.responses = ["y"]
        test_filename = self.create_simple_commit("WIP: This ïs a title.\nContënt on the second line",
                                                  out=self._interact, tty_in=True)
    
        # Determine short commit-msg hash, needed to determine expected output
        short_hash = self.get_last_commit_short_hash()
    
        expected_output = self._violations()
        expected_output += ["Continue with commit anyways (this keeps the current commit message)? " +
                            "[y(es)/n(no)/e(dit)] " +
                            "[master %s] WIP: This ïs a title. Contënt on the second line\n"
                            % short_hash,
                            " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
                            " create mode 100644 %s\n" % test_filename]
    
        assert len(self.githook_output) == len(expected_output)
        for output, expected in zip(self.githook_output, expected_output):
>           self.assertMultiLineEqual(
                output.replace('\r', ''),
                expected.replace('\r', ''))
E           AssertionError: 'Cont[85 chars]] [main ab98e73] WIP: This ïs a title. Contënt[17 chars]ne\n' != 'Cont[85 chars]] [master ab98e73] WIP: This ïs a title. Contë[19 chars]ne\n'
E           - Continue with commit anyways (this keeps the current commit message)? [y(es)/n(no)/e(dit)] [main ab98e73] WIP: This ïs a title. Contënt on the second line
E           ?                                                                                               ^^
E           + Continue with commit anyways (this keeps the current commit message)? [y(es)/n(no)/e(dit)] [master ab98e73] WIP: This ïs a title. Contënt on the second line
E           ?                                                                                               ^^^^

qa/test_hooks.py:86: AssertionError
_____________________________________ HookTests.test_commit_hook_edit ______________________________________

self = <qa.test_hooks.HookTests testMethod=test_commit_hook_edit>

    def test_commit_hook_edit(self):
        self.responses = ["e", "y"]
        env = {"EDITOR": ":"}
        test_filename = self.create_simple_commit("WIP: This ïs a title.\nContënt on the second line",
                                                  out=self._interact, env=env, tty_in=True)
        git("rm", "-f", test_filename, _cwd=self.tmp_git_repo)
    
        short_hash = git("rev-parse", "--short", "HEAD", _cwd=self.tmp_git_repo, _tty_in=True).replace("\n", "")
    
        # Determine short commit-msg hash, needed to determine expected output
    
        expected_output = self._violations()
        expected_output += ['Continue with commit anyways (this keeps the current commit message)? ' +
                            '[y(es)/n(no)/e(dit)] ' + self._violations()[0]]
        expected_output += self._violations()[1:]
        expected_output += ['Continue with commit anyways (this keeps the current commit message)? ' +
                            "[y(es)/n(no)/e(dit)] " +
                            "[master %s] WIP: This ïs a title. Contënt on the second line\n" % short_hash,
                            " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
                            " create mode 100644 %s\n" % test_filename]
    
        assert len(self.githook_output) == len(expected_output)
        for output, expected in zip(self.githook_output, expected_output):
>           self.assertMultiLineEqual(
                output.replace('\r', ''),
                expected.replace('\r', ''))
E           AssertionError: 'Cont[85 chars]] [main 7856dc2] WIP: This ïs a title. Contënt[17 chars]ne\n' != 'Cont[85 chars]] [master 7856dc2] WIP: This ïs a title. Contë[19 chars]ne\n'
E           - Continue with commit anyways (this keeps the current commit message)? [y(es)/n(no)/e(dit)] [main 7856dc2] WIP: This ïs a title. Contënt on the second line
E           ?                                                                                               ^^
E           + Continue with commit anyways (this keeps the current commit message)? [y(es)/n(no)/e(dit)] [master 7856dc2] WIP: This ïs a title. Contënt on the second line
E           ?                                                                                               ^^^^

qa/test_hooks.py:133: AssertionError
_________________________________ HookTests.test_commit_hook_no_violations _________________________________

self = <qa.test_hooks.HookTests testMethod=test_commit_hook_no_violations>

    def test_commit_hook_no_violations(self):
        test_filename = self.create_simple_commit("This ïs a title\n\nBody contënt that should work",
                                                  out=self._interact, tty_in=True)
    
        short_hash = self.get_last_commit_short_hash()
        expected_output = ["gitlint: checking commit message...\n",
                           "gitlint: \x1b[32mOK\x1b[0m (no violations in commit message)\n",
                           "[master %s] This ïs a title\n" % short_hash,
                           " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
                           " create mode 100644 %s\n" % test_filename]
>       self.assertListEqual(expected_output, self.githook_output)
E       AssertionError: Lists differ: ['git[102 chars] '[master c519325] This ïs a title\n', ' 1 fil[113 chars]b\n'] != ['git[102 chars] '[main c519325] This ïs a title\n', ' 1 file [111 chars]b\n']
E       
E       First differing element 2:
E       '[master c519325] This ïs a title\n'
E       '[main c519325] This ïs a title\n'
E       
E         ['gitlint: checking commit message...\n',
E          'gitlint: \x1b[32mOK\x1b[0m (no violations in commit message)\n',
E       -  '[master c519325] This ïs a title\n',
E       ?      ^^^^
E       
E       +  '[main c519325] This ïs a title\n',
E       ?      ^^
E       
E          ' 1 file changed, 0 insertions(+), 0 deletions(-)\n',
E          ' create mode 100644 test-fïle-39df76ac-49e5-49f6-b9b9-1522f75653fb\n']

qa/test_hooks.py:66: AssertionError
__________________________ UserDefinedRuleTests.test_user_defined_rules_examples1 __________________________

self = <qa.test_user_defined.UserDefinedRuleTests testMethod=test_user_defined_rules_examples1>

    def test_user_defined_rules_examples1(self):
        """ Test the user defined rules in the top-level `examples/` directory """
        extra_path = self.get_example_path()
        commit_msg = "WIP: Thi$ is å title\nContent on the second line"
        self.create_simple_commit(commit_msg)
        output = gitlint("--extra-path", extra_path, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[5])
>       self.assertEqualStdout(output, self.get_expected("test_user_defined/test_user_defined_rules_examples_1"))

qa/test_user_defined.py:16: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: '1: T[151 chars] \'main\' does not start with one of [\'featur[167 chars]e"\n' != '1: T[151 chars] \'master\' does not start with one of [\'feat[169 chars]e"\n'
E     1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: Thi$ is å title"
E     1: UC2 Body does not contain a 'Signed-off-by' line
E   - 1: UC3 Branch name 'main' does not start with one of ['feature/', 'hotfix/', 'release/']
E   ?                       ^^
E   + 1: UC3 Branch name 'master' does not start with one of ['feature/', 'hotfix/', 'release/']
E   ?                       ^^^^
E     1: UL1 Title contains the special character '$': "WIP: Thi$ is å title"
E     2: B4 Second line is not empty: "Content on the second line"
__________________________ UserDefinedRuleTests.test_user_defined_rules_examples2 __________________________

self = <qa.test_user_defined.UserDefinedRuleTests testMethod=test_user_defined_rules_examples2>

    def test_user_defined_rules_examples2(self):
        """ Test the user defined rules in the top-level `examples/` directory """
        extra_path = self.get_example_path()
        commit_msg = "Release: Thi$ is å title\nContent on the second line\n$This line is ignored \nThis isn't\t\n"
        self.create_simple_commit(commit_msg)
        output = gitlint("--extra-path", extra_path, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[4])
>       self.assertEqualStdout(output, self.get_expected("test_user_defined/test_user_defined_rules_examples_2"))

qa/test_user_defined.py:24: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: "1: U[66 chars]e 'main' does not start with one of ['feature/[104 chars]ty\n" != "1: U[66 chars]e 'master' does not start with one of ['featur[106 chars]ty\n"
E     1: UC2 Body does not contain a 'Signed-off-by' line
E   - 1: UC3 Branch name 'main' does not start with one of ['feature/', 'hotfix/', 'release/']
E   ?                       ^^
E   + 1: UC3 Branch name 'master' does not start with one of ['feature/', 'hotfix/', 'release/']
E   ?                       ^^^^
E     1: UL1 Title contains the special character '$'
E     2: B4 Second line is not empty
____________________ UserDefinedRuleTests.test_user_defined_rules_examples_with_config _____________________

self = <qa.test_user_defined.UserDefinedRuleTests testMethod=test_user_defined_rules_examples_with_config>

    def test_user_defined_rules_examples_with_config(self):
        """ Test the user defined rules in the top-level `examples/` directory """
        extra_path = self.get_example_path()
        commit_msg = "WIP: Thi$ is å title\nContent on the second line"
        self.create_simple_commit(commit_msg)
        output = gitlint("--extra-path", extra_path, "-c", "body-max-line-count.max-line-count=1",
                         _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[6])
        expected_path = "test_user_defined/test_user_defined_rules_examples_with_config_1"
>       self.assertEqualStdout(output, self.get_expected(expected_path))

qa/test_user_defined.py:34: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: '1: T[196 chars] \'main\' does not start with one of [\'featur[167 chars]e"\n' != '1: T[196 chars] \'master\' does not start with one of [\'feat[169 chars]e"\n'
E     1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: Thi$ is å title"
E     1: UC1 Body contains too many lines (2 > 1)
E     1: UC2 Body does not contain a 'Signed-off-by' line
E   - 1: UC3 Branch name 'main' does not start with one of ['feature/', 'hotfix/', 'release/']
E   ?                       ^^
E   + 1: UC3 Branch name 'master' does not start with one of ['feature/', 'hotfix/', 'release/']
E   ?                       ^^^^
E     1: UL1 Title contains the special character '$': "WIP: Thi$ is å title"
E     2: B4 Second line is not empty: "Content on the second line"
____________________________ UserDefinedRuleTests.test_user_defined_rules_extra ____________________________

self = <qa.test_user_defined.UserDefinedRuleTests testMethod=test_user_defined_rules_extra>

    def test_user_defined_rules_extra(self):
        extra_path = self.get_sample_path("user_rules/extra")
        commit_msg = "WIP: Thi$ is å title\nContent on the second line"
        self.create_simple_commit(commit_msg)
        output = gitlint("--extra-path", extra_path, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[9])
>       self.assertEqualStdout(output, self.get_expected("test_user_defined/test_user_defined_rules_extra_1",
                                                         {'repo-path': self.tmp_git_repo}))

qa/test_user_defined.py:41: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qa/base.py:56: in assertEqualStdout
    self.assertMultiLineEqual(output, expected)
E   AssertionError: '1: T[109 chars]h: main\n1: UC1 GitContext.commentchar: #\n1: [237 chars] "\n' != '1: T[109 chars]h: master\n1: UC1 GitContext.commentchar: #\n1[241 chars] "\n'
E     1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: Thi$ is å title"
E   - 1: UC1 GitContext.current_branch: main
E   ?                                     ^^
E   + 1: UC1 GitContext.current_branch: master
E   ?                                     ^^^^
E     1: UC1 GitContext.commentchar: #
E   - 1: UC2 GitCommit.branches: ['main']
E   ?                                ^^
E   + 1: UC2 GitCommit.branches: ['master']
E   ?                                ^^^^
E     1: UC2 GitCommit.custom_prop: foöbar
E     1: UC4 int-öption: 2
E     1: UC4 str-öption: föo
E     1: UC4 list-öption: ['foo', 'bar']
E     4: B2 Line has trailing whitespace: "/tmp/gitlint-test-20210816-152134-251584 "
========================================= short test summary info ==========================================
FAILED qa/test_commits.py::CommitsTests::test_lint_staged_msg_filename - AssertionError: 'DEBU[2481 chars...
FAILED qa/test_commits.py::CommitsTests::test_lint_staged_stdin - AssertionError: 'DEBU[2556 chars][\'mai...
FAILED qa/test_config.py::ConfigTests::test_config_from_env - AssertionError: "DEBU[2925 chars] ['main']\...
FAILED qa/test_config.py::ConfigTests::test_config_from_file_debug - AssertionError: "DEBU[2807 chars] ['...
FAILED qa/test_gitlint.py::IntegrationTests::test_successful_merge_commit - sh.ErrorReturnCode_1: 
FAILED qa/test_hooks.py::HookTests::test_commit_hook_continue - AssertionError: 'Cont[85 chars]] [main ab...
FAILED qa/test_hooks.py::HookTests::test_commit_hook_edit - AssertionError: 'Cont[85 chars]] [main 7856dc...
FAILED qa/test_hooks.py::HookTests::test_commit_hook_no_violations - AssertionError: Lists differ: ['git[...
FAILED qa/test_user_defined.py::UserDefinedRuleTests::test_user_defined_rules_examples1 - AssertionError:...
FAILED qa/test_user_defined.py::UserDefinedRuleTests::test_user_defined_rules_examples2 - AssertionError:...
FAILED qa/test_user_defined.py::UserDefinedRuleTests::test_user_defined_rules_examples_with_config - Asse...
FAILED qa/test_user_defined.py::UserDefinedRuleTests::test_user_defined_rules_extra - AssertionError: '1:...
====================================== 12 failed, 32 passed in 10.05s ======================================
# BUILD TEST (Python 3.8.10, /home/victor/dev/gitlint/.venv/bin/python) #
Cleaning the *.pyc, site/, build/, dist/ and all __pycache__ directories...DONE
Copying gitlint to /tmp/gitlint-build-test-2021-08-16-15-21-35...DONE
Writing new version to file...DONE
Building package ...
/tmp/gitlint-build-test-2021-08-16-15-21-35 ~/dev/gitlint
/home/victor/dev/gitlint/.venv/lib/python3.8/site-packages/setuptools/dist.py:477: UserWarning: The version specified ('0.16.0dev-2021-08-16-15-21-35') is an invalid version, this may not work as expected with newer versions of setuptools, pip, and PyPI. Please see PEP 440 for more details.
  warnings.warn(
running sdist
running egg_info
writing gitlint.egg-info/PKG-INFO
writing dependency_links to gitlint.egg-info/dependency_links.txt
writing entry points to gitlint.egg-info/entry_points.txt
writing requirements to gitlint.egg-info/requires.txt
writing top-level names to gitlint.egg-info/top_level.txt
adding license file 'LICENSE' (matched pattern 'LICEN[CS]E*')
reading manifest file 'gitlint.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files found matching 'Vagrantfile'
warning: no previously-included files found matching '*.yml'
warning: no previously-included files found matching '*.sh'
warning: no previously-included files found matching '*.txt'
warning: no previously-included files matching '*' found under directory 'examples'
writing manifest file 'gitlint.egg-info/SOURCES.txt'
running check
warning: check: missing meta-data: if 'author' supplied, 'author_email' must be supplied too

creating gitlint-0.16.0dev-2021-08-16-15-21-35
creating gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
creating gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
creating gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/contrib
creating gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/contrib/rules
creating gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/files
copying files to gitlint-0.16.0dev-2021-08-16-15-21-35...
copying LICENSE -> gitlint-0.16.0dev-2021-08-16-15-21-35
copying MANIFEST.in -> gitlint-0.16.0dev-2021-08-16-15-21-35
copying README.md -> gitlint-0.16.0dev-2021-08-16-15-21-35
copying setup.cfg -> gitlint-0.16.0dev-2021-08-16-15-21-35
copying setup.py -> gitlint-0.16.0dev-2021-08-16-15-21-35
copying gitlint/__init__.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/cache.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/cli.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/config.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/display.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/exception.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/git.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/hooks.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/lint.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/options.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/rule_finder.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/rules.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/shell.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint/utils.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint
copying gitlint.egg-info/PKG-INFO -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
copying gitlint.egg-info/SOURCES.txt -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
copying gitlint.egg-info/dependency_links.txt -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
copying gitlint.egg-info/entry_points.txt -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
copying gitlint.egg-info/requires.txt -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
copying gitlint.egg-info/top_level.txt -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint.egg-info
copying gitlint/contrib/__init__.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/contrib
copying gitlint/contrib/rules/__init__.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/contrib/rules
copying gitlint/contrib/rules/conventional_commit.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/contrib/rules
copying gitlint/contrib/rules/signedoff_by.py -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/contrib/rules
copying gitlint/files/commit-msg -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/files
copying gitlint/files/gitlint -> gitlint-0.16.0dev-2021-08-16-15-21-35/gitlint/files
Writing gitlint-0.16.0dev-2021-08-16-15-21-35/setup.cfg
creating dist
Creating tar archive
removing 'gitlint-0.16.0dev-2021-08-16-15-21-35' (and everything under it)
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/qa
copying qa/utils.py -> build/lib/qa
copying qa/test_user_defined.py -> build/lib/qa
copying qa/test_stdin.py -> build/lib/qa
copying qa/test_named_rules.py -> build/lib/qa
copying qa/test_hooks.py -> build/lib/qa
copying qa/test_gitlint.py -> build/lib/qa
copying qa/test_contrib.py -> build/lib/qa
copying qa/test_config.py -> build/lib/qa
copying qa/test_commits.py -> build/lib/qa
copying qa/shell.py -> build/lib/qa
copying qa/base.py -> build/lib/qa
copying qa/__init__.py -> build/lib/qa
creating build/lib/gitlint
copying gitlint/utils.py -> build/lib/gitlint
copying gitlint/shell.py -> build/lib/gitlint
copying gitlint/rules.py -> build/lib/gitlint
copying gitlint/rule_finder.py -> build/lib/gitlint
copying gitlint/options.py -> build/lib/gitlint
copying gitlint/lint.py -> build/lib/gitlint
copying gitlint/hooks.py -> build/lib/gitlint
copying gitlint/git.py -> build/lib/gitlint
copying gitlint/exception.py -> build/lib/gitlint
copying gitlint/display.py -> build/lib/gitlint
copying gitlint/config.py -> build/lib/gitlint
copying gitlint/cli.py -> build/lib/gitlint
copying gitlint/cache.py -> build/lib/gitlint
copying gitlint/__init__.py -> build/lib/gitlint
creating build/lib/gitlint/tests
copying gitlint/tests/test_utils.py -> build/lib/gitlint/tests
copying gitlint/tests/test_options.py -> build/lib/gitlint/tests
copying gitlint/tests/test_lint.py -> build/lib/gitlint/tests
copying gitlint/tests/test_hooks.py -> build/lib/gitlint/tests
copying gitlint/tests/test_display.py -> build/lib/gitlint/tests
copying gitlint/tests/test_cache.py -> build/lib/gitlint/tests
copying gitlint/tests/base.py -> build/lib/gitlint/tests
copying gitlint/tests/__init__.py -> build/lib/gitlint/tests
creating build/lib/gitlint/contrib
copying gitlint/contrib/__init__.py -> build/lib/gitlint/contrib
creating build/lib/gitlint/tests/rules
copying gitlint/tests/rules/test_user_rules.py -> build/lib/gitlint/tests/rules
copying gitlint/tests/rules/test_title_rules.py -> build/lib/gitlint/tests/rules
copying gitlint/tests/rules/test_rules.py -> build/lib/gitlint/tests/rules
copying gitlint/tests/rules/test_meta_rules.py -> build/lib/gitlint/tests/rules
copying gitlint/tests/rules/test_configuration_rules.py -> build/lib/gitlint/tests/rules
copying gitlint/tests/rules/test_body_rules.py -> build/lib/gitlint/tests/rules
copying gitlint/tests/rules/__init__.py -> build/lib/gitlint/tests/rules
creating build/lib/gitlint/tests/contrib
copying gitlint/tests/contrib/test_contrib_rules.py -> build/lib/gitlint/tests/contrib
copying gitlint/tests/contrib/__init__.py -> build/lib/gitlint/tests/contrib
creating build/lib/gitlint/tests/contrib/rules
copying gitlint/tests/contrib/rules/test_signedoff_by.py -> build/lib/gitlint/tests/contrib/rules
copying gitlint/tests/contrib/rules/test_conventional_commit.py -> build/lib/gitlint/tests/contrib/rules
copying gitlint/tests/contrib/rules/__init__.py -> build/lib/gitlint/tests/contrib/rules
creating build/lib/gitlint/contrib/rules
copying gitlint/contrib/rules/signedoff_by.py -> build/lib/gitlint/contrib/rules
copying gitlint/contrib/rules/conventional_commit.py -> build/lib/gitlint/contrib/rules
copying gitlint/contrib/rules/__init__.py -> build/lib/gitlint/contrib/rules
creating build/lib/gitlint/files
copying gitlint/files/gitlint -> build/lib/gitlint/files
copying gitlint/files/commit-msg -> build/lib/gitlint/files
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/gitlint
creating build/bdist.linux-x86_64/wheel/gitlint/files
copying build/lib/gitlint/files/commit-msg -> build/bdist.linux-x86_64/wheel/gitlint/files
copying build/lib/gitlint/files/gitlint -> build/bdist.linux-x86_64/wheel/gitlint/files
creating build/bdist.linux-x86_64/wheel/gitlint/contrib
creating build/bdist.linux-x86_64/wheel/gitlint/contrib/rules
copying build/lib/gitlint/contrib/rules/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint/contrib/rules
copying build/lib/gitlint/contrib/rules/conventional_commit.py -> build/bdist.linux-x86_64/wheel/gitlint/contrib/rules
copying build/lib/gitlint/contrib/rules/signedoff_by.py -> build/bdist.linux-x86_64/wheel/gitlint/contrib/rules
copying build/lib/gitlint/contrib/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint/contrib
creating build/bdist.linux-x86_64/wheel/gitlint/tests
creating build/bdist.linux-x86_64/wheel/gitlint/tests/contrib
creating build/bdist.linux-x86_64/wheel/gitlint/tests/contrib/rules
copying build/lib/gitlint/tests/contrib/rules/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/contrib/rules
copying build/lib/gitlint/tests/contrib/rules/test_conventional_commit.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/contrib/rules
copying build/lib/gitlint/tests/contrib/rules/test_signedoff_by.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/contrib/rules
copying build/lib/gitlint/tests/contrib/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/contrib
copying build/lib/gitlint/tests/contrib/test_contrib_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/contrib
creating build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/test_body_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/test_configuration_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/test_meta_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/test_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/test_title_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/rules/test_user_rules.py -> build/bdist.linux-x86_64/wheel/gitlint/tests/rules
copying build/lib/gitlint/tests/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/base.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/test_cache.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/test_display.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/test_hooks.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/test_lint.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/test_options.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/tests/test_utils.py -> build/bdist.linux-x86_64/wheel/gitlint/tests
copying build/lib/gitlint/__init__.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/cache.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/cli.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/config.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/display.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/exception.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/git.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/hooks.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/lint.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/options.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/rule_finder.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/rules.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/shell.py -> build/bdist.linux-x86_64/wheel/gitlint
copying build/lib/gitlint/utils.py -> build/bdist.linux-x86_64/wheel/gitlint
creating build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/__init__.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/base.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/shell.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_commits.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_config.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_contrib.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_gitlint.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_hooks.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_named_rules.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_stdin.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/test_user_defined.py -> build/bdist.linux-x86_64/wheel/qa
copying build/lib/qa/utils.py -> build/bdist.linux-x86_64/wheel/qa
running install_egg_info
Copying gitlint.egg-info to build/bdist.linux-x86_64/wheel/gitlint-0.16.0dev_2021_08_16_15_21_35-py3.8.egg-info
running install_scripts
adding license file "LICENSE" (matched pattern "LICEN[CS]E*")
creating build/bdist.linux-x86_64/wheel/gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/WHEEL
creating 'dist/gitlint-0.16.0dev_2021_08_16_15_21_35-py2.py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'gitlint/__init__.py'
adding 'gitlint/cache.py'
adding 'gitlint/cli.py'
adding 'gitlint/config.py'
adding 'gitlint/display.py'
adding 'gitlint/exception.py'
adding 'gitlint/git.py'
adding 'gitlint/hooks.py'
adding 'gitlint/lint.py'
adding 'gitlint/options.py'
adding 'gitlint/rule_finder.py'
adding 'gitlint/rules.py'
adding 'gitlint/shell.py'
adding 'gitlint/utils.py'
adding 'gitlint/contrib/__init__.py'
adding 'gitlint/contrib/rules/__init__.py'
adding 'gitlint/contrib/rules/conventional_commit.py'
adding 'gitlint/contrib/rules/signedoff_by.py'
adding 'gitlint/files/commit-msg'
adding 'gitlint/files/gitlint'
adding 'gitlint/tests/__init__.py'
adding 'gitlint/tests/base.py'
adding 'gitlint/tests/test_cache.py'
adding 'gitlint/tests/test_display.py'
adding 'gitlint/tests/test_hooks.py'
adding 'gitlint/tests/test_lint.py'
adding 'gitlint/tests/test_options.py'
adding 'gitlint/tests/test_utils.py'
adding 'gitlint/tests/contrib/__init__.py'
adding 'gitlint/tests/contrib/test_contrib_rules.py'
adding 'gitlint/tests/contrib/rules/__init__.py'
adding 'gitlint/tests/contrib/rules/test_conventional_commit.py'
adding 'gitlint/tests/contrib/rules/test_signedoff_by.py'
adding 'gitlint/tests/rules/__init__.py'
adding 'gitlint/tests/rules/test_body_rules.py'
adding 'gitlint/tests/rules/test_configuration_rules.py'
adding 'gitlint/tests/rules/test_meta_rules.py'
adding 'gitlint/tests/rules/test_rules.py'
adding 'gitlint/tests/rules/test_title_rules.py'
adding 'gitlint/tests/rules/test_user_rules.py'
adding 'qa/__init__.py'
adding 'qa/base.py'
adding 'qa/shell.py'
adding 'qa/test_commits.py'
adding 'qa/test_config.py'
adding 'qa/test_contrib.py'
adding 'qa/test_gitlint.py'
adding 'qa/test_hooks.py'
adding 'qa/test_named_rules.py'
adding 'qa/test_stdin.py'
adding 'qa/test_user_defined.py'
adding 'qa/utils.py'
adding 'gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/LICENSE'
adding 'gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/METADATA'
adding 'gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/WHEEL'
adding 'gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/entry_points.txt'
adding 'gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/top_level.txt'
adding 'gitlint-0.16.0dev_2021_08_16_15_21_35.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
~/dev/gitlint
Building package...SUCCESS
# STYLE CHECKS (Python 3.8.10, /home/victor/dev/gitlint/.venv/bin/python) #
Running flake8...SUCCESS

Running pylint...SUCCESS


--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

Running gitlint...SUCCESS


### OVERALL STATUS: FAILURE ###

@sigmavirus24 sigmavirus24 self-assigned this Sep 17, 2021
@jorisroovers jorisroovers added the development Issues that are not user-facing but related to gitlint development label Oct 11, 2021
@jorisroovers jorisroovers added this to the 0.20.0 milestone Mar 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
development Issues that are not user-facing but related to gitlint development
Projects
Status: Todo
Development

No branches or pull requests

3 participants