/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to backend/info.py

  • Committer: Szilveszter Farkas (Phanatic)
  • Date: 2006-07-08 17:36:59 UTC
  • mto: (0.14.1 main) (93.1.1 win32.bialix)
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: Szilveszter.Farkas@gmail.com-20060708173659-8ab442681dadd8ea
2006-07-08  Szilveszter Farkas <Szilveszter.Farkas@gmail.com>

    * backend/errors.py: added some exceptions related to diff() and log()
    * backend/info.py: implemented log()
    * backend/info.py: diff() works well with revnos
    * added e-mail address to copyright header

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
 
2
# Some parts of the code are:
 
3
# Copyright (C) 2005, 2006 by Canonical Ltd
 
4
 
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation; either version 2 of the License, or
 
8
# (at your option) any later version.
 
9
 
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
 
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
import bzrlib
 
20
import bzrlib.errors as errors
 
21
 
 
22
from bzrlib.branch import Branch
 
23
 
 
24
from errors import (DifferentBranchesError, NotBranchError, PrefixFormatError,
 
25
                    RevisionValueError)
 
26
 
 
27
def diff(revision=None, file_list=None, diff_options=None, prefix=None):
 
28
    """ Save the diff into a temporary file.
 
29
    
 
30
    :param revision: a list of revision numbers (one or two elements)
 
31
    
 
32
    :param file_list: list of files you want to diff
 
33
    
 
34
    :param diff_options: external diff options
 
35
    
 
36
    :param prefix: 0 - p0, 1 - p1, or specify prefixes in the form of old/:new/
 
37
    
 
38
    :return: path to the temporary file which contains the diff output (the frontend has to remove it!)
 
39
    """
 
40
    from tempfile import mkstemp
 
41
    
 
42
    from bzrlib.builtins import internal_tree_files
 
43
    from bzrlib.diff import show_diff_trees
 
44
    from bzrlib.revisionspec import RevisionSpec_int
 
45
    from bzrlib.workingtree import WorkingTree
 
46
    
 
47
    from info_helper import diff_helper
 
48
 
 
49
    if (prefix is None) or (prefix == '0'):
 
50
        # diff -p0 format
 
51
        old_label = ''
 
52
        new_label = ''
 
53
    elif prefix == '1':
 
54
        old_label = 'old/'
 
55
        new_label = 'new/'
 
56
    else:
 
57
        if not ':' in prefix:
 
58
            raise PrefixFormatError
 
59
        old_label, new_label = prefix.split(":")
 
60
    
 
61
    try:
 
62
        tree1, file_list = internal_tree_files(file_list)
 
63
        tree2 = None
 
64
        b = None
 
65
        b2 = None
 
66
    except errors.FileInWrongBranch:
 
67
        if len(file_list) != 2:
 
68
            raise DifferentBranchesError
 
69
 
 
70
        tree1, file1 = WorkingTree.open_containing(file_list[0])
 
71
        tree2, file2 = WorkingTree.open_containing(file_list[1])
 
72
    
 
73
        if file1 != "" or file2 != "":
 
74
            raise DifferentBranchesError
 
75
    
 
76
        file_list = None
 
77
    
 
78
    tmpfile = mkstemp(prefix='olive_')
 
79
    tmpfp = open(tmpfile[1], 'w')
 
80
    
 
81
    if revision is not None:
 
82
        if tree2 is not None:
 
83
            raise RevisionValueError
 
84
    
 
85
        if len(revision) >= 1:
 
86
            revision[0] = RevisionSpec_int(revision[0])
 
87
        if len(revision) == 2:
 
88
            revision[1] = RevisionSpec_int(revision[1])
 
89
        
 
90
        if (len(revision) == 1) or (revision[1].spec is None):
 
91
            ret = diff_helper(tree1, file_list, diff_options,
 
92
                              revision[0], 
 
93
                              old_label=old_label, new_label=new_label,
 
94
                              output=tmpfp)
 
95
        elif len(revision) == 2:
 
