Convert update-copyright.py to a more modular framework.
[update-copyright.git] / update_copyright / vcs / git.py
1 # Copyright
2
3 from . import VCSBackend as _VCSBackend
4 from . import utils as _utils
5
6
7 class GitBackend (_VCSBackend):
8     name = 'Git'
9
10     @staticmethod
11     def _git_cmd(*args):
12         status,stdout,stderr = _utils.invoke(['git'] + list(args))
13         return stdout.rstrip('\n')
14
15     def __init__(self, **kwargs):
16         super(GitBackend, self).__init__(**kwargs)
17         self._version = self._git_cmd('--version').split(' ')[-1]
18         if self._version.startswith('1.5.'):
19             # Author name <author email>
20             self._author_format = '--pretty=format:%an <%ae>'
21             self._year_format = ['--pretty=format:%ai']  # Author date
22             # YYYY-MM-DD HH:MM:SS Z
23             # Earlier versions of Git don't seem to recognize --date=short
24         else:
25             self._author_format = '--pretty=format:%aN <%aE>'
26             self._year_format = ['--pretty=format:%ad',  # Author date
27                                  '--date=short']         # YYYY-MM-DD
28
29     def _years(self, filename=None):
30         args = ['log'] + self._year_format
31         if filename is not None:
32             args.extend(['--follow'] + [filename])
33         output = self._git_cmd(*args)
34         if self._version.startswith('1.5.'):
35             output = '\n'.join([x.split()[0] for x in output.splitlines()])
36         years = set(int(line.split('-', 1)[0]) for line in output.splitlines())
37         return years
38
39     def _authors(self, filename=None):
40         args = ['log', self._author_format]
41         if filename is not None:
42             args.extend(['--follow', filename])
43         output = self._git_cmd(*args)
44         authors = set(output.splitlines())
45         return authors
46
47     def is_versioned(self, filename):
48         output = self._git_cmd('log', '--follow', filename)
49         if len(output) == 0:
50             return False
51         return True