/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
2
# Some parts of the code are:
3
# Copyright (C) 2005, 2006 by Canonical Ltd
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
4
#
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
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.
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
9
#
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
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.
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
14
#
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
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
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
19
import bzrlib
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
20
import bzrlib.errors as errors
21
22
from bzrlib.branch import Branch
0.8.23 by Szilveszter Farkas (Phanatic)
Visual feedback when Olive is busy; follow bzr API changes; commit dialog update
23
from bzrlib.workingtree import WorkingTree
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
24
0.11.1 by Jelmer Vernooij
Eliminate olive.backend.errors.
25
from bzrlib.errors import (NotBranchError, PermissionDenied, BzrError)
26
27
class DifferentBranchesError(BzrError):
28
    """ Occurs if the specified files are in different branches
29
    
30
    May occur in:
31
        info.diff()
32
    """
33
34
35
class PrefixFormatError(BzrError):
36
    """ Occurs if the prefix is badly formatted
37
    
38
    May occur in:
39
        info.diff()
40
    """
41
42
43
class RevisionValueError(BzrError):
44
    """ Invalid revision value provided
45
    
46
    May occur in:
47
        info.log()
48
    """
49
0.8.5 by Szilveszter Farkas (Phanatic)
* backend/info.py: nick() and revno() implemented
50
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
51
def diff(revision=None, file_list=None, diff_options=None, prefix=None):
52
    """ Save the diff into a temporary file.
53
    
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
54
    :param revision: a list of revision numbers (one or two elements)
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
55
    
56
    :param file_list: list of files you want to diff
57
    
58
    :param diff_options: external diff options
59
    
60
    :param prefix: 0 - p0, 1 - p1, or specify prefixes in the form of old/:new/
61
    
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
62
    :return: path to the temporary file which contains the diff output (the frontend has to remove it!)
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
63
    """
64
    from tempfile import mkstemp
65
    
66
    from bzrlib.builtins import internal_tree_files
67
    from bzrlib.diff import show_diff_trees
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
68
    from bzrlib.revisionspec import RevisionSpec_int
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
69
    from bzrlib.workingtree import WorkingTree
70
    
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
71
    from info_helper import diff_helper
72
73
    if (prefix is None) or (prefix == '0'):
74
        # diff -p0 format
75
        old_label = ''
76
        new_label = ''
77
    elif prefix == '1':
78
        old_label = 'old/'
79
        new_label = 'new/'
80
    else:
81
        if not ':' in prefix:
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
82
            raise PrefixFormatError
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
83
        old_label, new_label = prefix.split(":")
84
    
85
    try:
86
        tree1, file_list = internal_tree_files(file_list)
87
        tree2 = None
88
        b = None
89
        b2 = None
90
    except errors.FileInWrongBranch:
91
        if len(file_list) != 2:
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
92
            raise DifferentBranchesError
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
93
94
        tree1, file1 = WorkingTree.open_containing(file_list[0])
95
        tree2, file2 = WorkingTree.open_containing(file_list[1])
96
    
97
        if file1 != "" or file2 != "":
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
98
            raise DifferentBranchesError
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
99
    
100
        file_list = None
101
    
102
    tmpfile = mkstemp(prefix='olive_')
103
    tmpfp = open(tmpfile[1], 'w')
104
    
105
    if revision is not None:
106
        if tree2 is not None:
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
107
            raise RevisionValueError
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
108
    
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
109
        if len(revision) >= 1:
110
            revision[0] = RevisionSpec_int(revision[0])
111
        if len(revision) == 2:
112
            revision[1] = RevisionSpec_int(revision[1])
113
        
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
114
        if (len(revision) == 1) or (revision[1].spec is None):
115
            ret = diff_helper(tree1, file_list, diff_options,
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
116
                              revision[0], 
117
                              old_label=old_label, new_label=new_label,
118
                              output=tmpfp)
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
119
        elif len(revision) == 2:
120
            ret = diff_helper(tree1, file_list, diff_options,
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
121
                              revision[0], revision[1],
122
                              old_label=old_label, new_label=new_label,
123
                              output=tmpfp)
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
124
        else:
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
125
            raise RevisionValueError
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
126
    else:
127
        if tree2 is not None:
128
            ret = show_diff_trees(tree1, tree2, tmpfp, 
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
129
                                  specific_files=file_list,
130
                                  external_diff_options=diff_options,
131
                                  old_label=old_label, new_label=new_label)
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
132
        else:
