Example #1
0
    def test_commit_hook_worktree(self):
        """ Tests that hook installation and un-installation also work in git worktrees.
        Test steps:
            ```sh
            git init <tmpdir>
            cd <tmpdir>
            git worktree add <worktree-tempdir>
            cd <worktree-tempdir>
            gitlint install-hook
            gitlint uninstall-hook
            ```
        """
        tmp_git_repo = self.create_tmp_git_repo()
        self.create_simple_commit("Simple title\n\nContënt in the body",
                                  git_repo=tmp_git_repo)

        worktree_dir = self.generate_temp_path()
        self.tmp_git_repos.append(
            worktree_dir)  # make sure we clean up the worktree afterwards

        git("worktree", "add", worktree_dir, _cwd=tmp_git_repo, _tty_in=True)

        output_installed = gitlint("install-hook", _cwd=worktree_dir)
        expected_hook_path = os.path.join(tmp_git_repo, ".git", "hooks",
                                          "commit-msg")
        expected_msg = f"Successfully installed gitlint commit-msg hook in {expected_hook_path}\r\n"
        self.assertEqual(output_installed, expected_msg)

        output_uninstalled = gitlint("uninstall-hook", _cwd=worktree_dir)
        expected_hook_path = os.path.join(tmp_git_repo, ".git", "hooks",
                                          "commit-msg")
        expected_msg = f"Successfully uninstalled gitlint commit-msg hook from {expected_hook_path}\r\n"
        self.assertEqual(output_uninstalled, expected_msg)
Example #2
0
    def test_verbosity(self):
        self._create_simple_commit(
            u"WIP: Thïs is a title.\nContënt on the second line")
        output = gitlint("-v",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _ok_code=[3])

        expected = u"1: T3\n1: T5\n2: B4\n"
        self.assertEqualStdout(output, expected)

        output = gitlint("-vv",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _ok_code=[3])
        self.assertEqualStdout(
            output, self.get_expected("test_config/test_verbosity_1"))

        output = gitlint("-vvv",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _ok_code=[3])
        self.assertEqualStdout(
            output, self.get_expected("test_config/test_verbosity_2"))

        # test silent mode
        output = gitlint("--silent",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _ok_code=[3])
        self.assertEqualStdout(output, "")
Example #3
0
 def get_system_info_dict():
     """ Returns a dict with items related to system values logged by `gitlint --debug` """
     expected_gitlint_version = gitlint("--version").replace("gitlint, version ", "").strip()
     expected_git_version = git("--version").strip()
     return {'platform': platform.platform(), 'python_version': sys.version,
             'git_version': expected_git_version, 'gitlint_version': expected_gitlint_version,
             'GITLINT_USE_SH_LIB': BaseTestCase.GITLINT_USE_SH_LIB, 'DEFAULT_ENCODING': DEFAULT_ENCODING}
Example #4
0
    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(u"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(u"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': sstr(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))
        self.assertEqual(output.exit_code, 3)
Example #5
0
    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))
Example #6
0
 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}))
Example #7
0
 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"))
Example #8
0
 def test_msg_filename(self):
     tmp_commit_msg_file = self.create_tmpfile(u"WIP: msg-fïlename test.")
     output = gitlint("--msg-filename",
                      tmp_commit_msg_file,
                      _tty_in=True,
                      _ok_code=[3])
     self.assertEqualStdout(
         output, self.get_expected("test_gitlint/test_msg_filename_1"))
Example #9
0
 def test_successful(self):
     # Test for STDIN with and without a TTY attached
     self.create_simple_commit(
         u"Sïmple title\n\nSimple bödy describing the commit")
     output = gitlint(_cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _err_to_out=True)
     self.assertEqualStdout(output, "")
Example #10
0
 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))
Example #11
0
 def test_set_rule_option(self):
     self._create_simple_commit(u"This ïs a title.")
     output = gitlint("-c",
                      "title-max-length.line-length=5",
                      _tty_in=True,
                      _cwd=self.tmp_git_repo,
                      _ok_code=[3])
     self.assertEqualStdout(
         output, self.get_expected("test_config/test_set_rule_option_1"))
Example #12
0
    def test_git_errors(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])

        expected = u"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(u"WIP: Pïpe test."),
                         "--staged",
                         _cwd=empty_git_repo,
                         _tty_in=False,
                         _err_to_out=True,
                         _ok_code=[self.GIT_CONTEXT_ERROR_CODE])
        self.assertEqualStdout(output, expected)
Example #13
0
    def test_revert_commit(self):
        self.create_simple_commit(u"WIP: Cömmit on master.\n\nSimple bödy")
        hash = self.get_last_commit_hash()
        git("revert", hash, _cwd=self.tmp_git_repo)

        # Run gitlint and assert output is empty
        output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True)
        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])
        self.assertEqual(output.exit_code, 1)
        expected = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"Revert \"WIP: Cömmit on master.\"\"\n"
        self.assertEqualStdout(output, expected)
