~ubuntu-branches/debian/sid/bzr-builddeb/sid

« back to all changes in this revision

Viewing changes to dep3.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij, Jelmer Vernooij, Jonathan Riddell, Scott Kitterman
  • Date: 2011-07-15 12:15:22 UTC
  • Revision ID: james.westby@ubuntu.com-20110715121522-avtc0uc3uuzcg7zn
Tags: 2.7.5
[ Jelmer Vernooij ]
* New 'bzr dep3-patch' subcommand that can generate DEP-3 compliant
  patches. LP: #460576

[ Jonathan Riddell ]
* Use new set_commit_message() hook in bzr to set the commit
  message from debian/changelog and set fixed bugs in tags. LP: #707274

[ Jelmer Vernooij ]
* Add dependency on devscripts >= 2.10.59, required now that 'dch --
  package' is used. LP: #783122
* Fix support for native packages with dashes in their version in
  sources.list. LP: #796853
* Fix deprecation warnings for TestCase.failUnlessExists and
  TestCase.failIfExists in bzr 2.4.

[ Scott Kitterman ]
* Delete debian/bzr-builddeb.dirs so the long obsolete and empty
  /usr/lib/python2.4/site-packages/bzrlib/plugins/bzr-builddeb/ is no
  longer created. Closes: #631564

[ Jelmer Vernooij ]
* Add support for xz and lzma tarballs. LP: #553668
* When importing upstream component tarballs, don't repack bz2/lzma
  tarballs to gz if the package is in v3 source format. LP: #810531

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#    dep3.py -- DEP-3 compatible patch formatting
 
2
#    Copyright (C) 2011 Canonical Ltd.
 
3
#
 
4
#    This file is part of bzr-builddeb.
 
5
#
 
6
#    bzr-builddeb is free software; you can redistribute it and/or modify
 
7
#    it under the terms of the GNU General Public License as published by
 
8
#    the Free Software Foundation; either version 2 of the License, or
 
9
#    (at your option) any later version.
 
10
#
 
11
#    bzr-builddeb is distributed in the hope that it will be useful,
 
12
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
#    GNU General Public License for more details.
 
15
#
 
16
#    You should have received a copy of the GNU General Public License
 
17
#    along with bzr-builddeb; if not, write to the Free Software
 
18
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
#
 
20
 
 
21
"""DEP-3 style patch formatting."""
 
22
 
 
23
from bzrlib import diff
 
24
 
 
25
import time
 
26
 
 
27
 
 
28
def write_dep3_bug_line(f, bug_url, status):
 
29
    """Write a DEP-3 compatible line with a bug link.
 
30
 
 
31
    :param f: File-like object to write to
 
32
    :param bug_url: Bug URL
 
33
    :param status: Bug status (e.g. "fixed")
 
34
    """
 
35
    # For the moment, we only care about fixed bugs
 
36
    if status != "fixed":
 
37
        return
 
38
    if bug_url.startswith("http://bugs.debian.org/"):
 
39
        f.write("Bug-Debian: %s\n" % bug_url)
 
40
    else:
 
41
        # FIXME: Filter out Ubuntu bugs on Launchpad
 
42
        f.write("Bug: %s\n" % bug_url)
 
43
 
 
44
 
 
45
def write_dep3_patch_header(f, description=None, origin=None, forwarded=None,
 
46
        bugs=None, authors=None, revision_id=None, last_update=None,
 
47
        applied_upstream=None):
 
48
    """Write a DEP3 patch header.
 
49
 
 
50
    :param f: File-like object to write to
 
51
    :param description: Description of the patch
 
52
    :param origin: Single line describing the origin of the patch
 
53
    :param forwarded: Single line describing whether and how the patch was
 
54
        forwarded
 
55
    :param bugs: Set of bugs fixed in this patch
 
56
    :param authors: Authors of the patch
 
57
    :param revision_id: Relevant bzr revision id
 
58
    :param last_update: Last update timestamp
 
59
    :param applied_upstream: If the patch is applied upstream,
 
60
        an informal string describing where it was merged
 
61
    """
 
62
    # FIXME: Handle line breaks, etc sensibly
 
63
    if description is not None:
 
64
        description = description.strip("\n")
 
65
        description = description.replace("\n\n", "\n.\n")
 
66
        description = description.replace("\n", "\n ")
 
67
        f.write("Description: %s\n" % description)
 
68
    if origin is not None:
 
69
        f.write("Origin: %s\n" % origin)
 
70
    if forwarded is not None:
 
71
        f.write("Forwarded: %s\n" % forwarded)
 
72
    if authors is not None:
 
73
        for author in authors:
 
74
            f.write("Author: %s\n" % author)
 
75
    if bugs is not None:
 
76
        for bug_url, status in bugs:
 
77
            write_dep3_bug_line(f, bug_url, status)
 
78
    if last_update is not None:
 
