/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: Szilveszter Farkas (Phanatic)
  • Date: 2006-08-10 17:25:30 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-20060810172530-d63fde9240356aab
Implemented Log functionality (via bzrk).

2006-08-10  Szilveszter Farkas <Szilveszter.Farkas@gmail.com>

    * olive/frontend/gtk/log.py: implemented OliveLog (calls BzrkApp)
    * olive/frontend/gtk/viz/diffwin.py: made it bzrlib 0.9 API compatible
    * olive/frontend/gtk/viz/bzrkapp.py: don't quit main loop
    * olive/frontend/gtk/viz: added bzrk codebase for Log functionality
    * setup.py: added olive.frontend.gtk.viz package

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