def test_gitcontext_ignore_specific(self):
     # ignore specific rules
     config = LintConfig()
     context = self.gitcontext("test\ngitlint-ignore: T1, body-hard-tab")
     config.apply_config_from_commit(context.commits[-1])
     expected_rules = [rule for rule in config.rules if rule.id not in ["T1", "body-hard-tab"]]
     self.assertEqual(config.rules, expected_rules)
Beispiel #2
0
    def test_uninstall_commit_msg_hook_negative(self, isdir, path_exists, remove):
        lint_config = LintConfig()
        lint_config.target = self.SAMPLES_DIR
        # mock that the current directory is not a git repo
        isdir.return_value = False
        expected_msg = "{0} is not a git repository".format(self.SAMPLES_DIR)
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)
            isdir.assert_called_with(os.path.join(self.SAMPLES_DIR, '.git/hooks'))
            path_exists.assert_not_called()
            remove.assert_not_called()

        # mock that there is no commit hook present
        isdir.return_value = True
        path_exists.return_value = False
        expected_dst = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH)
        expected_msg = "There is no commit-msg hook present in {0}.".format(expected_dst)
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)
            isdir.assert_called_with(os.path.join(self.SAMPLES_DIR, '.git/hooks'))
            path_exists.assert_called_once_with(expected_dst)
            remove.assert_not_called()

        # mock that there is a different (=not gitlint) commit hook
        isdir.return_value = True
        path_exists.return_value = True
        read_data = "#!/bin/sh\nfoo"
        expected_dst = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH)
        expected_msg = "The commit-msg hook in {0} was not installed by gitlint ".format(expected_dst) + \
                       r"\(or it was modified\).\nUninstallation of 3th party or modified gitlint hooks " + \
                       "is not supported."
        with patch('gitlint.hooks.open', mock_open(read_data=read_data), create=True):
            with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
                GitHookInstaller.uninstall_commit_msg_hook(lint_config)
            remove.assert_not_called()
Beispiel #3
0
    def test_load_config_from_file_negative(self):
        # bad config file load
        foo_path = self.get_sample_path("foo")
        with self.assertRaisesRegexp(LintConfigError, "Invalid file path: {0}".format(foo_path)):
            LintConfig.load_from_file(foo_path)

        # error during file parsing
        path = self.get_sample_path("config/no-sections")
        expected_error_msg = "File contains no section headers."
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            LintConfig.load_from_file(path)

        # non-existing rule
        path = self.get_sample_path("config/nonexisting-rule")
        expected_error_msg = "No such rule 'foobar'"
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            LintConfig.load_from_file(path)

        # non-existing option
        path = self.get_sample_path("config/nonexisting-option")
        expected_error_msg = "Rule 'title-max-length' has no option 'foobar'"
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            LintConfig.load_from_file(path)

        # invalid option value
        path = self.get_sample_path("config/invalid-option-value")
        expected_error_msg = "'foo' is not a valid value for option 'title-max-length.line-length'. " + \
                             "Option 'line-length' must be a positive integer \(current value: 'foo'\)."
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            LintConfig.load_from_file(path)
Beispiel #4
0
 def test_ignore_independent_from_rules(self):
     # Test that the lintconfig rules are not modified when setting config.ignore
     # This was different in the past, this test is mostly here to catch regressions
     config = LintConfig()
     original_rules = config.rules
     config.ignore = ["T1", "T2"]
     self.assertEqual(config.ignore, ["T1", "T2"])
     self.assertListEqual(config.rules, original_rules)
 def test_lint_sample4(self):
     gitcontext = self.gitcontext(self.get_sample("commit_message/sample4"))
     lintconfig = LintConfig()
     lintconfig.apply_config_from_commit(gitcontext.commits[-1])
     linter = GitLinter(lintconfig)
     violations = linter.lint(gitcontext.commits[-1], gitcontext)
     # expect no violations because sample4 has a 'gitlint: disable line'
     expected = []
     self.assertListEqual(violations, expected)
    def test_set_rule_option(self):
        config = LintConfig()

        # assert default title line-length
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 72)

        # change line length and assert it is set
        config.set_rule_option('title-max-length', 'line-length', 60)
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 60)
Beispiel #7
0
 def test_install_commit_msg_hook(self, isdir, path_exists, copy, stat, chmod):
     lint_config = LintConfig()
     lint_config.target = self.SAMPLES_DIR
     expected_dst = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH)
     GitHookInstaller.install_commit_msg_hook(lint_config)
     isdir.assert_called_with(self.SAMPLES_DIR + '/.git/hooks')
     path_exists.assert_called_once_with(expected_dst)
     copy.assert_called_once_with(COMMIT_MSG_HOOK_SRC_PATH, expected_dst)
     stat.assert_called_once_with(expected_dst)
     chmod.assert_called_once_with(expected_dst, ANY)
Beispiel #8
0
    def test_lint_ignore(self):
        lint_config = LintConfig()
        lint_config.ignore = ["T1", "T3", "T4", "T5", "T6", "B1", "B2"]
        linter = GitLinter(lint_config)
        violations = linter.lint(self.gitcommit(self.get_sample("commit_message/sample3")))

        expected = [RuleViolation("B4", "Second line is not empty", "This line should be empty", 2),
                    RuleViolation("B3", "Line contains hard tab characters (\\t)",
                                  "This line has a trailing tab.\t", 5)]

        self.assertListEqual(violations, expected)
Beispiel #9
0
    def test_lint_ignore(self):
        lint_config = LintConfig()
        lint_config.ignore = ["T1", "T3", "T4", "T5", "T6", "B1", "B2"]
        linter = GitLinter(lint_config)
        violations = linter.lint(self.gitcommit(self.get_sample("commit_message/sample3")))

        expected = [RuleViolation("B4", "Second line is not empty", "This line should be empty", 2),
                    RuleViolation("B3", "Line contains hard tab characters (\\t)",
                                  u"This line has a tråiling tab.\t", 5)]

        self.assertListEqual(violations, expected)
Beispiel #10
0
    def test_uninstall_commit_msg_hook(self, isdir, path_exists, remove):
        lint_config = LintConfig()
        lint_config.target = self.SAMPLES_DIR
        read_data = "#!/bin/sh\n" + GITLINT_HOOK_IDENTIFIER
        with patch('gitlint.hooks.open', mock_open(read_data=read_data), create=True):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)

        expected_dst = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH)
        isdir.assert_called_with(os.path.join(self.SAMPLES_DIR, '.git/hooks'))
        path_exists.assert_called_once_with(expected_dst)
        remove.assert_called_with(expected_dst)
