/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 olive/backend/info.py

  • Committer: Jelmer Vernooij
  • Date: 2006-09-04 23:36:58 UTC
  • mto: (0.8.83 merge)
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: jelmer@samba.org-20060904233658-9c7861991474581b
Move ui.py to frontend as it is gtk-specific

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
from bzrlib.workingtree import WorkingTree
 
24
 
 
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
 
 
50
 
 
51
def diff(revision=None, file_list=None, diff_options=None, prefix=None):
 
52
    """ Save the diff into a temporary file.
 
53
    
 
54
    :param revision: a list of revision numbers (one or two elements)
 
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
    
 
62
    :return: path to the temporary file which contains the diff output (the frontend has to remove it!)
 
63
    """
 
64
    from tempfile import mkstemp
 
65
    
 
66
    from bzrlib.builtins import internal_tree_files
 
67
    from bzrlib.diff import show_diff_trees
 
68
    from bzrlib.revisionspec import RevisionSpec_int
 
69
    from bzrlib.workingtree import WorkingTree
 
70
    
 
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:
 
82
            raise PrefixFormatError
 
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:
 
92
            raise DifferentBranchesError
 
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 != "":
 
98
            raise DifferentBranchesError
 
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:
 
107
            raise RevisionValueError
 
108
    
 
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
        
 
114
        if (len(revision) == 1) or (revision[1].spec is None):
 
115
            ret = diff_helper(tree1, file_list, diff_options,
 
116
                              revision[0], 
 
117
                              old_label=old_label, new_label=new_label,
 
118
                              output=tmpfp)
 
119
        elif len(revision) == 2:
 
120
            ret = diff_helper(tree1, file_list, diff_options,
 
121
                              revision[0], revision[1],
 
122
                              old_label=old_label, new_label=new_label,
 
123
                              output=tmpfp)
 
124
        else:
 
125
            raise RevisionValueError
 
126
    else:
 
127
        if tree2 is not None:
 
128
            ret = show_diff_trees(tree1, tree2, tmpfp, 
 
129
                                  specific_files=file_list,
 
130
                                  external_diff_options=diff_options,
 
131
                                  old_label=old_label, new_label=new_label)
 
132
        else:
 
133
            ret = diff_helper(tree1, file_list, diff_options,
 
134
                              old_label=old_label, new_label=new_label,
 
135
                              output=tmpfp)
 
136
    
 
137
    tmpfp.close()
 
138
    
 
139
    if ret == 0:
 
140
        return False
 
141
    else:
 
142
        return tmpfile[1]
 
143
 
 
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
 
 
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
 
186
    ret['missing']['branch']: Missing revisions in branch
 
187
    ret['missing']['workingtree']: Missing revisions in working tree
 
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 = {}
 
209
    try:
 
210
        a_bzrdir = bzrdir.BzrDir.open_containing(location)[0]
 
211
    except errors.NotBranchError:
 
212
        raise NotBranchError(location)
 
213
 
 
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
 
221
            
 
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)
 
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)
 
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)
 
247
            ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
 
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
 
271
 
 
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
 
283
    except errors.PermissionDenied:
 
284
        raise PermissionDenied(location)
 
285
    else:
 
286
        return True
 
287
        
 
288
 
 
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
 
 
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
 
 
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()