133
            ret = diff_helper(tree1, file_list, diff_options,
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
134
                              old_label=old_label, new_label=new_label,
135
                              output=tmpfp)
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
136
    
137
    tmpfp.close()
138
    
139
    if ret == 0:
140
        return False
141
    else:
142
        return tmpfile[1]
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
143
0.8.27 by Szilveszter Farkas (Phanatic)
Push dialog now displays stored location
144
def get_push_location(location):
145
    """ Get the stored push location of a branch.
146
    
147
    :param location: the path to the branch
148
    
149
    :return: the stored location
150
    """
151
    from bzrlib.branch import Branch
152
    
153
    try:
154
        branch = Branch.open_containing(location)[0]
155
    except errors.NotBranchError:
156
        raise NotBranchError(location)
157
    except:
158
        raise
159
    
160
    return branch.get_push_location()
161
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
162
def info(location):
163
    """ Get info about branch, working tree, and repository
164
    
165
    :param location: the location of the branch/working tree/repository
166
    
167
    :return: the information in dictionary format
168
    
169
    The following informations are delivered (if available):
170
    ret['location']['lightcoroot']: Light checkout root
171
    ret['location']['sharedrepo']: Shared repository
172
    ret['location']['repobranch']: Repository branch
173
    ret['location']['cobranch']: Checkout of branch
174
    ret['location']['repoco']: Repository checkout
175
    ret['location']['coroot']: Checkout root
176
    ret['location']['branchroot']: Branch root
177
    ret['related']['parentbranch']: Parent branch
178
    ret['related']['publishbranch']: Publish to branch
179
    ret['format']['control']: Control format
180
    ret['format']['workingtree']: Working tree format
181
    ret['format']['branch']: Branch format
182
    ret['format']['repository']: Repository format
183
    ret['locking']['workingtree']: Working tree lock status
184
    ret['locking']['branch']: Branch lock status
185
    ret['locking']['repository']: Repository lock status
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
186
    ret['missing']['branch']: Missing revisions in branch
187
    ret['missing']['workingtree']: Missing revisions in working tree
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
188
    ret['wtstats']['unchanged']: Unchanged files
189
    ret['wtstats']['modified']: Modified files
190
    ret['wtstats']['added']: Added files
191
    ret['wtstats']['removed']: Removed files
192
    ret['wtstats']['renamed']: Renamed files
193
    ret['wtstats']['unknown']: Unknown files
194
    ret['wtstats']['ignored']: Ingnored files
195
    ret['wtstats']['subdirs']: Versioned subdirectories
196
    ret['brstats']['revno']: Revisions in branch
197
    ret['brstats']['commiters']: Number of commiters
198
    ret['brstats']['age']: Age of branch in days
199
    ret['brstats']['firstrev']: Time of first revision
200
    ret['brstats']['lastrev']: Time of last revision
201
    ret['repstats']['revisions']: Revisions in repository
202
    ret['repstats']['size']: Size of repository in bytes
203
    """
204
    import bzrlib.bzrdir as bzrdir
205
    
206
    import info_helper
207
    
208
    ret = {}
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
209
    try:
210
        a_bzrdir = bzrdir.BzrDir.open_containing(location)[0]
211
    except errors.NotBranchError:
212
        raise NotBranchError(location)
213
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
214
    try:
215
        working = a_bzrdir.open_workingtree()
216
        working.lock_read()
217
        try:
218
            branch = working.branch
219
            repository = branch.repository
220
            control = working.bzrdir
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
221
            
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
222
            ret['location'] = info_helper.get_location_info(repository, branch, working)
223
            ret['related'] = info_helper.get_related_info(branch)
224
            ret['format'] = info_helper.get_format_info(control, repository, branch, working)
225
            ret['locking'] = info_helper.get_locking_info(repository, branch, working)
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
226
            ret['missing'] = {}
227
            ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
228
            ret['missing']['workingtree'] = info_helper.get_missing_revisions_working(working)
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
229
            ret['wtstats'] = info_helper.get_working_stats(working)
230
            ret['brstats'] = info_helper.get_branch_stats(branch)
231
            ret['repstats'] = info_helper.get_repository_stats(repository)
232
        finally:
233
            working.unlock()
234
            return ret
235
        return