Beispiel #11
0
    def test_extra_path_negative(self):
        config = LintConfig()
        regex = u"Option extra-path must be either an existing directory or file \(current value: 'föo/bar'\)"
        # incorrect extra_path
        with self.assertRaisesRegex(LintConfigError, regex):
            config.extra_path = u"föo/bar"

        # extra path contains classes with errors
        with self.assertRaisesRegex(LintConfigError,
                                    "User-defined rule class 'MyUserLineRule' must have a 'validate' method"):
            config.extra_path = self.get_sample_path("user_rules/incorrect_linerule")
    def test_rebuild_config(self):
        # normal config build
        config_builder = LintConfigBuilder()
        config_builder.set_option('general', 'verbosity', 3)
        lint_config = config_builder.build()
        self.assertEqual(lint_config.verbosity, 3)

        # check that existing config changes when we rebuild it
        existing_lintconfig = LintConfig()
        existing_lintconfig.verbosity = 2
        lint_config = config_builder.build(existing_lintconfig)
        self.assertEqual(lint_config.verbosity, 3)
Beispiel #13
0
    def test_contrib_negative(self):
        config = LintConfig()
        # non-existent contrib rule
        with self.assertRaisesRegex(LintConfigError, u"No contrib rule with id or name 'föo' found."):
            config.contrib = u"contrib-title-conventional-commits,föo"

        # UserRuleError, RuleOptionError should be re-raised as LintConfigErrors
        side_effects = [rules.UserRuleError(u"üser-rule"), options.RuleOptionError(u"rüle-option")]
        for side_effect in side_effects:
            with patch('gitlint.config.rule_finder.find_rule_classes', side_effect=side_effect):
                with self.assertRaisesRegex(LintConfigError, ustr(side_effect)):
                    config.contrib = u"contrib-title-conventional-commits"
Beispiel #14
0
    def test_rebuild_config(self):
        # normal config build
        config_builder = LintConfigBuilder()
        config_builder.set_option('general', 'verbosity', 3)
        lint_config = config_builder.build()
        self.assertEqual(lint_config.verbosity, 3)

        # check that existing config changes when we rebuild it
        existing_lintconfig = LintConfig()
        existing_lintconfig.verbosity = 2
        lint_config = config_builder.build(existing_lintconfig)
        self.assertEqual(lint_config.verbosity, 3)
Beispiel #15
0
    def test_rebuild_config(self):
        # normal config build
        config_builder = LintConfigBuilder()
        config_builder.set_option('general', 'verbosity', 3)
        lint_config = config_builder.build()
        self.assertEqual(lint_config.verbosity, 3)

        # check that existing config gets overwritten when we pass it to a configbuilder with different options
        existing_lintconfig = LintConfig()
        existing_lintconfig.verbosity = 2
        lint_config = config_builder.build(existing_lintconfig)
        self.assertEqual(lint_config.verbosity, 3)
        self.assertEqual(existing_lintconfig.verbosity, 3)
Beispiel #16
0
    def test_uninstall_commit_msg_hook(isdir, path_exists, remove):
        lint_config = LintConfig()
        lint_config.target = u"/foo/bår"
        read_data = "#!/bin/sh\n" + GITLINT_HOOK_IDENTIFIER
        with patch('gitlint.hooks.open',
                   mock_open(read_data=read_data),
                   create=True):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)

        expected_dst = os.path.join(u"/foo/bår", COMMIT_MSG_HOOK_DST_PATH)
        isdir.assert_called_with(os.path.join(u"/foo/bår", '.git/hooks'))
        path_exists.assert_called_once_with(expected_dst)
        remove.assert_called_with(expected_dst)
Beispiel #17
0
    def test_ignore_by_title(self):
        commit = self.gitcommit("Releäse\n\nThis is the secōnd body line")

        # No regex specified -> Config shouldn't be changed
        rule = rules.IgnoreByTitle()
        config = LintConfig()
        rule.apply(config, commit)
        self.assertEqual(config, LintConfig())
        self.assert_logged([])  # nothing logged -> nothing ignored

        # Matching regex -> expect config to ignore all rules
        rule = rules.IgnoreByTitle({"regex": "^Releäse(.*)"})
        expected_config = LintConfig()
        expected_config.ignore = "all"
        rule.apply(config, commit)
        self.assertEqual(config, expected_config)

        expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I1': " + \
            "Commit title 'Releäse' matches the regex '^Releäse(.*)', ignoring rules: all"
        self.assert_log_contains(expected_log_message)

        # Matching regex with specific ignore
        rule = rules.IgnoreByTitle({
            "regex": "^Releäse(.*)",
            "ignore": "T1,B2"
        })
        expected_config = LintConfig()
        expected_config.ignore = "T1,B2"
        rule.apply(config, commit)
        self.assertEqual(config, expected_config)

        expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I1': " + \
            "Commit title 'Releäse' matches the regex '^Releäse(.*)', ignoring rules: T1,B2"
Beispiel #18
0
    def test_lint_regex_rules(self):
        """ Additional test for title-match-regex, body-match-regex """
        commit = self.gitcommit(
            self.get_sample("commit_message/no-violations"))
        lintconfig = LintConfig()
        linter = GitLinter(lintconfig)
        violations = linter.lint(commit)
        # No violations by default
        self.assertListEqual(violations, [])

        # Matching regexes shouldn't be a problem
        rule_regexes = [("title-match-regex", u"Tïtle$"),
                        ("body-match-regex", u"Sïgned-Off-By: (.*)$")]
        for rule_regex in rule_regexes:
            lintconfig.set_rule_option(rule_regex[0], "regex", rule_regex[1])
            violations = linter.lint(commit)
            self.assertListEqual(violations, [])

        # Non-matching regexes should return violations
        rule_regexes = [("title-match-regex", ), ("body-match-regex", )]
        lintconfig.set_rule_option("title-match-regex", "regex", u"^Tïtle")
        lintconfig.set_rule_option("body-match-regex", "regex",
                                   u"Sügned-Off-By: (.*)$")
        expected_violations = [
            RuleViolation("T7", u"Title does not match regex (^Tïtle)",
                          u"Normal Commit Tïtle", 1),
            RuleViolation("B8",
                          u"Body does not match regex (Sügned-Off-By: (.*)$)",
                          None, 6)
        ]
        violations = linter.lint(commit)
        self.assertListEqual(violations, expected_violations)
