~bzr-pqm/bzr/bzr.dev

0.8.21 by John Arbash Meinel
Splitting up the version info code into a lazy factory style.
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
#
0.8.1 by John Arbash Meinel
Creating a plugin to ease generating version information from a tree.
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
0.8.21 by John Arbash Meinel
Splitting up the version info code into a lazy factory style.
7
#
0.8.1 by John Arbash Meinel
Creating a plugin to ease generating version information from a tree.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
0.8.21 by John Arbash Meinel
Splitting up the version info code into a lazy factory style.
12
#
0.8.1 by John Arbash Meinel
Creating a plugin to ease generating version information from a tree.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.8.1 by John Arbash Meinel
Creating a plugin to ease generating version information from a tree.
16
0.8.21 by John Arbash Meinel
Splitting up the version info code into a lazy factory style.
17
"""Routines for extracting all version information from a bzr branch."""
0.8.1 by John Arbash Meinel
Creating a plugin to ease generating version information from a tree.
18
19
import time
0.8.21 by John Arbash Meinel
Splitting up the version info code into a lazy factory style.
20
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
21
from bzrlib.osutils import local_time_offset, format_date
2948.4.2 by Lukáš Lalinský
Use registry for the list of formats. Documentation.
22
from bzrlib import registry
23
0.8.1 by John Arbash Meinel
Creating a plugin to ease generating version information from a tree.
24
0.8.13 by John Arbash Meinel
Including file-revisions fields, updated test suite.
25
def create_date_str(timestamp=None, offset=None):
26
    """Just a wrapper around format_date to provide the right format.
0.8.23 by John Arbash Meinel
whitespace and formatting cleanups.
27
0.8.13 by John Arbash Meinel
Including file-revisions fields, updated test suite.
28
    We don't want to use '%a' in the time string, because it is locale
29
    dependant. We also want to force timezone original, and show_offset
30
31
    Without parameters this function yields the current date in the local
32
    time zone.
33
    """
34
    if timestamp is None and offset is None:
35
        timestamp = time.time()
36
        offset = local_time_offset()
37
    return format_date(timestamp, offset, date_fmt='%Y-%m-%d %H:%M:%S',
38
                       timezone='original', show_offset=True)
39
0.8.4 by John Arbash Meinel
Cleaned up formats include-history always displays the log message.
40
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
41
class VersionInfoBuilder(object):
0.8.23 by John Arbash Meinel
whitespace and formatting cleanups.
42
    """A class which lets you build up information about a revision."""
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
43
44
    def __init__(self, branch, working_tree=None,
45
                check_for_clean=False,
46
                include_revision_history=False,
47
                include_file_revisions=False,
2948.4.3 by Lukáš Lalinský
Fix problems from Alexander's review.
48
                template=None):
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
49
        """Build up information about the given branch.
50
        If working_tree is given, it can be checked for changes.
51
52
        :param branch: The branch to work on
53
        :param working_tree: If supplied, preferentially check
54
            the working tree for changes.
55
        :param check_for_clean: If False, we will skip the expense
56
            of looking for changes.
57
        :param include_revision_history: If True, the output
58
            will include the full mainline revision history, including
59
            date and message
60
        :param include_file_revisions: The output should
61
            include the explicit last-changed revision for each file.
2948.4.3 by Lukáš Lalinský
Fix problems from Alexander's review.
62
        :param template: Template for the output formatting, not used by
63
            all builders.
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
64
        """
65
        self._branch = branch
66
        self._working_tree = working_tree
67
        self._check = check_for_clean
68
        self._include_history = include_revision_history
69
        self._include_file_revs = include_file_revisions
2948.4.1 by Lukáš Lalinský
Custom template-based version info formatter.
70
        self._template = template
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
71
72
        self._clean = None
73
        self._file_revisions = {}
74
        self._revision_history_info= []
75
76
    def _extract_file_revisions(self):
77
        """Extract the working revisions for all files"""
78
79
        # Things seem clean if we never look :)
80
        self._clean = True
81
82
        if self._working_tree is not None:
83
            basis_tree = self._working_tree.basis_tree()
2255.2.63 by John Arbash Meinel
track down a couple other places where we are using list_files.
84
            # TODO: jam 20070215 The working tree should actually be locked at
85
            #       a higher level, but this will do for now.
86
            self._working_tree.lock_read()
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
87
        else:
88
            basis_tree = self._branch.basis_tree()
89
2255.2.63 by John Arbash Meinel
track down a couple other places where we are using list_files.
90
        basis_tree.lock_read()
91
        try:
92
            # Build up the list from the basis inventory
93
            for info in basis_tree.list_files(include_root=True):