236
    except (errors.NoWorkingTree, errors.NotLocalUrl):
237
        pass
238
239
    try:
240
        branch = a_bzrdir.open_branch()
241
        branch.lock_read()
242
        try:
243
            ret['location'] = info_helper.get_location_info(repository, branch)
244
            ret['related'] = info_helper.get_related_info(branch)
245
            ret['format'] = info_helper.get_format_info(control, repository, branch)
246
            ret['locking'] = info_helper.get_locking_info(repository, branch)
0.8.42 by Szilveszter Farkas (Phanatic)
Implemented Informations functionality; some bzrlib API changes handled.
247
            ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
0.8.6 by Szilveszter Farkas (Phanatic)
* backend/info.py: implemented version(), whoami() and info()
248
            ret['brstats'] = info_helper.get_branch_stats(branch)
249
            ret['repstats'] = info_helper.get_repository_stats(repository)
250
        finally:
251
            branch.unlock()
252
            return ret
253
        return
254
    except errors.NotBranchError:
255
        pass
256
257
    try:
258
        repository = a_bzrdir.open_repository()
259
        repository.lock_read()
260
        try:
261
            ret['location'] = info_helper.get_location_info(repository)
262
            ret['format'] = info_helper.get_format_info(control, repository)
263
            ret['locking'] = info_helper.get_locking_info(repository)
264
            ret['repstats'] = info_helper.get_repository_stats(repository)
265
        finally:
266
            repository.unlock()
267
            return ret
268
        return
269
    except errors.NoRepositoryPresent:
270
        pass
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
271
0.8.53 by Szilveszter Farkas (Phanatic)
Set sensitivity of menus and toolbuttons.
272
def is_branch(location):
273
    """ Check if the location is a branch.
274
    
275
    :param location: the location you want to check
276
    
277
    :return: True or False respectively
278
    """
279
    try:
280
        branch = Branch.open_containing(location)[0]
281
    except errors.NotBranchError:
282
        return False
0.8.56 by Szilveszter Farkas (Phanatic)
Handle permission denied exceptions properly.
283
    except errors.PermissionDenied:
284
        raise PermissionDenied(location)
0.8.53 by Szilveszter Farkas (Phanatic)
Set sensitivity of menus and toolbuttons.
285
    else:
286
        return True
287
        
288
0.8.23 by Szilveszter Farkas (Phanatic)
Visual feedback when Olive is busy; follow bzr API changes; commit dialog update
289
def is_checkout(location):
290
    """ Check if the location is a checkout.
291
    
292
    :param location: the location you want to check
293
    
294
    :return: True or False respectively
295
    """
296
    try:
297
        branch = Branch.open_containing(location)[0]
298
    except errors.NotBranchError:
299
        raise NotBranchError
300
    
301
    try:
302
        working = WorkingTree.open_containing(location)[0]
303
    except:
304
        raise
305
    
306
    working_path = working.bzrdir.root_transport.base
307
    branch_path = branch.bzrdir.root_transport.base
308
    
309
    if working_path != branch_path:
310
        # lightweight checkout
311
        return True
312
    elif branch.get_bound_location():
313
        # checkout
314
        return True
315
    else:
316
        return False
317
0.8.9 by Szilveszter Farkas (Phanatic)
2006-07-08 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
318
def log(location, timezone='original', verbose=False, show_ids=False,
319
        forward=False, revision=None, log_format=None, message=None,
320
        long=False, short=False, line=False):
321
    """ Print log into a temporary file.
322
    
323
    :param location: location of local/remote branch or file
324
    
325
    :param timzone: requested timezone
326
    
327
    :param verbose: verbose output
328
    
329
    :param show_ids:
330
    
331
    :param forward: if True, start from the earliest entry
332
    
333
    :param revision: revision range as a list ([from, to])
334
    
335
    :param log_format: line, short, long
336
    
337
    :param message: show revisions whose message matches this regexp
338
    
339
    :param long: long log format
340
    
341
    :param short: short log format
342
    
343
    :param line: line log format
344
    
345
    :return: full path to the temporary file containing the log (the frontend has to remove it!)
346
    """
347
    from tempfile import mkstemp
348
    
349
    from bzrlib import bzrdir    
350
    from bzrlib.builtins import get_log_format
351
    from bzrlib.log import log_formatter, show_log
352
    from bzrlib.revisionspec import RevisionSpec_int
353
    
