summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoris Roovers <jroovers@cisco.com>2017-04-25 13:02:20 +0200
committerJoris Roovers <jroovers@cisco.com>2017-04-25 13:02:20 +0200
commitf45eb745561184cef63d9abfa3f951f1ae2505b1 (patch)
tree114805d3960ce712820128f0f50e119cec278352
parent644210c2b428e871da96d4fd98e433fa0d4dcbbd (diff)
Extra tests for --extra-path accepting file names + doc updates
Added some extra tests for the new PathOption which is used by --extra-path. Also added support for the 'file' type for PathOption's. Additional changes: - Moved LOGFORMAT to gitlint/utils.py because having it in gitlint/cli.py broke the ability to run individual test cases via run_tests.sh - Updated the CHANGELOG for the upcoming 0.8.2 release. - Updated docs based on changes in this commit
-rw-r--r--CHANGELOG.md13
-rw-r--r--docs/index.md38
-rw-r--r--docs/user_defined_rules.md2
-rw-r--r--gitlint/cli.py4
-rw-r--r--gitlint/options.py9
-rw-r--r--gitlint/tests/base.py12
-rw-r--r--gitlint/tests/test_cli.py10
-rw-r--r--gitlint/tests/test_options.py39
-rw-r--r--gitlint/tests/test_user_rules.py5
-rw-r--r--gitlint/user_rules.py2
-rw-r--r--gitlint/utils.py1
11 files changed, 96 insertions, 39 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6b5421d..e2b4c4f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog #
+## v0.8.1 (2017-04-25) ##
+
+The 0.8.2 release brings minor improvements, bugfixes and some under-the-hood changes. Special thanks to
+[tommyip](https://github.com/tommyip) for his contributions.
+- ```--extra-path``` now also accepts a file path (in the past only directory paths where accepted).
+Thanks to [tommyip](https://github.com/tommyip) for implementing this!
+- gitlint will now show more information when using the ```--debug``` flag. This is initial work and will continue to
+be improved upon in later releases.
+- Bugfixes:
+ - [#24: --commits doesn't take commit specific config into account](https://github.com/jorisroovers/gitlint/issues/24)
+ - [#27: --commits returns the wrong exit code](https://github.com/jorisroovers/gitlint/issues/27)
+- Development: better unit and integration test coverage for ```--commits```
+
## v0.8.1 (2017-03-16) ##
The 0.8.1 release brings minor tweaks and some experimental features. Special thanks to
diff --git a/docs/index.md b/docs/index.md
index ce1bc54..c1060f3 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -81,29 +81,29 @@ The default verbosity is ```-vvv```.
Other commands and variations:
-```
+```no-highlight
Usage: gitlint [OPTIONS] COMMAND [ARGS]...
Git lint tool, checks your git commit messages for styling issues
Options:
- --target DIRECTORY Path of the target git repository. [default:
- current working directory]
- -C, --config PATH Config file location [default: .gitlint]
- -c TEXT Config flags in format <rule>.<option>=<value>
- (e.g.: -c T1.line-length=80). Flag can be used
- multiple times to set multiple config values.
- --commits TEXT The range of commits to lint. [default: HEAD]
- -e, --extra-path DIRECTORY Path to a directory with extra user-defined
- rules
- --ignore TEXT Ignore rules (comma-separated by id or name).
- -v, --verbose Verbosity, more v's for more verbose output
- (e.g.: -v, -vv, -vvv). [default: -vvv]
- -s, --silent Silent mode (no output). Takes precedence over
- -v, -vv, -vvv.
- -d, --debug Enable debugging output.
- --version Show the version and exit.
- --help Show this message and exit.
+ --target DIRECTORY Path of the target git repository. [default: current
+ working directory]
+ -C, --config PATH Config file location [default: .gitlint]
+ -c TEXT Config flags in format <rule>.<option>=<value> (e.g.:
+ -c T1.line-length=80). Flag can be used multiple
+ times to set multiple config values.
+ --commits TEXT The range of commits to lint. [default: HEAD]
+ -e, --extra-path PATH Path to a directory or python module with extra user-
+ defined rules
+ --ignore TEXT Ignore rules (comma-separated by id or name).
+ -v, --verbose Verbosity, more v's for more verbose output (e.g.:
+ -v, -vv, -vvv). [default: -vvv]
+ -s, --silent Silent mode (no output). Takes precedence over -v,
+ -vv, -vvv.
+ -d, --debug Enable debugging output.
+ --version Show the version and exit.
+ --help Show this message and exit.
Commands:
generate-config Generates a sample gitlint config file.
@@ -154,7 +154,7 @@ future versions of gitlint might fix this.
## Linting a range of commits ##
_Experimental support introduced in gitlint v0.8.1, known issues:_
-_[#23](https://github.com/jorisroovers/gitlint/pull/23), [#24](https://github.com/jorisroovers/gitlint/pull/24)_
+_[#23](https://github.com/jorisroovers/gitlint/pull/23)_
Gitlint allows users to commit a number of commits at once like so:
diff --git a/docs/user_defined_rules.md b/docs/user_defined_rules.md
index f873bac..04e1c36 100644
--- a/docs/user_defined_rules.md
+++ b/docs/user_defined_rules.md
@@ -260,7 +260,7 @@ StrOption | Strings
IntOption | Integers. ```IntOption``` takes an optional ```allow_negative``` parameter if you want to allow negative integers.
BoolOption | Booleans. Valid values: true, false. Case-insensitive.
ListOption | List of strings. Comma separated.
-PathOption | Directory or file path. Takes an optional ```type``` parameter for specifying path type (```dir``` \| ```both```).
+PathOption | Directory or file path. Takes an optional ```type``` parameter for specifying path type (```file```, ```dir``` (=default) or ```both```).
!!! note
Gitlint currently does not support options for all possible types (e.g. float, filepath, list of int, etc).
diff --git a/gitlint/cli.py b/gitlint/cli.py
index 09daeb4..5955640 100644
--- a/gitlint/cli.py
+++ b/gitlint/cli.py
@@ -25,7 +25,7 @@ from gitlint.lint import GitLinter
from gitlint.config import LintConfigBuilder, LintConfigError, LintConfigGenerator
from gitlint.git import GitContext, GitContextError
from gitlint import hooks
-from gitlint.utils import ustr
+from gitlint.utils import ustr, LOG_FORMAT
DEFAULT_CONFIG_FILE = ".gitlint"
@@ -40,7 +40,7 @@ def setup_logging():
root_log = logging.getLogger("gitlint")
root_log.propagate = False # Don't propagate to child loggers, the gitlint root logger handles everything
handler = logging.StreamHandler()
- formatter = logging.Formatter('%(levelname)s: %(name)s %(message)s')
+ formatter = logging.Formatter(LOG_FORMAT)
handler.setFormatter(formatter)
root_log.addHandler(handler)
root_log.setLevel(logging.ERROR)
diff --git a/gitlint/options.py b/gitlint/options.py
index bff76f6..34bc389 100644
--- a/gitlint/options.py
+++ b/gitlint/options.py
@@ -90,7 +90,7 @@ class ListOption(RuleOption):
class PathOption(RuleOption):
""" Option that accepts either a directory or both a directory and a file. """
- def __init__(self, name, value, description, type='dir'):
+ def __init__(self, name, value, description, type=u"dir"):
self.type = type
super(PathOption, self).__init__(name, value, description)
@@ -102,11 +102,16 @@ class PathOption(RuleOption):
if self.type == 'dir':
if not os.path.isdir(value):
error_msg = u"Option {0} must be an existing directory (current value: '{1}')".format(self.name, value)
-
+ elif self.type == 'file':
+ if not os.path.isfile(value):
+ error_msg = u"Option {0} must be an existing file (current value: '{1}')".format(self.name, value)
elif self.type == 'both':
if not os.path.isdir(value) and not os.path.isfile(value):
error_msg = (u"Option {0} must be either an existing directory or file "
u"(current value: '{1}')").format(self.name, value)
+ else:
+ error_msg = u"Option {0} type must be one of: 'file', 'dir', 'both' (current: '{1}')".format(self.name,
+ self.type)
if error_msg:
raise RuleOptionError(error_msg)
diff --git a/gitlint/tests/base.py b/gitlint/tests/base.py
index fc48bc4..245105c 100644
--- a/gitlint/tests/base.py
+++ b/gitlint/tests/base.py
@@ -3,7 +3,7 @@ import os
import unittest2
from gitlint.git import GitContext
-from gitlint.utils import ustr
+from gitlint.utils import ustr, LOG_FORMAT
# unittest2's assertRaisesRegex doesn't do unicode comparison.
# Let's monkeypatch the str() function to point to unicode() so that it does :)
@@ -25,14 +25,16 @@ class BaseTestCase(unittest2.TestCase):
def setUp(self):
self.logcapture = LogCapture()
- # Make sure that the format used by our test logger is the same as used by gitlint itself
- formatter = logging.getLogger('gitlint').handlers[0].formatter
- self.logcapture.setFormatter(formatter)
+ self.logcapture.setFormatter(logging.Formatter(LOG_FORMAT))
logging.getLogger('gitlint').handlers = [self.logcapture]
@staticmethod
def get_sample_path(filename=""):
- return os.path.join(BaseTestCase.SAMPLES_DIR, filename)
+ # Don't join up empty files names because this will add a trailing slash
+ if filename == "":
+ return ustr(BaseTestCase.SAMPLES_DIR)
+
+ return ustr(os.path.join(BaseTestCase.SAMPLES_DIR, filename))
@staticmethod
def get_sample(filename=""):
diff --git a/gitlint/tests/test_cli.py b/gitlint/tests/test_cli.py
index dcfbe81..c385021 100644
--- a/gitlint/tests/test_cli.py
+++ b/gitlint/tests/test_cli.py
@@ -191,6 +191,7 @@ class CLITests(BaseTestCase):
def test_extra_path(self):
""" Test for --extra-path flag """
+ # Test extra-path pointing to a directory
with patch('gitlint.display.stderr', new=StringIO()) as stderr:
extra_path = self.get_sample_path("user_rules")
result = self.cli.invoke(cli.cli, ["--extra-path", extra_path, "--debug"], input=u"Test tïtle\n")
@@ -199,6 +200,15 @@ class CLITests(BaseTestCase):
self.assertEqual(stderr.getvalue(), expected_output)
self.assertEqual(result.exit_code, 2)
+ # Test extra-path pointing to a file
+ with patch('gitlint.display.stderr', new=StringIO()) as stderr:
+ extra_path = self.get_sample_path("user_rules/my_commit_rules.py")
+ result = self.cli.invoke(cli.cli, ["--extra-path", extra_path, "--debug"], input=u"Test tïtle\n")
+ expected_output = u"1: UC1 Commit violåtion 1: \"Contënt 1\"\n" + \
+ "3: B6 Body message is missing\n"
+ self.assertEqual(stderr.getvalue(), expected_output)
+ self.assertEqual(result.exit_code, 2)
+
def test_config_file(self):
""" Test for --config option """
with patch('gitlint.display.stderr', new=StringIO()) as stderr:
diff --git a/gitlint/tests/test_options.py b/gitlint/tests/test_options.py
index 7c5c16d..346bb0a 100644
--- a/gitlint/tests/test_options.py
+++ b/gitlint/tests/test_options.py
@@ -116,22 +116,51 @@ class RuleOptionTests(BaseTestCase):
option.set(123)
self.assertListEqual(option.value, ["123"])
- def test_dir_option(self):
- option = PathOption("test-directory", ".", u"Test Description")
+ def test_path_option(self):
+ option = PathOption("test-directory", ".", u"Test Description", type=u"dir")
self.assertEqual(option.value, os.getcwd())
self.assertEqual(option.name, "test-directory")
self.assertEqual(option.description, u"Test Description")
+ self.assertEqual(option.type, u"dir")
# re-set value
option.set(self.SAMPLES_DIR)
self.assertEqual(option.value, self.SAMPLES_DIR)
+ # set to int
+ expected = u"Option test-directory must be an existing directory \(current value: '1234'\)"
+ with self.assertRaisesRegex(RuleOptionError, expected):
+ option.set(1234)
+
# set to non-existing directory
expected = u"Option test-directory must be an existing directory \(current value: '/föo/bar'\)"
with self.assertRaisesRegex(RuleOptionError, expected):
option.set(u"/föo/bar")
- # set to int
- expected = u"Option test-directory must be an existing directory \(current value: '1234'\)"
+ # set to a file, should raise exception since option.type = dir
+ sample_path = self.get_sample_path("commit_message/sample1")
+ expected = u"Option test-directory must be an existing directory \(current value: '{0}'\)".format(sample_path)
with self.assertRaisesRegex(RuleOptionError, expected):
- option.set(1234)
+ option.set(sample_path)
+
+ # set option.type = file, file should now be accepted, directories not
+ option.type = u"file"
+ option.set(sample_path)
+ self.assertEqual(option.value, sample_path)
+ expected = u"Option test-directory must be an existing file \(current value: '{0}'\)".format(
+ self.get_sample_path())
+ with self.assertRaisesRegex(RuleOptionError, expected):
+ option.set(self.get_sample_path())
+
+ # set option.type = both, files and directories should now be accepted
+ option.type = u"both"
+ option.set(sample_path)
+ self.assertEqual(option.value, sample_path)
+ option.set(self.get_sample_path())
+ self.assertEqual(option.value, self.get_sample_path())
+
+ # Expect exception if path type is invalid
+ option.type = u'föo'
+ expected = u"Option test-directory type must be one of: 'file', 'dir', 'both' \(current: 'föo'\)"
+ with self.assertRaisesRegex(RuleOptionError, expected):
+ option.set("haha")
diff --git a/gitlint/tests/test_user_rules.py b/gitlint/tests/test_user_rules.py
index 0be4627..3c24b95 100644
--- a/gitlint/tests/test_user_rules.py
+++ b/gitlint/tests/test_user_rules.py
@@ -79,10 +79,7 @@ class UserRuleTests(BaseTestCase):
find_rule_classes(user_rule_path)
def test_find_rule_classes_nonexisting_path(self):
- # When searching an non-existing path, we expect an OSError. That's fine because this case will be caught by
- # the CLI (you cannot specify a non-existing directory). What we do here is just assert that we indeed
- # get an OSError (so we guard against regressions).
- with self.assertRaisesRegex(OSError, "No such file or directory"):
+ with self.assertRaisesRegex(UserRuleError, u"Invalid extra-path: föo/bar"):
find_rule_classes(u"föo/bar")
def test_assert_valid_rule_class(self):
diff --git a/gitlint/user_rules.py b/gitlint/user_rules.py
index a61d26f..b061b24 100644
--- a/gitlint/user_rules.py
+++ b/gitlint/user_rules.py
@@ -33,7 +33,7 @@ def find_rule_classes(extra_path):
files = os.listdir(extra_path)
directory = extra_path
else:
- raise OSError('No such file or directory')
+ raise UserRuleError(u"Invalid extra-path: {0}".format(extra_path))
# Filter out files that are not python modules
for filename in files:
diff --git a/gitlint/utils.py b/gitlint/utils.py
index 2f9ae3f..7a6fed4 100644
--- a/gitlint/utils.py
+++ b/gitlint/utils.py
@@ -4,6 +4,7 @@ import sys
from locale import getpreferredencoding
DEFAULT_ENCODING = getpreferredencoding() or "UTF-8"
+LOG_FORMAT = '%(levelname)s: %(name)s %(message)s'
def ustr(obj):