94
                self._file_revisions[info[0]] = info[-1].revision
95
96
            if not self._check or self._working_tree is None:
97
                return
98
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
99
            delta = self._working_tree.changes_from(basis_tree,
2255.2.63 by John Arbash Meinel
track down a couple other places where we are using list_files.
100
                                                    include_root=True)
101
102
            # Using a 2-pass algorithm for renames. This is because you might have
103
            # renamed something out of the way, and then created a new file
104
            # in which case we would rather see the new marker
105
            # Or you might have removed the target, and then renamed
106
            # in which case we would rather see the renamed marker
107
            for (old_path, new_path, file_id,
108
                 kind, text_mod, meta_mod) in delta.renamed:
109
                self._clean = False
110
                self._file_revisions[old_path] = u'renamed to %s' % (new_path,)
111
            for path, file_id, kind in delta.removed:
112
                self._clean = False
113
                self._file_revisions[path] = 'removed'
114
            for path, file_id, kind in delta.added:
115
                self._clean = False
116
                self._file_revisions[path] = 'new'
117
            for (old_path, new_path, file_id,
118
                 kind, text_mod, meta_mod) in delta.renamed:
119
                self._clean = False
120
                self._file_revisions[new_path] = u'renamed from %s' % (old_path,)
121
            for path, file_id, kind, text_mod, meta_mod in delta.modified:
122
                self._clean = False
123
                self._file_revisions[path] = 'modified'
124
125
            for path in self._working_tree.unknowns():
126
                self._clean = False
127
                self._file_revisions[path] = 'unversioned'
128
        finally:
129
            basis_tree.unlock()
130
            if self._working_tree is not None:
131
                self._working_tree.unlock()
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
132
133
    def _extract_revision_history(self):
134
        """Find the messages for all revisions in history."""
135
136
        # Unfortunately, there is no WorkingTree.revision_history
137
        rev_hist = self._branch.revision_history()
138
        if self._working_tree is not None:
139
            last_rev = self._working_tree.last_revision()
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
140
            if last_rev not in rev_hist:
141
                raise AssertionError(
142
                    "Working Tree's last revision not in branch.revision_history")
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
143
            rev_hist = rev_hist[:rev_hist.index(last_rev)+1]
144
145
        repository =  self._branch.repository
146
        repository.lock_read()
147
        try:
148
            for revision_id in rev_hist:
149
                rev = repository.get_revision(revision_id)
150
                self._revision_history_info.append(
151
                    (rev.revision_id, rev.message,
152
                     rev.timestamp, rev.timezone))
153
        finally:
154
            repository.unlock()
155
156
    def _get_revision_id(self):
157
        """Get the revision id we are working on."""
158
        if self._working_tree is not None:
159
            return self._working_tree.last_revision()
160
        return self._branch.last_revision()
161
5967.11.2 by Benoît Pierre
Update version-info formats to support dotted revnos.
162
    def _get_revno_str(self, revision_id):
163
        numbers = self._branch.revision_id_to_dotted_revno(revision_id)
164
        revno_str = '.'.join([str(num) for num in numbers])
165
        return revno_str
166
0.8.20 by John Arbash Meinel
Updated version-info to the latest bzr.dev codebase. Changed to using VersionInfoBuilder, and made tests pass.
167
    def generate(self, to_file):
168
        """Output the version information to the supplied file.
169
170
        :param to_file: The file to write the stream to. The output
171
                will already be encoded, so to_file should not try
172
                to change encodings.
173
        :return: None
174
        """
175
        raise NotImplementedError(VersionInfoBuilder.generate)
0.8.21 by John Arbash Meinel
Splitting up the version info code into a lazy factory style.
176
177
2948.4.2 by Lukáš Lalinský
Use registry for the list of formats. Documentation.
178
format_registry = registry.Registry()
179
180
181
format_registry.register_lazy(
182
    'rio',
183
    'bzrlib.version_info_formats.format_rio',
184
    'RioVersionInfoBuilder',
3231.1.1 by Wesley J. Landaker
Add some more text to the --rio option help in version-info.
185
    'Version info in RIO (simple text) format (default).')
2948.4.2 by Lukáš Lalinský
Use registry for the list of formats. Documentation.
186
format_registry.default_key = 'rio'
187
format_registry.register_lazy(
188
    'python',
189
    'bzrlib.version_info_formats.format_python',
190
    'PythonVersionInfoBuilder',
191
    'Version info in Python format.')
192
format_registry.register_lazy(
193
    'custom',
194
    'bzrlib.version_info_formats.format_custom',
195
    'CustomVersionInfoBuilder',
196
    'Version info in Custom template-based format.')