354
    assert message is None or isinstance(message, basestring), \
355
        "invalid message argument %r" % message
356
    direction = (forward and 'forward') or 'reverse'
357
        
358
    # log everything
359
    file_id = None
360
    
361
    # find the file id to log:
362
    dir, fp = bzrdir.BzrDir.open_containing(location)
363
    b = dir.open_branch()
364
    if fp != '':
365
        try:
366
            # might be a tree:
367
            inv = dir.open_workingtree().inventory
368
        except (errors.NotBranchError, errors.NotLocalUrl):
369
            # either no tree, or is remote.
370
            inv = b.basis_tree().inventory
371
        file_id = inv.path2id(fp)
372
373
    if revision is not None:
374
        if len(revision) >= 1:
375
            revision[0] = RevisionSpec_int(revision[0])
376
        if len(revision) == 2:
377
            revision[1] = RevisionSpec_int(revision[1])
378
    
379
    if revision is None:
380
        rev1 = None
381
        rev2 = None
382
    elif len(revision) == 1:
383
        rev1 = rev2 = revision[0].in_history(b).revno
384
    elif len(revision) == 2:
385
        if revision[0].spec is None:
386
            # missing begin-range means first revision
387
            rev1 = 1
388
        else:
389
            rev1 = revision[0].in_history(b).revno
390
391
        if revision[1].spec is None:
392
            # missing end-range means last known revision
393
            rev2 = b.revno()
394
        else:
395
            rev2 = revision[1].in_history(b).revno
396
    else:
397
        raise RevisionValueError
398
399
    # By this point, the revision numbers are converted to the +ve
400
    # form if they were supplied in the -ve form, so we can do
401
    # this comparison in relative safety
402
    if rev1 > rev2:
403
        (rev2, rev1) = (rev1, rev2)
404
405
    if (log_format == None):
406
        default = b.get_config().log_format()
407
        log_format = get_log_format(long=long, short=short, line=line, 
408
                                    default=default)
409
    
410
    tmpfile = mkstemp(prefix='olive_')
411
    tmpfp = open(tmpfile[1], 'w')
412
    
413
    lf = log_formatter(log_format,
414
                       show_ids=show_ids,
415
                       to_file=tmpfp,
416
                       show_timezone=timezone)
417
418
    show_log(b,
419
             lf,
420
             file_id,
421
             verbose=verbose,
422
             direction=direction,
423
             start_revision=rev1,
424
             end_revision=rev2,
425
             search=message)
426
    
427
    tmpfp.close()
428
    return tmpfile[1]
429
0.8.8 by Szilveszter Farkas (Phanatic)
2006-07-06 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
430
def nick(branch, nickname=None):
431
    """ Get or set nickname.
432
    
433
    :param branch: path to the branch
434
    
435
    :param nickname: if specified, the nickname will be set
436
    
437
    :return: nickname
438
    """
439
    try:
440
        branch = Branch.open_containing(branch)[0]
441
    except errors.NotBranchError:
442
        raise NotBranchError
443
    
444
    if nickname is not None:
445
        branch.nick = nickname
446
447
    return branch.nick    
448
449
def revno(branch):
450
    """ Get current revision number for specified branch
451
    
452
    :param branch: path to the branch
453
    
454
    :return: revision number
455
    """
456
    try:
457
        revno = Branch.open_containing(branch)[0].revno()
458
    except errors.NotBranchError:
459
        raise NotBranchError
460
    else:
461
        return revno
462
463
def version():
464
    """ Get version information from bzr
465
    
466
    :return: bzrlib version
467
    """
468
    return bzrlib.__version__
469
470
def whoami(branch=None, email=False):
471
    """ Get user's data (name and email address)
472
    
473
    :param branch: if specified, the user's data will be looked up in the branch's config
474
    
475
    :param email: if True, only the email address will be returned
476
    
477
    :return: user info (only email address if email is True)
478
    """
479
    from bzrlib.workingtree import WorkingTree
480
    
481
    if branch is not None:
482
        try:
483
            b = WorkingTree.open_containing(u'.')[0].branch
484
            config = bzrlib.config.BranchConfig(b)
485
        except NotBranchError:
486
            config = bzrlib.config.GlobalConfig()
487
    else:
488
        config = bzrlib.config.GlobalConfig()
489
        
490
    if email:
491
        return config.user_email()
492
    else:
493
        return config.username()