Example #14
0
 def test_invalid_contrib_rules(self):
     self._create_simple_commit("WIP: test")
     output = gitlint("--contrib",
                      u"föobar,CC1",
                      _cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _ok_code=[255])
     self.assertEqualStdout(
         output,
         u"Config Error: No contrib rule with id or name 'föobar' found.\n")
Example #15
0
 def test_ignore_by_name(self):
     self._create_simple_commit(
         u"WIP: Thïs is a title.\nContënt on the second line")
     output = gitlint("--ignore",
                      "title-must-not-contain-word,body-first-line-empty",
                      _cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _ok_code=[1])
     expected = u"1: T3 Title has trailing punctuation (.): \"WIP: Thïs is a title.\"\n"
     self.assertEqualStdout(output, expected)
Example #16
0
 def test_successful(self):
     """ Test linting multiple commits without violations """
     git("checkout", "-b", "test-branch-commits-base", _cwd=self.tmp_git_repo)
     self.create_simple_commit(u"Sïmple title\n\nSimple bödy describing the commit")
     git("checkout", "-b", "test-branch-commits", _cwd=self.tmp_git_repo)
     self.create_simple_commit(u"Sïmple title2\n\nSimple bödy describing the commit2")
     self.create_simple_commit(u"Sïmple title3\n\nSimple bödy describing the commit3")
     output = gitlint("--commits", "test-branch-commits-base...test-branch-commits",
                      _cwd=self.tmp_git_repo, _tty_in=True)
     self.assertEqualStdout(output, "")
Example #17
0
 def test_ignore_by_id(self):
     self._create_simple_commit(
         u"WIP: Thïs is a title.\nContënt on the second line")
     output = gitlint("--ignore",
                      "T5,B4",
                      _tty_in=True,
                      _cwd=self.tmp_git_repo,
                      _ok_code=[1])
     expected = u"1: T3 Title has trailing punctuation (.): \"WIP: Thïs is a title.\"\n"
     self.assertEqualStdout(output, expected)
Example #18
0
    def setUp(self):
        self.responses = []
        self.response_index = 0
        self.githook_output = []

        # install git commit-msg hook and assert output
        output_installed = gitlint("install-hook", _cwd=self.tmp_git_repo)
        expected_installed = u"Successfully installed gitlint commit-msg hook in %s/.git/hooks/commit-msg\n" % \
                             self.tmp_git_repo
        self.assertEqualStdout(output_installed, expected_installed)
Example #19
0
    def test_squash_commit(self):
        # Create a normal commit and assert that it has a violation
        test_filename = self.create_simple_commit(
            u"Cömmit on WIP master\n\nSimple bödy that is long enough")
        output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1])
        expected = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\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:
            # 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(u"Appending some stuff\n")

        git("add", test_filename, _cwd=self.tmp_git_repo)

        git("commit",
            "--squash",
            self.get_last_commit_hash(),
            "-m",
            u"Töo short body",
            _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-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 = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"squash! Cömmit on WIP master\"\n" + \
            u"3: B5 Body message is too short (14<20): \"Töo short body\"\n"

        self.assertEqualStdout(output, expected)
Example #20
0
 def test_lint_single_commit(self):
     self._create_simple_commit(u"Sïmple title.\n")
     self._create_simple_commit(u"Sïmple title2.\n")
     commit_sha = self.get_last_commit_hash()
     refspec = "{0}^...{0}".format(commit_sha)
     self._create_simple_commit(u"Sïmple title3.\n")
     output = gitlint("--commits", refspec, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2])
     expected = (u"1: T3 Title has trailing punctuation (.): \"Sïmple title2.\"\n" +
                 u"3: B6 Body message is missing\n")
     self.assertEqual(output.exit_code, 2)
     self.assertEqualStdout(output, expected)
Example #21
0
 def test_named_rule(self):
     commit_msg = "WIP: thåt dûr bår\n\nSïmple commit body"
     self.create_simple_commit(commit_msg)
     config_path = self.get_sample_path("config/named-rules")
     output = gitlint("--config",
                      config_path,
                      _cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _ok_code=[5])
     self.assertEqualStdout(
         output, self.get_expected("test_named_rules/test_named_rule_1"))
Example #22
0
 def test_contrib_rules(self):
     self._create_simple_commit(
         u"WIP Thi$ is å title\n\nMy bödy that is a bit longer than 20 chars"
     )
     output = gitlint("--contrib",
                      "contrib-title-conventional-commits,CC1",
                      _cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _ok_code=[4])
     self.assertEqualStdout(
         output, self.get_expected("test_contrib/test_contrib_rules_1"))