96
            ret = diff_helper(tree1, file_list, diff_options,
 
97
                              revision[0], revision[1],
 
98
                              old_label=old_label, new_label=new_label,
 
99
                              output=tmpfp)
 
100
        else:
 
101
            raise RevisionValueError
 
102
    else:
 
103
        if tree2 is not None:
 
104
            ret = show_diff_trees(tree1, tree2, tmpfp, 
 
105
                                  specific_files=file_list,
 
106
                                  external_diff_options=diff_options,
 
107
                                  old_label=old_label, new_label=new_label)
 
108
        else:
 
109
            ret = diff_helper(tree1, file_list, diff_options,
 
110
                              old_label=old_label, new_label=new_label,
 
111
                              output=tmpfp)
 
112
    
 
113
    tmpfp.close()
 
114
    
 
115
    if ret == 0:
 
116
        return False
 
117
    else:
 
118
        return tmpfile[1]
 
119
 
 
120
def info(location):
 
121
    """ Get info about branch, working tree, and repository
 
122
    
 
123
    :param location: the location of the branch/working tree/repository
 
124
    
 
125
    :return: the information in dictionary format
 
126
    
 
127
    The following informations are delivered (if available):
 
128
    ret['location']['lightcoroot']: Light checkout root
 
129
    ret['location']['sharedrepo']: Shared repository
 
130
    ret['location']['repobranch']: Repository branch
 
131
    ret['location']['cobranch']: Checkout of branch
 
132
    ret['location']['repoco']: Repository checkout
 
133
    ret['location']['coroot']: Checkout root
 
134
    ret['location']['branchroot']: Branch root
 
135
    ret['related']['parentbranch']: Parent branch
 
136
    ret['related']['publishbranch']: Publish to branch
 
137
    ret['format']['control']: Control format
 
138
    ret['format']['workingtree']: Working tree format
 
139
    ret['format']['branch']: Branch format
 
140
    ret['format']['repository']: Repository format
 
141
    ret['locking']['workingtree']: Working tree lock status
 
142
    ret['locking']['branch']: Branch lock status
 
143
    ret['locking']['repository']: Repository lock status
 
144
    ret['mrevbranch']['missing']: Missing revisions in branch
 
145
    ret['mrevworking']['missing']: Missing revisions in working tree
 
146
    ret['wtstats']['unchanged']: Unchanged files
 
147
    ret['wtstats']['modified']: Modified files
 
148
    ret['wtstats']['added']: Added files
 
149
    ret['wtstats']['removed']: Removed files
 
150
    ret['wtstats']['renamed']: Renamed files
 
151
    ret['wtstats']['unknown']: Unknown files
 
152
    ret['wtstats']['ignored']: Ingnored files
 
153
    ret['wtstats']['subdirs']: Versioned subdirectories
 
154
    ret['brstats']['revno']: Revisions in branch
 
155
    ret['brstats']['commiters']: Number of commiters
 
156
    ret['brstats']['age']: Age of branch in days
 
157
    ret['brstats']['firstrev']: Time of first revision
 
158
    ret['brstats']['lastrev']: Time of last revision
 
159
    ret['repstats']['revisions']: Revisions in repository
 
160
    ret['repstats']['size']: Size of repository in bytes
 
161
    """
 
162
    import bzrlib.bzrdir as bzrdir
 
163
    
 
164
    import info_helper
 
165
    
 
166
    ret = {}
 
167
    a_bzrdir = bzrdir.BzrDir.open_containing(location)[0]
 
168
    try:
 
169
        working = a_bzrdir.open_workingtree()
 
170
        working.lock_read()
 
171
        try:
 
172
            branch = working.branch
 
173
            repository = branch.repository
 
174
            control = working.bzrdir
 
175
 
 
176
            ret['location'] = info_helper.get_location_info(repository, branch, working)
 
177
            ret['related'] = info_helper.get_related_info(branch)
 
178
            ret['format'] = info_helper.get_format_info(control, repository, branch, working)
 
179
            ret['locking'] = info_helper.get_locking_info(repository, branch, working)
 
180
            ret['mrevbranch'] = info_helper.get_missing_revisions_branch(branch)
 