79
        f.write("Last-Update: %s\n" % time.strftime("%Y-%m-%d",
 
80
            time.gmtime(last_update)))
 
81
    if applied_upstream is not None:
 
82
        f.write("Applied-Upstream: %s\n" % applied_upstream)
 
83
    if revision_id is not None:
 
84
        f.write("X-Bzr-Revision-Id: %s\n" % revision_id)
 
85
    f.write("\n")
 
86
 
 
87
 
 
88
def gather_bugs_and_authors(repository, interesting_revision_ids):
 
89
    """Gather bug and author information from revisions.
 
90
 
 
91
    :param interesting_revision_ids: Iterable of revision ids to check
 
92
    :return: Tuple of bugs, authors and highest found commit timestamp
 
93
    """
 
94
    authors = set()
 
95
    bugs = set()
 
96
    last_update = None
 
97
    for rev in repository.get_revisions(interesting_revision_ids):
 
98
        last_update = max(rev.timestamp, last_update)
 
99
        authors.update(rev.get_apparent_authors())
 
100
        bugs.update(rev.iter_bugs())
 
101
    return (bugs, authors, last_update)
 
102
 
 
103
 
 
104
def determine_applied_upstream(upstream_branch, feature_branch, feature_revid=None):
 
105
    """Check if a particular revision has been merged upstream.
 
106
 
 
107
    :param upstream_branch: Upstream branch object
 
108
    :param feature_branch: Feature branch
 
109
    :param feature_revid: Revision id in feature branch to check,
 
110
        defaults to feature_branch tip.
 
111
    :return: String that can be used for Applied-Upstream field
 
112
    """
 
113
    if feature_revid is None:
 
114
        feature_revid = feature_branch.last_revision()
 
115
    upstream_graph = feature_branch.repository.get_graph(upstream_branch.repository)
 
116
    merger = upstream_graph.find_lefthand_merger(feature_revid,
 
117
        upstream_branch.last_revision())
 
118
    if merger is not None:
 
119
        return "merged in revision %s" % (
 
120
            ".".join(str(x) for x in upstream_branch.revision_id_to_dotted_revno(merger)), )
 
121
    else:
 
122
        return "no"
 
123
 
 
124
 
 
125
def determine_forwarded(upstream_branch, feature_branch, feature_revid):
 
126
    """See if a branch has been forwarded to upstream.
 
127
 
 
128
    :param upstream_branch: Upstream branch object
 
129
    :param feature_branch: Feature branch
 
130
    :param feature_revid: Revision id in feature branch to check
 
131
    :return: String that can be used for Applied-Upstream field
 
132
    """
 
133
    # FIXME: Check for Launchpad merge proposals from feature_branch (or its
 
134
    # public_branch) to upstream_branch
 
135
 
 
136
    # Are there any other ways to see that a patch has been forwarded upstream?
 
137
    return None
 
138
 
 
139
 
 
140
def describe_origin(branch, revid):
 
141
    """Describe a tree for use in the origin field.
 
142
 
 
143
    :param branch: Branch to retrieve the revision from
 
144
    :param revid: Revision id
 
145
    """
 
146
    public_branch_url = branch.get_public_branch()
 
147
    if public_branch_url is not None:
 
148
        return "commit, %s, revision: %s" % (
 
149
            public_branch_url,
 
150
            ".".join(str(x) for x in branch.revision_id_to_dotted_revno(revid)), )
 
151
    else:
 
152
        return "commit, revision id: %s" % revid
 
153
 
 
154
 
 
155
def write_dep3_patch(f, branch, base_revid, target_revid, description=None,
 
156
        origin=None, forwarded=None, applied_upstream=None, bugs=None,
 
157
        authors=None, last_update=None):
 
158
    """Write a DEP-3 compliant patch.
 
159
 
 
160
    :param f: File-like object to write to
 
161
    :param repository: Repository to retrieve revisions from
 
162
    :param base_revid: Base revision id
 
163
    :param target_revid: Target revision id
 
164
    :param description: Optional description
 
165
    :param forwarded: Optional information on if/how the patch was forwarded
 
166
    :param applied_upstream: Optional information on how whether the patch
 
167
        was merged upstream
 
168
    :param bugs: Sequence of bug reports related to this patch
 
169
    :param authors: Sequence of authors of this patch
 
170
    :param last_update: Timestamp for last time this patch was updated
 
171
    """
 
172
    write_dep3_patch_header(f, bugs=bugs, authors=authors, last_update=last_update,
 
173
            description=description, revision_id=target_revid, origin=origin,
 
174
            applied_upstream=applied_upstream, forwarded=forwarded)
 
175
    old_tree = branch.repository.revision_tree(base_revid)
 
176
    new_tree = branch.repository.revision_tree(target_revid)
 
177
    diff.show_diff_trees(old_tree, new_tree, f, old_label='old/', new_label='new/')