Beispiel #19
0
    def test_set_config_from_string_list(self):
        config = LintConfig()
        # assert some defaults
        self.assertEqual(
            config.get_rule_option('title-max-length', 'line-length'), 72)
        self.assertEqual(
            config.get_rule_option('body-max-line-length', 'line-length'), 80)
        self.assertListEqual(
            config.get_rule_option('title-must-not-contain-word', 'words'),
            ["WIP"])
        self.assertEqual(config.verbosity, 3)

        # change and assert changes
        config_builder = LintConfigBuilder()
        config_builder.set_config_from_string_list([
            'general.verbosity=1', 'title-max-length.line-length=60',
            'body-max-line-length.line-length=120',
            u"title-must-not-contain-word.words=håha"
        ])

        config = config_builder.build()
        self.assertEqual(
            config.get_rule_option('title-max-length', 'line-length'), 60)
        self.assertEqual(
            config.get_rule_option('body-max-line-length', 'line-length'), 120)
        self.assertListEqual(
            config.get_rule_option('title-must-not-contain-word', 'words'),
            [u"håha"])
        self.assertEqual(config.verbosity, 1)
Beispiel #20
0
    def test_set_general_option_negative(self):
        config = LintConfig()

        with self.assertRaisesRegexp(LintConfigError, "'foo' is not a valid gitlint option"):
            config.set_general_option("foo", "bar")

        # invalid verbosity
        incorrect_values = [-1, "foo"]
        for value in incorrect_values:
            expected_msg = r"Option 'verbosity' must be a positive integer \(current value: '{0}'\)".format(value)
            with self.assertRaisesRegexp(LintConfigError, expected_msg):
                config.verbosity = value

        incorrect_values = [4]
        for value in incorrect_values:
            with self.assertRaisesRegexp(LintConfigError, "Option 'verbosity' must be set between 0 and 3"):
                config.verbosity = value

        # invalid ignore_merge_commits
        incorrect_values = [-1, 4, "foo"]
        for value in incorrect_values:
            with self.assertRaisesRegexp(LintConfigError,
                                         r"Option 'ignore-merge-commits' must be either 'true' or 'false'"):
                config.ignore_merge_commits = value

        # invalid debug
        with self.assertRaisesRegexp(LintConfigError, r"Option 'debug' must be either 'true' or 'false'"):
            config.debug = "foobar"
Beispiel #21
0
    def test_ignore_by_body(self):
        commit = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line")

        # No regex specified -> Config shouldn't be changed
        rule = rules.IgnoreByBody()
        config = LintConfig()
        rule.apply(config, commit)
        self.assertEqual(config, LintConfig())
        self.assert_logged([])  # nothing logged -> nothing ignored

        # Matching regex -> expect config to ignore all rules
        rule = rules.IgnoreByBody({"regex": "(.*)relëase(.*)"})
        expected_config = LintConfig()
        expected_config.ignore = "all"
        rule.apply(config, commit)
        self.assertEqual(config, expected_config)

        expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I2': " + \
                               "Commit message line ' a relëase body' matches the regex '(.*)relëase(.*)'," + \
                               " ignoring rules: all"
        self.assert_log_contains(expected_log_message)

        # Matching regex with specific ignore
        rule = rules.IgnoreByBody({
            "regex": "(.*)relëase(.*)",
            "ignore": "T1,B2"
        })
        expected_config = LintConfig()
        expected_config.ignore = "T1,B2"
        rule.apply(config, commit)
        self.assertEqual(config, expected_config)

        expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I2': " + \
            "Commit message line ' a relëase body' matches the regex '(.*)relëase(.*)', ignoring rules: T1,B2"
        self.assert_log_contains(expected_log_message)
Beispiel #22
0
    def test_lint_merge_commit(self):
        commit = self.gitcommit(self.get_sample("commit_message/sample6"))  # Sample 6 is a merge commit
        lintconfig = LintConfig()
        linter = GitLinter(lintconfig)
        violations = linter.lint(commit)
        # Even though there are a number of violations in the commit message, they are ignored because
        # we are dealing with a merge commit
        self.assertListEqual(violations, [])

        # Check that we do see violations if we disable 'ignore-merge-commits'
        lintconfig.ignore_merge_commits = False
        linter = GitLinter(lintconfig)
        violations = linter.lint(commit)
        self.assertTrue(len(violations) > 0)
Beispiel #23
0
def get_config(ctx, target, config_path, c, ignore, verbose, silent):
    """ Creates a LintConfig object based on a set of commandline parameters. """
    try:
        # Config precedence:
        # First, load default config or config from configfile
        lint_config = load_config_from_path(ctx, config_path)
        # default to default configuration when no config file was loaded
        if lint_config:
            click.echo("Using config from {0}".format(lint_config.config_path))
        else:
            lint_config = LintConfig()

        # Then process any commandline configuration flags
        lint_config.apply_config_options(c)

        # Finally, overwrite with any convenience commandline flags
        lint_config.apply_on_csv_string(ignore, lint_config.disable_rule)
        if silent:
            lint_config.verbosity = 0
        elif verbose > 0:
            lint_config.verbosity = verbose

        # Set target
        lint_config.target = target
        return lint_config
    except LintConfigError as e:
        click.echo("Config Error: {0}".format(str(e)))
    ctx.exit(CONFIG_ERROR_CODE)  # return CONFIG_ERROR_CODE on config error
Beispiel #24
0
    def test_lint_merge_commit(self):
        commit = self.gitcommit(self.get_sample(
            "commit_message/sample6"))  # Sample 6 is a merge commit
        lintconfig = LintConfig()
        linter = GitLinter(lintconfig)
        violations = linter.lint(commit)
        # Even though there are a number of violations in the commit message, they are ignored because
        # we are dealing with a merge commit
        self.assertListEqual(violations, [])

        # Check that we do see violations if we disable 'ignore-merge-commits'
        lintconfig.ignore_merge_commits = False
        linter = GitLinter(lintconfig)
        violations = linter.lint(commit)
        self.assertTrue(len(violations) > 0)
Beispiel #25
0
def load_config_from_path(ctx, config_path=None):
    """ Tries loading the config from the given path. If no path is specified, the default config path
    is tried, and if no file exists at the that location, None is returned. """
    config = None
    try:
        if config_path:
            config = LintConfig.load_from_file(config_path)
        elif os.path.exists(DEFAULT_CONFIG_FILE):
            config = LintConfig.load_from_file(DEFAULT_CONFIG_FILE)

    except LintConfigError as e:
        click.echo("Error during config file parsing: {0}".format(str(e)))
        ctx.exit(CONFIG_ERROR_CODE)

    return config
Beispiel #26
0
 def test_install_commit_msg_hook(git_hooks_dir, isdir, path_exists, copy,
                                  stat, chmod):
     lint_config = LintConfig()
     lint_config.target = os.path.join(u"/hür", u"dur")
     git_hooks_dir.return_value = os.path.join(u"/föo", u"bar", ".git",
                                               "hooks")
     expected_dst = os.path.join(git_hooks_dir.return_value,
                                 COMMIT_MSG_HOOK_DST_PATH)
     GitHookInstaller.install_commit_msg_hook(lint_config)
     isdir.assert_called_with(git_hooks_dir.return_value)
     path_exists.assert_called_once_with(expected_dst)
     copy.assert_called_once_with(COMMIT_MSG_HOOK_SRC_PATH, expected_dst)
     stat.assert_called_once_with(expected_dst)
     chmod.assert_called_once_with(expected_dst, ANY)
     git_hooks_dir.assert_called_with(lint_config.target)