181
            ret['mrevworking'] = info_helper.get_missing_revisions_working(working)
 
182
            ret['wtstats'] = info_helper.get_working_stats(working)
 
183
            ret['brstats'] = info_helper.get_branch_stats(branch)
 
184
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
185
        finally:
 
186
            working.unlock()
 
187
            return ret
 
188
        return
 
189
    except (errors.NoWorkingTree, errors.NotLocalUrl):
 
190
        pass
 
191
 
 
192
    try:
 
193
        branch = a_bzrdir.open_branch()
 
194
        branch.lock_read()
 
195
        try:
 
196
            ret['location'] = info_helper.get_location_info(repository, branch)
 
197
            ret['related'] = info_helper.get_related_info(branch)
 
198
            ret['format'] = info_helper.get_format_info(control, repository, branch)
 
199
            ret['locking'] = info_helper.get_locking_info(repository, branch)
 
200
            ret['mrevbranch'] = info_helper.get_missing_revisions_branch(branch)
 
201
            ret['brstats'] = info_helper.get_branch_stats(branch)
 
202
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
203
        finally:
 
204
            branch.unlock()
 
205
            return ret
 
206
        return
 
207
    except errors.NotBranchError:
 
208
        pass
 
209
 
 
210
    try:
 
211
        repository = a_bzrdir.open_repository()
 
212
        repository.lock_read()
 
213
        try:
 
214
            ret['location'] = info_helper.get_location_info(repository)
 
215
            ret['format'] = info_helper.get_format_info(control, repository)
 
216
            ret['locking'] = info_helper.get_locking_info(repository)
 
217
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
218
        finally:
 
219
            repository.unlock()
 
220
            return ret
 
221
        return
 
222
    except errors.NoRepositoryPresent:
 
223
        pass
 
224
 
 
225
def log(location, timezone='original', verbose=False, show_ids=False,
 
226
        forward=False, revision=None, log_format=None, message=None,
 
227
        long=False, short=False, line=False):
 
228
    """ Print log into a temporary file.
 
229
    
 
230
    :param location: location of local/remote branch or file
 
231
    
 
232
    :param timzone: requested timezone
 
233
    
 
234
    :param verbose: verbose output
 
235
    
 
236
    :param show_ids:
 
237
    
 
238
    :param forward: if True, start from the earliest entry
 
239
    
 
240
    :param revision: revision range as a list ([from, to])
 
241
    
 
242
    :param log_format: line, short, long
 
243
    
 
244
    :param message: show revisions whose message matches this regexp
 
245
    
 
246
    :param long: long log format
 
247
    
 
248
    :param short: short log format
 
249
    
 
250
    :param line: line log format
 
251
    
 
252
    :return: full path to the temporary file containing the log (the frontend has to remove it!)
 
253
    """
 
254
    from tempfile import mkstemp
 
255
    
 
256
    from bzrlib import bzrdir    
 
257
    from bzrlib.builtins import get_log_format
 
258
    from bzrlib.log import log_formatter, show_log
 
259
    from bzrlib.revisionspec import RevisionSpec_int
 
260
    
 
261
    assert message is None or isinstance(message, basestring), \
 
262
        "invalid message argument %r" % message
 
263
    direction = (forward and 'forward') or 'reverse'
 
264
        
 
265
    # log everything
 
266
    file_id = None
 
267
    
 
268
    # find the file id to log:
 
269
    dir, fp = bzrdir.BzrDir.open_containing(location)
 
270
    b = dir.open_branch()
 
271
    if fp != '':
 
272
        try:
 
273
            # might be a tree:
 
274
            inv = dir.open_workingtree().inventory
 
275
        except (errors.NotBranchError, errors.NotLocalUrl):
 
276
            # either no tree, or is remote.
 
277
            inv = b.basis_tree().inventory
 
278
        file_id = inv.path2id(fp)
 
279
 
 
280
    if revision is not None:
 
281
        if len(revision) >= 1:
 
282
            revision[0] = RevisionSpec_int(revision[0])
 
283
        if len(revision) == 2:
 
