/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-05 01:37:16 UTC
  • mto: (0.8.83 merge)
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: jelmer@samba.org-20060905013716-ed1ce9389829a5a1
Integrate olive.backend.fileops

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
    branch = Branch.open_containing(location)[0]
 
154
    
 
155
    return branch.get_push_location()
 
156
 
 
157
def info(location):
 
158
    """ Get info about branch, working tree, and repository
 
159
    
 
160
    :param location: the location of the branch/working tree/repository
 
161
    
 
162
    :return: the information in dictionary format
 
163
    
 
164
    The following informations are delivered (if available):
 
165
    ret['location']['lightcoroot']: Light checkout root
 
166
    ret['location']['sharedrepo']: Shared repository
 
167
    ret['location']['repobranch']: Repository branch
 
168
    ret['location']['cobranch']: Checkout of branch
 
169
    ret['location']['repoco']: Repository checkout
 
170
    ret['location']['coroot']: Checkout root
 
171
    ret['location']['branchroot']: Branch root
 
172
    ret['related']['parentbranch']: Parent branch
 
173
    ret['related']['publishbranch']: Publish to branch
 
174
    ret['format']['control']: Control format
 
175
    ret['format']['workingtree']: Working tree format
 
176
    ret['format']['branch']: Branch format
 
177
    ret['format']['repository']: Repository format
 
178
    ret['locking']['workingtree']: Working tree lock status
 
179
    ret['locking']['branch']: Branch lock status
 
180
    ret['locking']['repository']: Repository lock status
 
181
    ret['missing']['branch']: Missing revisions in branch
 
182
    ret['missing']['workingtree']: Missing revisions in working tree
 
183
    ret['wtstats']['unchanged']: Unchanged files
 
184
    ret['wtstats']['modified']: Modified files
 
185
    ret['wtstats']['added']: Added files
 
186
    ret['wtstats']['removed']: Removed files
 
187
    ret['wtstats']['renamed']: Renamed files
 
188
    ret['wtstats']['unknown']: Unknown files
 
189
    ret['wtstats']['ignored']: Ingnored files
 
190
    ret['wtstats']['subdirs']: Versioned subdirectories
 
191
    ret['brstats']['revno']: Revisions in branch
 
192
    ret['brstats']['commiters']: Number of commiters
 
193
    ret['brstats']['age']: Age of branch in days
 
194
    ret['brstats']['firstrev']: Time of first revision
 
195
    ret['brstats']['lastrev']: Time of last revision
 
196
    ret['repstats']['revisions']: Revisions in repository
 
197
    ret['repstats']['size']: Size of repository in bytes
 
198
    """
 
199
    import bzrlib.bzrdir as bzrdir
 
200
    
 
201
    import info_helper
 
202
    
 
203
    ret = {}
 
204
    a_bzrdir = bzrdir.BzrDir.open_containing(location)[0]
 
205
 
 
206
    try:
 
207
        working = a_bzrdir.open_workingtree()
 
208
        working.lock_read()
 
209
        try:
 
210
            branch = working.branch
 
211
            repository = branch.repository
 
212
            control = working.bzrdir
 
213
            
 
214
            ret['location'] = info_helper.get_location_info(repository, branch, working)
 
215
            ret['related'] = info_helper.get_related_info(branch)
 
216
            ret['format'] = info_helper.get_format_info(control, repository, branch, working)
 
217
            ret['locking'] = info_helper.get_locking_info(repository, branch, working)
 
218
            ret['missing'] = {}
 
219
            ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
 
220
            ret['missing']['workingtree'] = info_helper.get_missing_revisions_working(working)
 
221
            ret['wtstats'] = info_helper.get_working_stats(working)
 
222
            ret['brstats'] = info_helper.get_branch_stats(branch)
 
223
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
224
        finally:
 
225
            working.unlock()
 
226
            return ret
 
227
        return
 
228
    except (errors.NoWorkingTree, errors.NotLocalUrl):
 
229
        pass
 
230
 
 
231
    try:
 
232
        branch = a_bzrdir.open_branch()
 
233
        branch.lock_read()
 
234
        try:
 
235
            ret['location'] = info_helper.get_location_info(repository, branch)
 
236
            ret['related'] = info_helper.get_related_info(branch)
 