Beispiel #27
0
def load_config_from_path(ctx, config_path=None):
    """ Tries loading the config from the given path. If no path is specified, the default config path
    is tried, and if no file exists at the that location, None is returned. """
    config = None
    try:
        if config_path:
            config = LintConfig.load_from_file(config_path)
        elif os.path.exists(DEFAULT_CONFIG_FILE):
            config = LintConfig.load_from_file(DEFAULT_CONFIG_FILE)

    except LintConfigError as e:
        click.echo("Error during config file parsing: {0}".format(str(e)))
        ctx.exit(CONFIG_ERROR_CODE)

    return config
Beispiel #28
0
    def test_set_general_option_negative(self):
        config = LintConfig()

        # Note that we shouldn't test whether we can set unicode because python just doesn't allow unicode attributes
        with self.assertRaisesRegex(LintConfigError, "'foo' is not a valid gitlint option"):
            config.set_general_option("foo", u"bår")

        # try setting _config_path, this is a real attribute of LintConfig, but the code should prevent it from
        # being set
        with self.assertRaisesRegex(LintConfigError, "'_config_path' is not a valid gitlint option"):
            config.set_general_option("_config_path", u"bår")

        # invalid verbosity`
        incorrect_values = [-1, u"föo"]
        for value in incorrect_values:
            expected_msg = u"Option 'verbosity' must be a positive integer \(current value: '{0}'\)".format(value)
            with self.assertRaisesRegex(LintConfigError, expected_msg):
                config.verbosity = value

        incorrect_values = [4]
        for value in incorrect_values:
            with self.assertRaisesRegex(LintConfigError, "Option 'verbosity' must be set between 0 and 3"):
                config.verbosity = value

        # invalid ignore_xxx_commits
        ignore_attributes = ["ignore_merge_commits", "ignore_fixup_commits", "ignore_squash_commits",
                             "ignore_revert_commits"]
        incorrect_values = [-1, 4, u"föo"]
        for attribute in ignore_attributes:
            for value in incorrect_values:
                option_name = attribute.replace("_", "-")
                with self.assertRaisesRegex(LintConfigError,
                                            "Option '{0}' must be either 'true' or 'false'".format(option_name)):
                    setattr(config, attribute, value)

        # invalid ignore -> not here because ignore is a ListOption which converts everything to a string before
        # splitting which means it it will accept just about everything

        # invalid debug
        with self.assertRaisesRegex(LintConfigError, "Option 'debug' must be either 'true' or 'false'"):
            config.debug = u"föobar"

        # extra-path has its own negative test

        # invalid target
        with self.assertRaisesRegex(LintConfigError,
                                    u"Option target must be an existing directory \(current value: 'föo/bar'\)"):
            config.target = u"föo/bar"
Beispiel #29
0
    def test_print_violations(self):
        violations = [
            RuleViolation("RULE_ID_1", u"Error Messåge 1",
                          "Violating Content 1", None),
            RuleViolation("RULE_ID_2", "Error Message 2",
                          u"Violåting Content 2", 2)
        ]
        linter = GitLinter(LintConfig())

        # test output with increasing verbosity
        with patch('gitlint.display.stderr', new=StringIO()) as stderr:
            linter.config.verbosity = 0
            linter.print_violations(violations)
            self.assertEqual("", stderr.getvalue())

        with patch('gitlint.display.stderr', new=StringIO()) as stderr:
            linter.config.verbosity = 1
            linter.print_violations(violations)
            expected = u"-: RULE_ID_1\n2: RULE_ID_2\n"
            self.assertEqual(expected, stderr.getvalue())

        with patch('gitlint.display.stderr', new=StringIO()) as stderr:
            linter.config.verbosity = 2
            linter.print_violations(violations)
            expected = u"-: RULE_ID_1 Error Messåge 1\n2: RULE_ID_2 Error Message 2\n"
            self.assertEqual(expected, stderr.getvalue())

        with patch('gitlint.display.stderr', new=StringIO()) as stderr:
            linter.config.verbosity = 3
            linter.print_violations(violations)
            expected = u"-: RULE_ID_1 Error Messåge 1: \"Violating Content 1\"\n" + \
                       u"2: RULE_ID_2 Error Message 2: \"Violåting Content 2\"\n"
            self.assertEqual(expected, stderr.getvalue())
    def test_set_config_from_string_list(self):
        config = LintConfig()
        # assert some defaults
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 72)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 80)
        self.assertEqual(config.verbosity, 3)

        # change and assert changes
        config_builder = LintConfigBuilder()
        config_builder.set_config_from_string_list(['general.verbosity=1', 'title-max-length.line-length=60',
                                                    'body-max-line-length.line-length=120'])

        config = config_builder.build()
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 60)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 120)
        self.assertEqual(config.verbosity, 1)
Beispiel #31
0
    def test_set_from_commit_ignore_all(self):
        config = LintConfig()
        original_rules = config.rules
        original_rule_ids = [rule.id for rule in original_rules]

        config_builder = LintConfigBuilder()

        # nothing gitlint
        config_builder.set_config_from_commit(
            self.gitcommit(u"tëst\ngitlint\nfoo"))
        config = config_builder.build()
        self.assertListEqual(config.rules, original_rules)
        self.assertListEqual(config.ignore, [])

        # ignore all rules
        config_builder.set_config_from_commit(
            self.gitcommit(u"tëst\ngitlint-ignore: all\nfoo"))
        config = config_builder.build()
        self.assertEqual(config.ignore, original_rule_ids)

        # ignore all rules, no space
        config_builder.set_config_from_commit(
            self.gitcommit(u"tëst\ngitlint-ignore:all\nfoo"))
        config = config_builder.build()
        self.assertEqual(config.ignore, original_rule_ids)

        # ignore all rules, more spacing
        config_builder.set_config_from_commit(
            self.gitcommit(u"tëst\ngitlint-ignore: \t all\nfoo"))
        config = config_builder.build()
        self.assertEqual(config.ignore, original_rule_ids)
