gitchangelog.gitchangelog module
- gitchangelog.gitchangelog.FileInsertAtFirstRegexMatch(filename, pattern, flags=0, idx=<function <lambda>>)[source]
- class gitchangelog.gitchangelog.GitCmd(repos)[source]
Bases:
SubGitObjectMixin
- class gitchangelog.gitchangelog.GitCommit(repos, identifier)[source]
Bases:
SubGitObjectMixin
Represent a Git Commit and expose through its attribute many information
Let’s create a fake GitRepos:
>>> from minimock import Mock >>> repos = Mock("gitRepos")
Initialization:
>>> repos.git = Mock("gitRepos.git") >>> repos.git.log.mock_returns_func = \ ... lambda *a, **kwargs: "\x00".join([{ ... 'sha1': "000000", ... 'sha1_short': "000", ... 'subject': SUBJECT, ... 'author_name': "John Smith", ... 'author_date': "Tue Feb 14 20:31:22 2017 +0700", ... 'author_email': "john.smith@example.com", ... 'author_date_timestamp': "0", ## epoch ... 'committer_name': "Alice Wang", ... 'committer_date_timestamp': "0", ## epoch ... 'raw_body': "my subject\n\n%s" % BODY, ... 'body': BODY, ... }[key] for key in GIT_FORMAT_KEYS.keys()]) >>> repos.git.rev_list.mock_returns = "123456"
Query, by attributes or items:
>>> SUBJECT = "fee fie foh" >>> BODY = "foo foo foo"
>>> head = GitCommit(repos, "HEAD") >>> head.subject Called gitRepos.git.log(...'HEAD'...) 'fee fie foh' >>> head.author_name 'John Smith'
Notice that on the second call, there’s no need to call again git log as all the values have already been computed.
Trailer
GitCommit
offers a simple direct API to trailer values. These are like RFC822’s header value but are at the end of body:>>> BODY = '''\ ... Stuff in the body ... Change-id: 1234 ... Value-X: Supports multi ... line values'''
>>> head = GitCommit(repos, "HEAD") >>> head.trailer_change_id Called gitRepos.git.log(...'HEAD'...) '1234' >>> head.trailer_value_x 'Supports multi\nline values'
Notice how the multi-line value was unindented. In case of multiple values, these are concatenated in lists:
>>> BODY = '''\ ... Stuff in the body ... Co-Authored-By: Bob ... Co-Authored-By: Alice ... Co-Authored-By: Jack ... '''
>>> head = GitCommit(repos, "HEAD") >>> head.trailer_co_authored_by Called gitRepos.git.log(...'HEAD'...) ['Bob', 'Alice', 'Jack']
Special values
Authors
>>> BODY = '''\ ... Stuff in the body ... Co-Authored-By: Bob ... Co-Authored-By: Alice ... Co-Authored-By: Jack ... '''
>>> head = GitCommit(repos, "HEAD") >>> head.author_names Called gitRepos.git.log(...'HEAD'...) ['Alice', 'Bob', 'Jack', 'John Smith']
Notice that they are printed in alphabetical order.
- property author_names
- property authors
- property date
- property has_annotated_tag
- property tagger_date
- property tagger_date_timestamp
- class gitchangelog.gitchangelog.GitConfig(repos)[source]
Bases:
SubGitObjectMixin
Interface to config values of git
Let’s create a fake GitRepos:
>>> from minimock import Mock >>> repos = Mock("gitRepos")
Initialization:
>>> cfg = GitConfig(repos)
Query, by attributes or items:
>>> repos.git.config.mock_returns = "bar" >>> cfg.foo Called gitRepos.git.config('foo') 'bar' >>> cfg["foo"] Called gitRepos.git.config('foo') 'bar' >>> cfg.get("foo") Called gitRepos.git.config('foo') 'bar' >>> cfg["foo.wiz"] Called gitRepos.git.config('foo.wiz') 'bar'
Notice that you can’t use attribute search in subsection as
cfg.foo.wiz
That’s because in git config files, you can have a value attached to an element, and this element can also be a section.Nevertheless, you can do:
>>> getattr(cfg, "foo.wiz") Called gitRepos.git.config('foo.wiz') 'bar'
Default values
get item, and getattr default values can be used:
>>> del repos.git.config.mock_returns >>> repos.git.config.mock_raises = ShellError('Key not found', ... errlvl=1, out="", err="")
>>> getattr(cfg, "foo", "default") Called gitRepos.git.config('foo') 'default'
>>> cfg["foo"] # Traceback (most recent call last): ... KeyError: 'foo'
>>> getattr(cfg, "foo") # Traceback (most recent call last): ... AttributeError...
>>> cfg.get("foo", "default") Called gitRepos.git.config('foo') 'default'
>>> print("%r" % cfg.get("foo")) Called gitRepos.git.config('foo') None
- class gitchangelog.gitchangelog.GitRepos(path)[source]
Bases:
object
- property config
- property git
- gitchangelog.gitchangelog.Indent(*a, **kw)
- class gitchangelog.gitchangelog.Phile(filename, buffersize=4096, encoding='utf-8')[source]
Bases:
object
File like API to read fields separated by any delimiters
It’ll take care of file decoding to unicode.
This is an adaptor on a file object.
>>> if PY3: ... from io import BytesIO ... def File(s): ... _obj = BytesIO() ... _obj.write(s.encode(_preferred_encoding)) ... _obj.seek(0) ... return _obj ... else: ... from cStringIO import StringIO as File
>>> f = Phile(File("a-b-c-d"))
Read provides an iterator:
>>> def show(l): ... print(", ".join(l)) >>> show(f.read(delimiter="-")) a, b, c, d
You can change the buffersize loaded into memory before outputing your changes. It should not change the iterator output:
>>> f = Phile(File("é-à-ü-d"), buffersize=3) >>> len(list(f.read(delimiter="-"))) 4
>>> f = Phile(File("foo-bang-yummy"), buffersize=3) >>> show(f.read(delimiter="-")) foo, bang, yummy
>>> f = Phile(File("foo-bang-yummy"), buffersize=1) >>> show(f.read(delimiter="-")) foo, bang, yummy
- gitchangelog.gitchangelog.ReSub(p, r, **k)
- gitchangelog.gitchangelog.SetIfEmpty(*a, **kw)
- exception gitchangelog.gitchangelog.ShellError(msg, errlvl=None, command=None, out=None, err=None)[source]
Bases:
Exception
- class gitchangelog.gitchangelog.SubGitObjectMixin(repos)[source]
Bases:
object
- property git
Simple delegation to
repos
original method.
- gitchangelog.gitchangelog.Wrap(*a, **kw)
- gitchangelog.gitchangelog.changelog(output_engine=<function rest_py>, unreleased_version_label='unreleased', warn=<function warn>, **kwargs)[source]
Returns a string containing the changelog of given repository
This function returns a string corresponding to the template rendered with the changelog data tree.
(see
gitchangelog.rc.sample
file for more info)For an exact list of arguments, see the arguments of
versions_data_iter(..)
.- Parameters:
unreleased_version_label – version label for untagged commits
output_engine – callable to render the changelog data
warn – callable to output warnings, mocked by tests
- Returns:
content of changelog
- gitchangelog.gitchangelog.ensure_template_file_exists(label, template_name)[source]
Return template file path given a label hint and the template name
Template name can be either a filename with full path, if this is the case, the label is of no use.
If
template_name
does not refer to an existing file, thenlabel
is used to find a template file in the the bundled ones.
- gitchangelog.gitchangelog.format_last_exception(prefix=' | ')[source]
Format the last exception for display it in tests.
This allows to raise custom exception, without loosing the context of what caused the problem in the first place:
>>> def f(): ... raise Exception("Something terrible happened") >>> try: # ... f() ... except Exception: ... formated_exception = format_last_exception() ... raise ValueError('Oops, an error occured:\n%s' ... % formated_exception) Traceback (most recent call last): ... ValueError: Oops, an error occured: | Traceback (most recent call last): ... | Exception: Something terrible happened
- gitchangelog.gitchangelog.indent(text, chars=' ', first=None)[source]
Return text string indented with the given chars
>>> string = 'This is first line.\nThis is second line\n'
>>> print(indent(string, chars="| ")) | This is first line. | This is second line |
>>> print(indent(string, first="- ")) - This is first line. This is second line
>>> string = 'This is first line.\n\nThis is second line' >>> print(indent(string, first="- ")) - This is first line. This is second line
- gitchangelog.gitchangelog.load_config_file(filename, default_filename=None, fail_if_not_present=True)[source]
Loads data from a config file.
- gitchangelog.gitchangelog.makotemplate(template_name)[source]
Return a callable that will render a changelog data structure
returned callable must take 2 arguments
data
andopts
.
- gitchangelog.gitchangelog.mustache(template_name)[source]
Return a callable that will render a changelog data structure
returned callable must take 2 arguments
data
andopts
.
- gitchangelog.gitchangelog.normpath(path, cwd=None)[source]
path can be absolute or relative, if relative it uses the cwd given as param.
- gitchangelog.gitchangelog.paragraph_wrap(text, regexp='\n\n')[source]
Wrap text by making sure that paragraph are separated correctly
>>> string = 'This is first paragraph which is quite long don\'t you \ ... think ? Well, I think so.\n\nThis is second paragraph\n'
>>> print(paragraph_wrap(string)) This is first paragraph which is quite long don't you think ? Well, I think so. This is second paragraph
Notice that that each paragraph has been wrapped separately.
- gitchangelog.gitchangelog.rest_py(data, opts=None)[source]
Returns ReStructured Text changelog content from data
- gitchangelog.gitchangelog.swrap(command, **kwargs)[source]
Same as
wrap(...)
but strips the output.
- gitchangelog.gitchangelog.versions_data_iter(repository, revlist=None, ignore_regexps=None, section_regexps=None, tag_filter_regexp='\\d+\\.\\d+(\\.\\d+)?', include_merge=True, body_process=<function <lambda>>, subject_process=<function <lambda>>, log_encoding='utf-8', warn=<function warn>)[source]
Returns an iterator through versions data structures
(see
gitchangelog.rc.reference
file for more info)- Parameters:
repository – target
GitRepos
objectrevlist – list of strings that git log understands as revlist
ignore_regexps – list of regexp identifying ignored commit messages
section_regexps – regexps identifying sections
tag_filter_regexp – regexp to match tags used as version
include_merge – whether to include merge commits in the log or not
body_process – text processing object to apply to body
subject_process – text processing object to apply to subject
log_encoding – the encoding used in git logs
warn – callable to output warnings, mocked by tests
- Returns:
iterator of versions data_structures
- gitchangelog.gitchangelog.wrap(command, ignore_errlvls=None, env=None, shell=True)[source]
Wraps a shell command and casts an exception on unexpected errlvl
>>> wrap('/tmp/lsdjflkjf') Traceback (most recent call last): ... ShellError: Wrapped command '/tmp/lsdjflkjf' exited with errorlevel 127. stderr: | /bin/sh: .../tmp/lsdjflkjf: not found
>>> print(wrap('echo hello'), end='') hello
>>> print(wrap('echo hello && false'), ... end='') Traceback (most recent call last): ... ShellError: Wrapped command 'echo hello && false' exited with errorlevel 1. stdout: | hello