File: changelog.py

package info (click to toggle)
breezy-debian 2.8.81
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,448 kB
  • sloc: python: 19,137; makefile: 61; sh: 1
file content (125 lines) | stat: -rw-r--r-- 4,173 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#    __init__.py -- The plugin for bzr
#    Copyright (C) 2009-2018 Jelmer Vernooij <jelmer@jelmer.uk
#
#    This file is part of brz-debian.
#
#    brz-debian is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    brz-debian is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with brz-debian; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

import posixpath
from typing import Optional

from breezy.errors import BzrError
from breezy.tree import Tree
from debian.changelog import Changelog
from debmutate.changelog import new_changelog_entries, strip_changelog_message

from . import tree_debian_tag_name


class UnreleasedChanges(BzrError):
    _fmt = "%(path)s says it's UNRELEASED."

    def __init__(self, path):
        BzrError.__init__(self)
        self.path = path


def changelog_changes(
    tree: Tree, basis_tree: Tree, cl_path: str = "debian/changelog"
) -> list[str]:
    changes = []
    for change in tree.iter_changes(basis_tree, specific_files=[cl_path]):
        paths = change.path
        changed_content = change.changed_content
        versioned = change.versioned
        kind = change.kind
        # Content not changed
        if not changed_content:
            return None
        # Not versioned in new tree
        if not versioned[1]:
            return None
        # Not a file in one tree
        if kind[0] != "file" or kind[1] != "file":
            return None

        old_text = basis_tree.get_file_lines(paths[0])
        new_text = tree.get_file_lines(paths[1])
        changes.extend(new_changelog_entries(old_text, new_text))
    return changes


def changelog_commit_message(
    tree: Tree, basis_tree: Tree, path: str = "debian/changelog"
) -> Optional[str]:
    changes = changelog_changes(tree, basis_tree, path)
    if not changes:
        return None

    return "".join(strip_changelog_message(changes))


def debcommit(
    tree, committer=None, subpath="", paths=None, reporter=None, message=None
):
    """Create a git commit with message based on the new entries in changelog.

    Args:
      tree: Tree to commit in
      committer: Optional committer identity
      subpath: subpath to commit in
      paths: specifics paths to commit, if any
      reporter: CommitReporter to use
      message: Override commit message
    Returns:
      Created revision id
    """
    if message is None:
        message = changelog_commit_message(
            tree, tree.basis_tree(), path=posixpath.join(subpath, "debian/changelog")
        )
    if paths:
        specific_files = [posixpath.join(subpath, p) for p in paths]
    elif subpath:
        specific_files = [subpath]
    else:
        specific_files = None
    return tree.commit(
        committer=committer,
        message=message,
        specific_files=specific_files,
        reporter=reporter,
    )


def debcommit_release(tree, committer=None, subpath="", message=None, vendor=None):
    cl_path = posixpath.join(subpath, "debian/changelog")
    if message is None or vendor is None:
        cl = Changelog(tree.get_file(cl_path), max_blocks=1)
        if message is None:
            message = "releasing package {} version {}".format(
                cl[0].package, cl[0].version
            )
        if vendor is None:
            from .util import suite_to_distribution

            vendor = suite_to_distribution(cl[0].distributions)
    tag_name = tree_debian_tag_name(tree, tree.branch, subpath=subpath, vendor=vendor)
    if tag_name is None:
        raise UnreleasedChanges(cl_path)
    revid = tree.commit(committer=committer, message=message)
    tree.branch.tags.set_tag(tag_name, revid)
    return tag_name