Beispiel #32
0
    def test_lint_sample3(self):
        linter = GitLinter(LintConfig())
        gitcontext = self.gitcontext(self.get_sample("commit_message/sample3"))
        violations = linter.lint(gitcontext.commits[-1])

        title = u" Commit title containing 'WIP', \tleading and tråiling whitespace and longer than 72 characters."
        expected = [
            RuleViolation("T1", "Title exceeds max length (95>72)", title, 1),
            RuleViolation("T3", "Title has trailing punctuation (.)", title,
                          1),
            RuleViolation("T4", "Title contains hard tab characters (\\t)",
                          title, 1),
            RuleViolation("T5",
                          "Title contains the word 'WIP' (case-insensitive)",
                          title, 1),
            RuleViolation("T6", "Title has leading whitespace", title, 1),
            RuleViolation("B4", "Second line is not empty",
                          "This line should be empty", 2),
            RuleViolation(
                "B1", "Line exceeds max length (101>80)",
                u"This is the first line is meånt to test a line that exceeds the maximum line "
                + "length of 80 characters.", 3),
            RuleViolation("B2", "Line has trailing whitespace",
                          "This line has a trailing space. ", 4),
            RuleViolation("B2", "Line has trailing whitespace",
                          u"This line has a tråiling tab.\t", 5),
            RuleViolation("B3", "Line contains hard tab characters (\\t)",
                          u"This line has a tråiling tab.\t", 5)
        ]

        self.assertListEqual(violations, expected)
Beispiel #33
0
    def test_get_rule(self):
        config = LintConfig()

        # get by id
        expected = rules.TitleMaxLength()
        rule = config.get_rule('T1')
        self.assertEqual(rule, expected)

        # get by name
        expected = rules.TitleTrailingWhitespace()  # pylint: disable=redefined-variable-type
        rule = config.get_rule('title-trailing-whitespace')
        self.assertEqual(rule, expected)

        # get non-existing
        rule = config.get_rule('foo')
        self.assertIsNone(rule)
    def test_get_rule(self):
        config = LintConfig()

        # get by id
        expected = rules.TitleMaxLength()
        rule = config.get_rule('T1')
        self.assertEqual(rule, expected)

        # get by name
        expected2 = rules.TitleTrailingWhitespace()
        rule = config.get_rule('title-trailing-whitespace')
        self.assertEqual(rule, expected2)

        # get non-existing
        rule = config.get_rule(u'föo')
        self.assertIsNone(rule)
    def test_get_rule(self):
        config = LintConfig()

        # get by id
        expected = rules.TitleMaxLength()
        rule = config.get_rule('T1')
        self.assertEqual(rule, expected)

        # get by name
        expected = rules.TitleTrailingWhitespace()  # pylint: disable=redefined-variable-type
        rule = config.get_rule('title-trailing-whitespace')
        self.assertEqual(rule, expected)

        # get non-existing
        rule = config.get_rule('foo')
        self.assertIsNone(rule)
    def test_e(self):
        display = Display(LintConfig())
        display.config.verbosity = 2

        with patch('gitlint.display.stdout', new=StringIO()) as stdout:
            # Non exact outputting, should output both v and vv output
            with patch('gitlint.display.stderr', new=StringIO()) as stderr:
                display.e(u"tëst")
                display.ee(u"tëst2")
                # vvvv should be ignored regardless
                display.eee(u"tëst3.1")
                display.eee(u"tëst3.2", exact=True)
                self.assertEqual(u"tëst\ntëst2\n", stderr.getvalue())

            # exact outputting, should only output v
            with patch('gitlint.display.stderr', new=StringIO()) as stderr:
                display.e(u"tëst", exact=True)
                display.ee(u"tëst2", exact=True)
                # vvvv should be ignored regardless
                display.eee(u"tëst3.1")
                display.eee(u"tëst3.2", exact=True)
                self.assertEqual(u"tëst2\n", stderr.getvalue())

            # standard output should be empty throughtout all of this
            self.assertEqual('', stdout.getvalue())
Beispiel #37
0
    def test_lint_sample1(self):
        linter = GitLinter(LintConfig())
        gitcontext = self.gitcontext(self.get_sample("commit_message/sample1"))
        violations = linter.lint(gitcontext.commits[-1])
        expected_errors = [
            RuleViolation(
                "T3", "Title has trailing punctuation (.)",
                u"Commit title contåining 'WIP', as well as trailing punctuation.",
                1),
            RuleViolation(
                "T5", "Title contains the word 'WIP' (case-insensitive)",
                u"Commit title contåining 'WIP', as well as trailing punctuation.",
                1),
            RuleViolation("B4", "Second line is not empty",
                          "This line should be empty", 2),
            RuleViolation(
                "B1", "Line exceeds max length (135>80)",
                "This is the first line of the commit message body and it is meant to test "
                +
                "a line that exceeds the maximum line length of 80 characters.",
                3),
            RuleViolation("B2", "Line has trailing whitespace",
                          u"This line has a tråiling space. ", 4),
            RuleViolation("B2", "Line has trailing whitespace",
                          "This line has a trailing tab.\t", 5),
            RuleViolation("B3", "Line contains hard tab characters (\\t)",
                          "This line has a trailing tab.\t", 5)
        ]

        self.assertListEqual(violations, expected_errors)
Beispiel #38
0
    def test_uninstall_commit_msg_hook_negative(self, git_hooks_dir, isdir,
                                                path_exists, remove):
        lint_config = LintConfig()
        lint_config.target = os.path.join(u"/hür", u"dur")
        git_hooks_dir.return_value = os.path.join(u"/föo", u"bar", ".git",
                                                  "hooks")

        # mock that the current directory is not a git repo
        isdir.return_value = False
        expected_msg = u"{0} is not a git repository".format(
            lint_config.target)
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)
            isdir.assert_called_with(git_hooks_dir.return_value)
            path_exists.assert_not_called()
            remove.assert_not_called()

        # mock that there is no commit hook present
        isdir.return_value = True
        path_exists.return_value = False
        expected_dst = os.path.join(git_hooks_dir.return_value,
                                    COMMIT_MSG_HOOK_DST_PATH)
        expected_msg = u"There is no commit-msg hook present in {0}.".format(
            expected_dst)
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)
            isdir.assert_called_with(git_hooks_dir.return_value)
            path_exists.assert_called_once_with(expected_dst)
            remove.assert_not_called()

        # mock that there is a different (=not gitlint) commit hook
        isdir.return_value = True
        path_exists.return_value = True
        read_data = "#!/bin/sh\nfoo"
        expected_dst = os.path.join(git_hooks_dir.return_value,
                                    COMMIT_MSG_HOOK_DST_PATH)
        expected_msg = u"The commit-msg hook in {0} was not installed by gitlint ".format(expected_dst) + \
                       r"\(or it was modified\).\nUninstallation of 3th party or modified gitlint hooks " + \
                       "is not supported."
        with patch('gitlint.hooks.io.open',
                   mock_open(read_data=read_data),
                   create=True):
            with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
                GitHookInstaller.uninstall_commit_msg_hook(lint_config)
            remove.assert_not_called()