284
            revision[1] = RevisionSpec_int(revision[1])
 
285
    
 
286
    if revision is None:
 
287
        rev1 = None
 
288
        rev2 = None
 
289
    elif len(revision) == 1:
 
290
        rev1 = rev2 = revision[0].in_history(b).revno
 
291
    elif len(revision) == 2:
 
292
        if revision[0].spec is None:
 
293
            # missing begin-range means first revision
 
294
            rev1 = 1
 
295
        else:
 
296
            rev1 = revision[0].in_history(b).revno
 
297
 
 
298
        if revision[1].spec is None:
 
299
            # missing end-range means last known revision
 
300
            rev2 = b.revno()
 
301
        else:
 
302
            rev2 = revision[1].in_history(b).revno
 
303
    else:
 
304
        raise RevisionValueError
 
305
 
 
306
    # By this point, the revision numbers are converted to the +ve
 
307
    # form if they were supplied in the -ve form, so we can do
 
308
    # this comparison in relative safety
 
309
    if rev1 > rev2:
 
310
        (rev2, rev1) = (rev1, rev2)
 
311
 
 
312
    if (log_format == None):
 
313
        default = b.get_config().log_format()
 
314
        log_format = get_log_format(long=long, short=short, line=line, 
 
315
                                    default=default)
 
316
    
 
317
    tmpfile = mkstemp(prefix='olive_')
 
318
    tmpfp = open(tmpfile[1], 'w')
 
319
    
 
320
    lf = log_formatter(log_format,
 
321
                       show_ids=show_ids,
 
322
                       to_file=tmpfp,
 
323
                       show_timezone=timezone)
 
324
 
 
325
    show_log(b,
 
326
             lf,
 
327
             file_id,
 
328
             verbose=verbose,
 
329
             direction=direction,
 
330
             start_revision=rev1,
 
331
             end_revision=rev2,
 
332
             search=message)
 
333
    
 
334
    tmpfp.close()
 
335
    return tmpfile[1]
 
336
 
 
337
def nick(branch, nickname=None):
 
338
    """ Get or set nickname.
 
339
    
 
340
    :param branch: path to the branch
 
341
    
 
342
    :param nickname: if specified, the nickname will be set
 
343
    
 
344
    :return: nickname
 
345
    """
 
346
    try:
 
347
        branch = Branch.open_containing(branch)[0]
 
348
    except errors.NotBranchError:
 
349
        raise NotBranchError
 
350
    
 
351
    if nickname is not None:
 
352
        branch.nick = nickname
 
353
 
 
354
    return branch.nick    
 
355
 
 
356
def revno(branch):
 
357
    """ Get current revision number for specified branch
 
358
    
 
359
    :param branch: path to the branch
 
360
    
 
361
    :return: revision number
 
362
    """
 
363
    try:
 
364
        revno = Branch.open_containing(branch)[0].revno()
 
365
    except errors.NotBranchError:
 
366
        raise NotBranchError
 
367
    else:
 
368
        return revno
 
369
 
 
370
def version():
 
371
    """ Get version information from bzr
 
372
    
 
373
    :return: bzrlib version
 
374
    """
 
375
    return bzrlib.__version__
 
376
 
 
377
def whoami(branch=None, email=False):
 
378
    """ Get user's data (name and email address)
 
379
    
 
380
    :param branch: if specified, the user's data will be looked up in the branch's config
 
381
    
 
382
    :param email: if True, only the email address will be returned
 
383
    
 
384
    :return: user info (only email address if email is True)
 
385
    """
 
386
    from bzrlib.workingtree import WorkingTree
 
387
    
 
388
    if branch is not None:
 
389
        try:
 
390
            b = WorkingTree.open_containing(u'.')[0].branch
 
391
            config = bzrlib.config.BranchConfig(b)
 
392
        except NotBranchError:
 
393
            config = bzrlib.config.GlobalConfig()
 
394
    else:
 
395
        config = bzrlib.config.GlobalConfig()
 
396
        
 
397
    if email:
 
398
        return config.user_email()
 
399
    else:
 
400
        return config.username()