diff options
author | Joris Roovers <jroovers@cisco.com> | 2016-12-03 17:48:26 +0100 |
---|---|---|
committer | Joris Roovers <jroovers@cisco.com> | 2016-12-03 17:48:26 +0100 |
commit | 2d323a9efcc9abda70316282545d5e505a83c1ac (patch) | |
tree | 3f0667d00e8f918faa61cb95a1af47b7dcc1e1dd | |
parent | dc24b5f2d10928fec5d87c8c2b3cd7daf6bcca57 (diff) |
Commit dates are now proper datetime objects
Previously, commit date objects were just represented by the string
returned by git. Now, commit.date is an actual python datetime object.
This did require us to include the arrow package as a dependency as
there are some issue with timezone-aware date parsing in python.
Also added __eq__ methods for GitCommit and GitCommitMessage as that
allows for easy comparison.
-rw-r--r-- | docs/user_defined_rules.md | 2 | ||||
-rw-r--r-- | gitlint/git.py | 21 | ||||
-rw-r--r-- | gitlint/tests/test_cli.py | 2 | ||||
-rw-r--r-- | gitlint/tests/test_git.py | 18 | ||||
-rw-r--r-- | qa/expected/debug_output1 | 2 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | setup.py | 1 |
7 files changed, 39 insertions, 8 deletions
diff --git a/docs/user_defined_rules.md b/docs/user_defined_rules.md index 1630104..6a142e7 100644 --- a/docs/user_defined_rules.md +++ b/docs/user_defined_rules.md @@ -169,7 +169,7 @@ commit.message.title | string | Title/subject of the commit message: commit.message.body | list of string | List of lines in the body of the commit message (i.e. starting from the second line) commit.author_name | string | Name of the author, result of ```git log --pretty=%aN``` commit.author_email | string | Email of the author, result of ```git log --pretty=%aE``` -commit.date | string | TODO: parse to date obj +commit.date | datetime | Python ```datetime``` object representing the time of commit commit.context | object | Object pointing to the bigger git context that the commit is part of commit.context.commits | list of commit | List of commits in the git context. Note that this might only be the subset of commits that gitlint is acting on, not all commits in the repo. diff --git a/gitlint/git.py b/gitlint/git.py index 923d6c3..a0de1b8 100644 --- a/gitlint/git.py +++ b/gitlint/git.py @@ -1,3 +1,4 @@ +import arrow import sh # import exceptions separately, this makes it a little easier to mock them out in the unit tests from sh import CommandNotFound, ErrorReturnCode @@ -37,6 +38,10 @@ class GitCommitMessage(object): def __repr__(self): return self.__str__() # pragma: no cover + def __eq__(self, other): + return self.original == other.original and self.full == other.full and \ + self.title == other.title and self.body == other.body # noqa + class GitCommit(object): """ Class representing a git commit. @@ -72,6 +77,11 @@ class GitCommit(object): def __repr__(self): return self.__str__() # pragma: no cover + def __eq__(self, other): + # skip checking the context as context refers back to this obj, this will trigger a cyclic dependency + return self.message == other.message and self.author_name == other.author_name and \ + self.author_email == other.autor_email and self.date == other.date # noqa + class GitContext(object): """ Class representing the git context in which gitlint is operating: a data object storing information about @@ -114,7 +124,8 @@ class GitContext(object): commit_msg = sh.git.log("-1", "--pretty=%B", **sh_special_args) commit_author_name = sh.git.log("-1", "--pretty=%aN", **sh_special_args) commit_author_email = sh.git.log("-1", "--pretty=%aE", **sh_special_args) - commit_date = sh.git.log("-1", "--pretty=%aD", **sh_special_args) + # %aI -> ISO 8601-like format, while %aI is strict ISO 8601, it seems to be less widely supporte + commit_date_str = sh.git.log("-1", "--pretty=%ai", **sh_special_args) commit_parents = sh.git.log("-1", "--pretty=%P", **sh_special_args).split(" ") commit_is_merge_commit = len(commit_parents) > 1 @@ -132,6 +143,11 @@ class GitContext(object): error_msg = "An error occurred while executing '{0}': {1}".format(e.full_cmd, error_msg) raise GitContextError(error_msg) + # "YYYY-MM-DD HH:mm:ss Z" -> ISO 8601-like format + # Use arrow for datetime parsing, because apparently python is quirky around ISO-8601 dates: + # http://stackoverflow.com/a/30696682/381010 + commit_date = arrow.get(str(commit_date_str), "YYYY-MM-DD HH:mm:ss Z").datetime + # Create Git commit object with the retrieved info changed_files = [changed_file for changed_file in changed_files_str.strip().split("\n")] commit_msg_obj = GitCommitMessage.from_full_message(commit_msg) @@ -143,3 +159,6 @@ class GitContext(object): context.commits.append(commit) return context + + def __eq__(self, other): + return self.commits == other.commits diff --git a/gitlint/tests/test_cli.py b/gitlint/tests/test_cli.py index 20f15c4..bff7bf1 100644 --- a/gitlint/tests/test_cli.py +++ b/gitlint/tests/test_cli.py @@ -37,7 +37,7 @@ class CLITests(BaseTestCase): def git_log_side_effect(*args, **_kwargs): return_values = {'--pretty=%B': "commit-title\n\ncommit-body", '--pretty=%aN': "test author", - '--pretty=%aE': "test-email@foo.com", '--pretty=%aD': "Mon Feb 29 22:19:39 2016 +0100", + '--pretty=%aE': "test-email@foo.com", '--pretty=%ai': "2016-12-03 15:28:15 01:00", '--pretty=%P': "abc"} return return_values[args[1]] diff --git a/gitlint/tests/test_git.py b/gitlint/tests/test_git.py index 91062ff..ab0a68d 100644 --- a/gitlint/tests/test_git.py +++ b/gitlint/tests/test_git.py @@ -1,3 +1,5 @@ +import datetime +import dateutil from mock import patch, call from sh import ErrorReturnCode, CommandNotFound @@ -10,7 +12,7 @@ class GitTests(BaseTestCase): def test_get_latest_commit(self, sh): def git_log_side_effect(*args, **_kwargs): return_values = {'--pretty=%B': "commit-title\n\ncommit-body", '--pretty=%aN': "test author", - '--pretty=%aE': "test-email@foo.com", '--pretty=%aD': "Mon Feb 29 22:19:39 2016 +0100", + '--pretty=%aE': "test-email@foo.com", '--pretty=%ai': "2016-12-03 15:28:15 01:00", '--pretty=%P': "abc"} return return_values[args[1]] @@ -26,7 +28,7 @@ class GitTests(BaseTestCase): expected_calls = [call('-1', '--pretty=%B', _cwd='fake/path', _tty_out=False), call('-1', '--pretty=%aN', _cwd='fake/path', _tty_out=False), call('-1', '--pretty=%aE', _cwd='fake/path', _tty_out=False), - call('-1', '--pretty=%aD', _cwd='fake/path', _tty_out=False), + call('-1', '--pretty=%ai', _cwd='fake/path', _tty_out=False), call('-1', '--pretty=%P', _cwd='fake/path', _tty_out=False)] self.assertListEqual(sh.git.log.mock_calls, expected_calls) @@ -36,6 +38,8 @@ class GitTests(BaseTestCase): self.assertEqual(last_commit.message.body, ["", "commit-body"]) self.assertEqual(last_commit.author_name, "test author") self.assertEqual(last_commit.author_email, "test-email@foo.com") + self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, + tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["abc"]) self.assertFalse(last_commit.is_merge_commit) @@ -48,7 +52,7 @@ class GitTests(BaseTestCase): def test_get_latest_commit_merge_commit(self, sh): def git_log_side_effect(*args, **_kwargs): return_values = {'--pretty=%B': "Merge \"foo bar commit\"", '--pretty=%aN': "test author", - '--pretty=%aE': "test-email@foo.com", '--pretty=%aD': "Mon Feb 29 22:19:39 2016 +0100", + '--pretty=%aE': "test-email@foo.com", '--pretty=%ai': "2016-12-03 15:28:15 01:00", '--pretty=%P': "abc def"} return return_values[args[1]] @@ -64,7 +68,7 @@ class GitTests(BaseTestCase): expected_calls = [call('-1', '--pretty=%B', _cwd='fake/path', _tty_out=False), call('-1', '--pretty=%aN', _cwd='fake/path', _tty_out=False), call('-1', '--pretty=%aE', _cwd='fake/path', _tty_out=False), - call('-1', '--pretty=%aD', _cwd='fake/path', _tty_out=False), + call('-1', '--pretty=%ai', _cwd='fake/path', _tty_out=False), call('-1', '--pretty=%P', _cwd='fake/path', _tty_out=False)] self.assertListEqual(sh.git.log.mock_calls, expected_calls) @@ -74,6 +78,8 @@ class GitTests(BaseTestCase): self.assertEqual(last_commit.message.body, []) self.assertEqual(last_commit.author_name, "test author") self.assertEqual(last_commit.author_email, "test-email@foo.com") + self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, + tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["abc", "def"]) self.assertTrue(last_commit.is_merge_commit) @@ -134,6 +140,7 @@ class GitTests(BaseTestCase): self.assertEqual(gitcontext.commits[-1].message.original, expected_original) self.assertEqual(gitcontext.commits[-1].author_name, None) self.assertEqual(gitcontext.commits[-1].author_email, None) + self.assertEqual(gitcontext.commits[-1].date, None) self.assertListEqual(gitcontext.commits[-1].parents, []) self.assertFalse(gitcontext.commits[-1].is_merge_commit) self.assertEqual(len(gitcontext.commits), 1) @@ -160,6 +167,7 @@ class GitTests(BaseTestCase): self.assertEqual(gitcontext.commits[-1].message.original, "") self.assertEqual(gitcontext.commits[-1].author_name, None) self.assertEqual(gitcontext.commits[-1].author_email, None) + self.assertEqual(gitcontext.commits[-1].date, None) self.assertListEqual(gitcontext.commits[-1].parents, []) self.assertFalse(gitcontext.commits[-1].is_merge_commit) self.assertEqual(len(gitcontext.commits), 1) @@ -173,6 +181,7 @@ class GitTests(BaseTestCase): self.assertEqual(gitcontext.commits[-1].message.original, "Title\n\nBody 1\n#Comment\nBody 2") self.assertEqual(gitcontext.commits[-1].author_name, None) self.assertEqual(gitcontext.commits[-1].author_email, None) + self.assertEqual(gitcontext.commits[-1].date, None) self.assertListEqual(gitcontext.commits[-1].parents, []) self.assertFalse(gitcontext.commits[-1].is_merge_commit) self.assertEqual(len(gitcontext.commits), 1) @@ -187,6 +196,7 @@ class GitTests(BaseTestCase): self.assertEqual(gitcontext.commits[-1].message.original, commit_msg) self.assertEqual(gitcontext.commits[-1].author_name, None) self.assertEqual(gitcontext.commits[-1].author_email, None) + self.assertEqual(gitcontext.commits[-1].date, None) self.assertListEqual(gitcontext.commits[-1].parents, []) self.assertTrue(gitcontext.commits[-1].is_merge_commit) self.assertEqual(len(gitcontext.commits), 1) diff --git a/qa/expected/debug_output1 b/qa/expected/debug_output1 index e9ac180..1867b4e 100644 --- a/qa/expected/debug_output1 +++ b/qa/expected/debug_output1 @@ -1,5 +1,5 @@ [GENERAL] -config path: /vagrant/qa/samples/config/gitlintconfig +config path: {config_path} extra path: None ignore merge commits: True verbosity: 2 diff --git a/requirements.txt b/requirements.txt index 830b530..df05267 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,6 @@ setuptools wheel==0.24.0 Click==6.6 sh==1.11 +arrow==0.10.0 ordereddict==1.1 importlib==1.0.3; python_version < '2.7'
\ No newline at end of file @@ -59,6 +59,7 @@ setup( install_requires=[ 'Click==6.6', 'sh==1.11', + 'arrow==0.10.0', 'ordereddict==1.1', ], extras_require={ |