Beispiel #39
0
    def test_lint_sample2(self):
        linter = GitLinter(LintConfig())
        gitcontext = self.gitcontext(self.get_sample("commit_message/sample2"))
        violations = linter.lint(gitcontext.commits[-1])
        expected = [RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)",
                                  u"Just a title contåining WIP", 1),
                    RuleViolation("B6", "Body message is missing", None, 3)]

        self.assertListEqual(violations, expected)
Beispiel #40
0
    def test_load_config_from_file(self):
        # regular config file load, no problems
        config = LintConfig.load_from_file(self.get_sample_path("config/gitlintconfig"))

        # Do some assertions on the config
        self.assertEqual(config.verbosity, 1)
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 20)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 30)
        self.assertIsNone(config.get_rule('title-trailing-whitespace'))
Beispiel #41
0
 def test_install_commit_msg_hook(isdir, path_exists, copy, stat, chmod):
     lint_config = LintConfig(target="/foo/bar")
     expected_dst = os.path.join("/foo/bar", COMMIT_MSG_HOOK_DST_PATH)
     GitHookInstaller.install_commit_msg_hook(lint_config)
     isdir.assert_called_once_with('/foo/bar/.git/hooks')
     path_exists.assert_called_once_with(expected_dst)
     copy.assert_called_once_with(COMMIT_MSG_HOOK_SRC_PATH, expected_dst)
     stat.assert_called_once_with(expected_dst)
     chmod.assert_called_once_with(expected_dst, ANY)
Beispiel #42
0
    def test_uninstall_commit_msg_hook(git_hooks_dir, isdir, path_exists,
                                       remove):
        lint_config = LintConfig()
        git_hooks_dir.return_value = os.path.join(u"/föo", u"bar", ".git",
                                                  "hooks")
        lint_config.target = os.path.join(u"/hür", u"dur")
        read_data = "#!/bin/sh\n" + GITLINT_HOOK_IDENTIFIER
        with patch('gitlint.hooks.io.open',
                   mock_open(read_data=read_data),
                   create=True):
            GitHookInstaller.uninstall_commit_msg_hook(lint_config)

        expected_dst = os.path.join(git_hooks_dir.return_value,
                                    COMMIT_MSG_HOOK_DST_PATH)
        isdir.assert_called_with(git_hooks_dir.return_value)
        path_exists.assert_called_once_with(expected_dst)
        remove.assert_called_with(expected_dst)
        git_hooks_dir.assert_called_with(lint_config.target)
Beispiel #43
0
    def test_contrib(self):
        config = LintConfig()
        contrib_rules = ["contrib-title-conventional-commits", "CC1"]
        config.set_general_option("contrib", ",".join(contrib_rules))
        self.assertEqual(config.contrib, contrib_rules)

        # Check contrib-title-conventional-commits contrib rule
        actual_rule = config.rules.find_rule(
            "contrib-title-conventional-commits")
        self.assertTrue(actual_rule.is_contrib)

        self.assertEqual(ustr(type(actual_rule)),
                         "<class 'conventional_commit.ConventionalCommit'>")
        self.assertEqual(actual_rule.id, 'CT1')
        self.assertEqual(actual_rule.name,
                         u'contrib-title-conventional-commits')
        self.assertEqual(actual_rule.target, rules.CommitMessageTitle)

        expected_rule_option = options.ListOption(
            "types",
            [
                "fix", "feat", "chore", "docs", "style", "refactor", "perf",
                "test", "revert"
            ],
            "Comma separated list of allowed commit types.",
        )

        self.assertListEqual(actual_rule.options_spec, [expected_rule_option])
        self.assertDictEqual(actual_rule.options,
                             {'types': expected_rule_option})

        # Check contrib-body-requires-signed-off-by contrib rule
        actual_rule = config.rules.find_rule(
            "contrib-body-requires-signed-off-by")
        self.assertTrue(actual_rule.is_contrib)

        self.assertEqual(ustr(type(actual_rule)),
                         "<class 'signedoff_by.SignedOffBy'>")
        self.assertEqual(actual_rule.id, 'CC1')
        self.assertEqual(actual_rule.name,
                         u'contrib-body-requires-signed-off-by')

        # reset value (this is a different code path)
        config.set_general_option("contrib",
                                  "contrib-body-requires-signed-off-by")
        self.assertEqual(
            actual_rule,
            config.rules.find_rule("contrib-body-requires-signed-off-by"))
        self.assertIsNone(
            config.rules.find_rule("contrib-title-conventional-commits"))

        # empty value
        config.set_general_option("contrib", "")
        self.assertListEqual(config.contrib, [])
 def test_lint_sample5(self):
     gitcontext = self.gitcontext(self.get_sample("commit_message/sample5"))
     lintconfig = LintConfig()
     lintconfig.apply_config_from_commit(gitcontext.commits[-1])
     linter = GitLinter(lintconfig)
     violations = linter.lint(gitcontext.commits[-1], gitcontext)
     title = " Commit title containing 'WIP', \tleading and trailing whitespace and longer than 72 characters."
     # expect only certain violations because sample5 has a 'gitlint: T3,'
     expected = [RuleViolation("T1", "Title exceeds max length (95>72)", title, 1),
                 RuleViolation("T4", "Title contains hard tab characters (\\t)", title, 1),
                 RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", title, 1),
                 RuleViolation("B4", "Second line is not empty", "This line should be empty", 2),
                 RuleViolation("B2", "Line has trailing whitespace",
                               "This line has a trailing space. ", 4),
                 RuleViolation("B2", "Line has trailing whitespace", "This line has a trailing tab.\t",
                               5),
                 RuleViolation("B3", "Line contains hard tab characters (\\t)",
                               "This line has a trailing tab.\t", 5)]
     self.assertListEqual(violations, expected)
Beispiel #45
0
    def test_apply_config_options(self):
        config = LintConfig()
        # assert some defaults
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 72)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 80)
        self.assertEqual(config.verbosity, 3)

        # change and assert changes
        config.apply_config_options(['general.verbosity=1', 'title-max-length.line-length=60',
                                     'body-max-line-length.line-length=120'])
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 60)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 120)
        self.assertEqual(config.verbosity, 1)