237
            ret['format'] = info_helper.get_format_info(control, repository, branch)
 
238
            ret['locking'] = info_helper.get_locking_info(repository, branch)
 
239
            ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
 
240
            ret['brstats'] = info_helper.get_branch_stats(branch)
 
241
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
242
        finally:
 
243
            branch.unlock()
 
244
            return ret
 
245
        return
 
246
    except errors.NotBranchError:
 
247
        pass
 
248
 
 
249
    try:
 
250
        repository = a_bzrdir.open_repository()
 
251
        repository.lock_read()
 
252
        try:
 
253
            ret['location'] = info_helper.get_location_info(repository)
 
254
            ret['format'] = info_helper.get_format_info(control, repository)
 
255
            ret['locking'] = info_helper.get_locking_info(repository)
 
256
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
257
        finally:
 
258
            repository.unlock()
 
259
            return ret
 
260
        return
 
261
    except errors.NoRepositoryPresent:
 
262
        pass
 
263
 
 
264
def is_branch(location):
 
265
    """ Check if the location is a branch.
 
266
    
 
267
    :param location: the location you want to check
 
268
    
 
269
    :return: True or False respectively
 
270
    """
 
271
    try:
 
272
        branch = Branch.open_containing(location)[0]
 
273
    except errors.NotBranchError:
 
274
        return False
 
275
    else:
 
276
        return True
 
277
        
 
278
 
 
279
def is_checkout(location):
 
280
    """ Check if the location is a checkout.
 
281
    
 
282
    :param location: the location you want to check
 
283
    
 
284
    :return: True or False respectively
 
285
    """
 
286
    branch = Branch.open_containing(location)[0]
 
287
    
 
288
    try:
 
289
        working = WorkingTree.open_containing(location)[0]
 
290
    except:
 
291
        raise
 
292
    
 
293
    working_path = working.bzrdir.root_transport.base
 
294
    branch_path = branch.bzrdir.root_transport.base
 
295
    
 
296
    if working_path != branch_path:
 
297
        # lightweight checkout
 
298
        return True
 
299
    elif branch.get_bound_location():
 
300
        # checkout
 
301
        return True
 
302
    else:
 
303
        return False
 
304
 
 
305
def log(location, timezone='original', verbose=False, show_ids=False,
 
306
        forward=False, revision=None, log_format=None, message=None,
 
307
        long=False, short=False, line=False):
 
308
    """ Print log into a temporary file.
 
309
    
 
310
    :param location: location of local/remote branch or file
 
311
    
 
312
    :param timzone: requested timezone
 
313
    
 
314
    :param verbose: verbose output
 
315
    
 
316
    :param show_ids:
 
317
    
 
318
    :param forward: if True, start from the earliest entry
 
319
    
 
320
    :param revision: revision range as a list ([from, to])
 
321
    
 
322
    :param log_format: line, short, long
 
323
    
 
324
    :param message: show revisions whose message matches this regexp
 
325
    
 
326
    :param long: long log format
 
327
    
 
328
    :param short: short log format
 
329
    
 
330
    :param line: line log format
 
331
    
 
332
    :return: full path to the temporary file containing the log (the frontend has to remove it!)
 
333
    """
 
334
    from tempfile import mkstemp
 
335
    
 
336
    from bzrlib import bzrdir    
 
337
    from bzrlib.builtins import get_log_format
 
338
    from bzrlib.log import log_formatter, show_log
 
339
    from bzrlib.revisionspec import RevisionSpec_int
 
340
    
 
341
    assert message is None or isinstance(message, basestring), \
 
342
        "invalid message argument %r" % message
 
343
    direction = (forward and 'forward') or 'reverse'
 
344
        
 
345
    # log everything
 
346
    file_id = None
 
347
    
 
348
    # find the file id to log:
 
349
    dir, fp = bzrdir.BzrDir.open_containing(location)
 
350
    b = dir.open_branch()
 
351
    if fp != '':
 
352
        try:
 
353
            # might be a tree:
 
354
            inv = dir.open_workingtree().inventory
 
355
        except (errors.NotBranchError, errors.NotLocalUrl):
 
356
            # either no tree, or is remote.
 
357
            inv = b.basis_tree().inventory
 
358
        file_id = inv.path2id(fp)
 