Example #23
0
 def test_lint_single_commit(self):
     """ Tests `gitlint --commits <sha>` """
     self.create_simple_commit("Sïmple title.\n")
     self.create_simple_commit("Sïmple title2.\n")
     commit_sha = self.get_last_commit_hash()
     refspec = f"{commit_sha}^...{commit_sha}"
     self.create_simple_commit("Sïmple title3.\n")
     output = gitlint("--commits", refspec, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2])
     expected = ("1: T3 Title has trailing punctuation (.): \"Sïmple title2.\"\n" +
                 "3: B6 Body message is missing\n")
     self.assertEqual(output.exit_code, 2)
     self.assertEqualStdout(output, expected)
Example #24
0
 def test_invalid_user_defined_rules(self):
     extra_path = self.get_sample_path("user_rules/incorrect_linerule")
     self.create_simple_commit("WIP: test")
     output = gitlint("--extra-path",
                      extra_path,
                      _cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _ok_code=[255])
     self.assertEqualStdout(
         output,
         "Config Error: User-defined rule class 'MyUserLineRule' must have a 'validate' method\n"
     )
Example #25
0
 def test_user_defined_rules(self):
     extra_path = self.get_example_path()
     commit_msg = u"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=[4])
     self.assertEqualStdout(
         output,
         self.get_expected("test_user_defined/test_user_defined_rules_1"))
Example #26
0
 def test_config_from_file(self):
     commit_msg = u"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"
     self._create_simple_commit(commit_msg)
     config_path = self.get_sample_path("config/gitlintconfig")
     output = gitlint("--config",
                      config_path,
                      _cwd=self.tmp_git_repo,
                      _tty_in=True,
                      _ok_code=[5])
     self.assertEqualStdout(
         output, self.get_expected("test_config/test_config_from_file_1"))
Example #27
0
 def test_no_git_email_set(self):
     """ 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)
     expected = "Missing git configuration: please set user.email\n"
     self.assertEqualStdout(output, expected)
Example #28
0
    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. """

        # 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)
        self.create_simple_commit(
            u"Sïmple title\n\nSimple bödy describing the commit\n$after commentchar\t ignored"
        )
        output = gitlint(_cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _err_to_out=True)
        self.assertEqualStdout(output, "")
Example #29
0
    def test_lint_head(self):
        """ Testing whether we can also recognize special refs like 'HEAD' """
        tmp_git_repo = self.create_tmp_git_repo()
        self.create_simple_commit(u"Sïmple title.\n\nSimple bödy describing the commit", git_repo=tmp_git_repo)
        self.create_simple_commit(u"Sïmple title", git_repo=tmp_git_repo)
        self.create_simple_commit(u"WIP: Sïmple title\n\nSimple bödy describing the commit", git_repo=tmp_git_repo)
        output = gitlint("--commits", "HEAD", _cwd=tmp_git_repo, _tty_in=True, _ok_code=[3])
        revlist = git("rev-list", "HEAD", _tty_in=True, _cwd=tmp_git_repo).split()

        expected_kwargs = {"commit_sha0": revlist[0][:10], "commit_sha1": revlist[1][:10],
                           "commit_sha2": revlist[2][:10]}

        self.assertEqualStdout(output, self.get_expected("test_commits/test_lint_head_1", expected_kwargs))
Example #30
0
    def test_config_from_file_debug(self):
        commit_msg = u"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"
        self._create_simple_commit(commit_msg)
        commit_sha = self.get_last_commit_hash()
        config_path = self.get_sample_path("config/gitlintconfig")
        output = gitlint("--config",
                         config_path,
                         "--debug",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _ok_code=[5])

        expected_date = git("log",
                            "-1",
                            "--pretty=%ai",
                            _cwd=self.tmp_git_repo)
        expected_date = arrow.get(str(expected_date),
                                  "YYYY-MM-DD HH:mm:ss Z").datetime
        expected_gitlint_version = gitlint("--version").replace(
            "gitlint, version ", "").replace("\n", "")
        expected_git_version = git("--version").replace("\n", "")

        expected_kwargs = {
            'platform': platform.platform(),
            'python_version': sys.version,
            'git_version': expected_git_version,
            'gitlint_version': expected_gitlint_version,
            'GITLINT_USE_SH_LIB': self.GITLINT_USE_SH_LIB,
            'config_path': config_path,
            'target': self.tmp_git_repo,
            'commit_sha': commit_sha,
            'commit_date': expected_date
        }
        self.assertEqualStdout(
            output,
            self.get_expected("test_config/test_config_from_file_debug_1",
                              expected_kwargs))