Beispiel #46
0
    def test_install_commit_msg_hook_negative(self, isdir, path_exists, copy):
        lint_config = LintConfig()
        lint_config.target = self.SAMPLES_DIR
        # mock that current dir is not a git repo
        isdir.return_value = False
        expected_msg = "{0} is not a git repository".format(self.SAMPLES_DIR)
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.install_commit_msg_hook(lint_config)
            isdir.assert_called_with(os.path.join(self.SAMPLES_DIR, '.git/hooks'))
            path_exists.assert_not_called()
            copy.assert_not_called()

        # mock that there is already a commit hook present
        isdir.return_value = True
        path_exists.return_value = True
        expected_dst = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH)
        expected_msg = "There is already a commit-msg hook file present in {0}.\n".format(expected_dst) + \
                       "gitlint currently does not support appending to an existing commit-msg file."
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.install_commit_msg_hook(lint_config)
Beispiel #47
0
    def test_install_commit_msg_hook_negative(self, isdir, path_exists, copy):
        lint_config = LintConfig()
        lint_config.target = u"/foo/bår"
        # mock that current dir is not a git repo
        isdir.return_value = False
        expected_msg = u"{0} is not a git repository".format(u"/foo/bår")
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.install_commit_msg_hook(lint_config)
            isdir.assert_called_with(os.path.join(u"/foo/bår", '.git/hooks'))
            path_exists.assert_not_called()
            copy.assert_not_called()

        # mock that there is already a commit hook present
        isdir.return_value = True
        path_exists.return_value = True
        expected_dst = os.path.join(u"/foo/bår", COMMIT_MSG_HOOK_DST_PATH)
        expected_msg = u"There is already a commit-msg hook file present in {0}.\n".format(expected_dst) + \
                       "gitlint currently does not support appending to an existing commit-msg file."
        with self.assertRaisesRegex(GitHookInstallerError, expected_msg):
            GitHookInstaller.install_commit_msg_hook(lint_config)
Beispiel #48
0
    def test_load_config_from_file(self):
        # regular config file load, no problems
        config = LintConfig.load_from_file(
            self.get_sample_path("config/gitlintconfig"))

        # Do some assertions on the config
        self.assertEqual(config.verbosity, 1)
        self.assertEqual(
            config.get_rule_option('title-max-length', 'line-length'), 20)
        self.assertEqual(
            config.get_rule_option('body-max-line-length', 'line-length'), 30)
        self.assertIsNone(config.get_rule('title-trailing-whitespace'))
Beispiel #49
0
def get_lint_config(config_path=None):
    """ Tries loading the config from the given path. If no path is specified, the default config path
    is tried, and if that is not specified, we the default config is returned. """
    # config path specified
    config = None
    try:
        if config_path:
            config = LintConfig.load_from_file(config_path)
        elif os.path.exists(DEFAULT_CONFIG_FILE):
            config = LintConfig.load_from_file(DEFAULT_CONFIG_FILE)

    except LintConfigError as e:
        click.echo("Error during config file parsing: {0}".format(e.message))
        exit(CONFIG_ERROR_CODE)  # return 10000 on config error

    # no config file
    if config:
        click.echo("Using config from {0}".format(config.config_path))
    else:
        config = LintConfig()

    return config
    def test_apply_config_options(self):
        config = LintConfig()
        # assert some defaults
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 72)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 80)
        self.assertEqual(config.verbosity, 3)

        # change and assert changes
        config.apply_config_options(['general.verbosity=1', 'title-max-length.line-length=60',
                                     'body-max-line-length.line-length=120'])
        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 60)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 120)
        self.assertEqual(config.verbosity, 1)
    def test_load_config_from_file(self):
        # regular config file load, no problems
        config = LintConfig.load_from_file(self.get_sample_path("config/gitlintconfig"))

        # Do some assertions on the config
        self.assertEqual(config.verbosity, 1)
        self.assertFalse(config.ignore_merge_commits)

        # ignored rules
        expected_ignored_rules = set([rules.BodyTrailingWhitespace, rules.TitleTrailingWhitespace])
        active_rule_classes = set(type(rule) for rule in config.rules)
        self.assertSetEqual(set(config.default_rule_classes) - expected_ignored_rules, active_rule_classes)

        self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 20)
        self.assertEqual(config.get_rule_option('body-max-line-length', 'line-length'), 30)
        self.assertIsNone(config.get_rule('title-trailing-whitespace'))
Beispiel #52
0
    def test_set_rule_option_negative(self):
        config = LintConfig()

        # non-existing rule
        expected_error_msg = "No such rule 'foobar'"
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            config.set_rule_option('foobar', 'line-length', 60)

        # non-existing option
        expected_error_msg = "Rule 'title-max-length' has no option 'foobar'"
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            config.set_rule_option('title-max-length', 'foobar', 60)

        # invalid option value
        expected_error_msg = "'foo' is not a valid value for option 'title-max-length.line-length'. " + \
                             "Option 'line-length' must be a positive integer \(current value: 'foo'\)."
        with self.assertRaisesRegexp(LintConfigError, expected_error_msg):
            config.set_rule_option('title-max-length', 'line-length', "foo")

        # invalid verbosity
        with self.assertRaisesRegexp(LintConfigError, "verbosity must be set between 0 and 3"):
            config.verbosity = -1
        with self.assertRaisesRegexp(LintConfigError, "verbosity must be set between 0 and 3"):
            config.verbosity = 4
Beispiel #53
0
    def test_extra_path(self):
        config = LintConfig()

        config.set_general_option("extra-path", self.get_rule_rules_path())
        self.assertEqual(config.extra_path, self.get_rule_rules_path())
        actual_rule = config.get_rule('TUC1')
        self.assertTrue(actual_rule.user_defined)
        self.assertEqual(str(type(actual_rule)), "<class 'my_commit_rules.MyUserCommitRule'>")
        self.assertEqual(actual_rule.id, 'TUC1')
        self.assertEqual(actual_rule.name, 'my-user-commit-rule')
        self.assertEqual(actual_rule.target, None)
        expected_rule_option = IntOption('violation-count', 1, "Number of violations to return")
        self.assertListEqual(actual_rule.options_spec, [expected_rule_option])
        self.assertDictEqual(actual_rule.options, {'violation-count': expected_rule_option})

        # reset value (this is a different code path)
        config.set_general_option("extra-path", self.SAMPLES_DIR)
        self.assertEqual(config.extra_path, self.SAMPLES_DIR)
        self.assertIsNone(config.get_rule("TUC1"))
    def test_set_general_option(self):
        config = LintConfig()

        # Check that default general options are correct
        self.assertTrue(config.ignore_merge_commits)
        self.assertEqual(config.verbosity, 3)
        active_rule_classes = [type(rule) for rule in config.rules]
        self.assertListEqual(active_rule_classes, config.default_rule_classes)

        # Check that we can change the general options
        # ignore
        config.set_general_option("ignore", "title-trailing-whitespace, B2")
        expected_ignored_rules = set([rules.BodyTrailingWhitespace, rules.TitleTrailingWhitespace])
        active_rule_classes = set(type(rule) for rule in config.rules)  # redetermine active rule classes
        expected_active_rule_classes = set(config.default_rule_classes) - expected_ignored_rules
        self.assertSetEqual(active_rule_classes, expected_active_rule_classes)

        # verbosity
        config.set_general_option("verbosity", 1)
        self.assertEqual(config.verbosity, 1)

        # ignore_merge_commit
        config.set_general_option("ignore-merge-commits", "false")
        self.assertFalse(config.ignore_merge_commits)
    def test_set_general_option_negative(self):
        config = LintConfig()

        with self.assertRaisesRegexp(LintConfigError, "'foo' is not a valid gitlint option"):
            config.set_general_option("foo", "bar")

        # invalid verbosity
        incorrect_values = [-1, "foo"]
        for value in incorrect_values:
            expected_msg = r"Option 'verbosity' must be a positive integer \(current value: '{0}'\)".format(value)
            with self.assertRaisesRegexp(LintConfigError, expected_msg):
                config.verbosity = value

        incorrect_values = [4]
        for value in incorrect_values:
            with self.assertRaisesRegexp(LintConfigError, "Option 'verbosity' must be set between 0 and 3"):
                config.verbosity = value

        # invalid ignore_merge_commits
        incorrect_values = [-1, 4, "foo"]
        for value in incorrect_values:
            with self.assertRaisesRegexp(LintConfigError,
                                         r"Option 'ignore-merge-commits' must be either 'true' or 'false'"):
                config.ignore_merge_commits = value