359
 
 
360
    if revision is not None:
 
361
        if len(revision) >= 1:
 
362
            revision[0] = RevisionSpec_int(revision[0])
 
363
        if len(revision) == 2:
 
364
            revision[1] = RevisionSpec_int(revision[1])
 
365
    
 
366
    if revision is None:
 
367
        rev1 = None
 
368
        rev2 = None
 
369
    elif len(revision) == 1:
 
370
        rev1 = rev2 = revision[0].in_history(b).revno
 
371
    elif len(revision) == 2:
 
372
        if revision[0].spec is None:
 
373
            # missing begin-range means first revision
 
374
            rev1 = 1
 
375
        else:
 
376
            rev1 = revision[0].in_history(b).revno
 
377
 
 
378
        if revision[1].spec is None:
 
379
            # missing end-range means last known revision
 
380
            rev2 = b.revno()
 
381
        else:
 
382
            rev2 = revision[1].in_history(b).revno
 
383
    else:
 
384
        raise RevisionValueError
 
385
 
 
386
    # By this point, the revision numbers are converted to the +ve
 
387
    # form if they were supplied in the -ve form, so we can do
 
388
    # this comparison in relative safety
 
389
    if rev1 > rev2:
 
390
        (rev2, rev1) = (rev1, rev2)
 
391
 
 
392
    if (log_format == None):
 
393
        default = b.get_config().log_format()
 
394
        log_format = get_log_format(long=long, short=short, line=line, 
 
395
                                    default=default)
 
396
    
 
397
    tmpfile = mkstemp(prefix='olive_')
 
398
    tmpfp = open(tmpfile[1], 'w')
 
399
    
 
400
    lf = log_formatter(log_format,
 
401
                       show_ids=show_ids,
 
402
                       to_file=tmpfp,
 
403
                       show_timezone=timezone)
 
404
 
 
405
    show_log(b,
 
406
             lf,
 
407
             file_id,
 
408
             verbose=verbose,
 
409
             direction=direction,
 
410
             start_revision=rev1,
 
411
             end_revision=rev2,
 
412
             search=message)
 
413
    
 
414
    tmpfp.close()
 
415
    return tmpfile[1]
 
416
 
 
417
def nick(branch, nickname=None):
 
418
    """ Get or set nickname.
 
419
    
 
420
    :param branch: path to the branch
 
421
    
 
422
    :param nickname: if specified, the nickname will be set
 
423
    
 
424
    :return: nickname
 
425
    """
 
426
    try:
 
427
        branch = Branch.open_containing(branch)[0]
 
428
    except errors.NotBranchError:
 
429
        raise NotBranchError
 
430
    
 
431
    if nickname is not None:
 
432
        branch.nick = nickname
 
433
 
 
434
    return branch.nick    
 
435
 
 
436
def revno(branch):
 
437
    """ Get current revision number for specified branch
 
438
    
 
439
    :param branch: path to the branch
 
440
    
 
441
    :return: revision number
 
442
    """
 
443
    try:
 
444
        revno = Branch.open_containing(branch)[0].revno()
 
445
    except errors.NotBranchError:
 
446
        raise NotBranchError
 
447
    else:
 
448
        return revno
 
449
 
 
450
def version():
 
451
    """ Get version information from bzr
 
452
    
 
453
    :return: bzrlib version
 
454
    """
 
455
    return bzrlib.__version__
 
456
 
 
457
def whoami(branch=None, email=False):
 
458
    """ Get user's data (name and email address)
 
459
    
 
460
    :param branch: if specified, the user's data will be looked up in the branch's config
 
461
    
 
462
    :param email: if True, only the email address will be returned
 
463
    
 
464
    :return: user info (only email address if email is True)
 
465
    """
 
466
    from bzrlib.workingtree import WorkingTree
 
467
    
 
468
    if branch is not None:
 
469
        try:
 
470
            b = WorkingTree.open_containing(u'.')[0].branch
 
471
            config = bzrlib.config.BranchConfig(b)
 
472
        except NotBranchError:
 
473
            config = bzrlib.config.GlobalConfig()
 
474
    else:
 
475
        config = bzrlib.config.GlobalConfig()
 
476
        
 
477
    if email:
 
478
        return config.user_email()
 
479
    else:
 
480
        return config.username()