Beispiel #56
0
    def test_set_general_option_negative(self):
        config = LintConfig()

        with self.assertRaisesRegex(LintConfigError, "'foo' is not a valid gitlint option"):
            config.set_general_option("foo", "bar")

        # try setting _config_path, this is a real attribute of LintConfig, but the code should prevent it from
        # being set
        with self.assertRaisesRegex(LintConfigError, "'_config_path' is not a valid gitlint option"):
            config.set_general_option("_config_path", "bar")

        # invalid verbosity`
        incorrect_values = [-1, "foo"]
        for value in incorrect_values:
            expected_msg = r"Option 'verbosity' must be a positive integer \(current value: '{0}'\)".format(value)
            with self.assertRaisesRegex(LintConfigError, expected_msg):
                config.verbosity = value

        incorrect_values = [4]
        for value in incorrect_values:
            with self.assertRaisesRegex(LintConfigError, "Option 'verbosity' must be set between 0 and 3"):
                config.verbosity = value

        # invalid ignore_merge_commits
        incorrect_values = [-1, 4, "foo"]
        for value in incorrect_values:
            with self.assertRaisesRegex(LintConfigError,
                                        r"Option 'ignore-merge-commits' must be either 'true' or 'false'"):
                config.ignore_merge_commits = value

        # invalid ignore -> not here because ignore is a ListOption which converts everything to a string before
        # splitting which means it it will accept just about everything

        # invalid debug
        with self.assertRaisesRegex(LintConfigError, r"Option 'debug' must be either 'true' or 'false'"):
            config.debug = "foobar"

        # invalid extra-path
        with self.assertRaisesRegex(LintConfigError,
                                    r"Option extra-path must be an existing directory \(current value: 'foo/bar'\)"):
            config.extra_path = "foo/bar"

        # invalid target
        with self.assertRaisesRegex(LintConfigError,
                                    r"Option target must be an existing directory \(current value: 'foo/bar'\)"):
            config.target = "foo/bar"
Beispiel #57
0
    def test_set_general_option(self):
        config = LintConfig()

        # Check that default general options are correct
        self.assertTrue(config.ignore_merge_commits)
        self.assertFalse(config.debug)
        self.assertEqual(config.verbosity, 3)
        active_rule_classes = tuple(type(rule) for rule in config.rules)
        self.assertTupleEqual(active_rule_classes, config.default_rule_classes)

        # ignore - set by string
        config.set_general_option("ignore", "title-trailing-whitespace, B2")
        self.assertEqual(config.ignore, ["title-trailing-whitespace", "B2"])

        # ignore - set by list
        config.set_general_option("ignore", ["T1", "B3"])
        self.assertEqual(config.ignore, ["T1", "B3"])

        # verbosity
        config.set_general_option("verbosity", 1)
        self.assertEqual(config.verbosity, 1)

        # ignore_merge_commit
        config.set_general_option("ignore-merge-commits", "false")
        self.assertFalse(config.ignore_merge_commits)

        # debug
        config.set_general_option("debug", "true")
        self.assertTrue(config.debug)

        # target
        config.set_general_option("target", self.SAMPLES_DIR)
        self.assertEqual(config.target, self.SAMPLES_DIR)
Beispiel #58
0
 def test_commit_msg_hook_path(self):
     lint_config = LintConfig()
     lint_config.target = self.SAMPLES_DIR
     expected_path = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH)
     path = GitHookInstaller.commit_msg_hook_path(lint_config)
     self.assertEqual(path, expected_path)
    def test_gitcontext_ignore_all(self):
        config = LintConfig()
        original_rules = config.rules

        # nothing gitlint
        context = self.gitcontext("test\ngitlint\nfoo")
        config.apply_config_from_commit(context.commits[-1])
        self.assertListEqual(config.rules, original_rules)

        # ignore all rules
        context = self.gitcontext("test\ngitlint-ignore: all\nfoo")
        config.apply_config_from_commit(context.commits[-1])
        self.assertEqual(config.rules, [])

        # ignore all rules, no space
        config = LintConfig()
        context = self.gitcontext("test\ngitlint-ignore:all\nfoo")
        config.apply_config_from_commit(context.commits[-1])
        self.assertEqual(config.rules, [])

        # ignore all rules, more spacing
        config = LintConfig()
        context = self.gitcontext("test\ngitlint-ignore: \t all\nfoo")
        config.apply_config_from_commit(context.commits[-1])
        self.assertEqual(config.rules, [])
    def test_apply_config_options_negative(self):
        config = LintConfig()

        # assert error on incorrect rule
        with self.assertRaisesRegexp(LintConfigError, "No such rule 'foo'"):
            config.apply_config_options(['foo.bar=1'])

        # no equal sign
        expected_msg = "'foo.bar' is an invalid configuration option. Use '<rule>.<option>=<value>'"
        with self.assertRaisesRegexp(LintConfigError, expected_msg):
            config.apply_config_options(['foo.bar'])

        # missing value
        expected_msg = "'foo.bar=' is an invalid configuration option. Use '<rule>.<option>=<value>'"
        with self.assertRaisesRegexp(LintConfigError, expected_msg):
            config.apply_config_options(['foo.bar='])

        # space instead of equal sign
        expected_msg = "'foo.bar 1' is an invalid configuration option. Use '<rule>.<option>=<value>'"
        with self.assertRaisesRegexp(LintConfigError, expected_msg):
            config.apply_config_options(['foo.bar 1'])

        # no period between rule and option names
        expected_msg = "'foobar=1' is an invalid configuration option. Use '<rule>.<option>=<value>'"
        with self.assertRaisesRegexp(LintConfigError, expected_msg):
            config.apply_config_options(['foobar=1'])