~ubuntu-branches/debian/sid/trac-bzr/sid

« back to all changes in this revision

Viewing changes to tracbzr/backend.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2010-08-14 18:21:23 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100814182123-16lchyp1jsow385b
Tags: 0.4.1-1
* New upstream release.
* Bump standards version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
# Copyright (C) 2006 Yann Hodique <hodique@lifl.fr>
7
7
# Copyright (C) 2006 Lukas Lalinsky <lalinsky@gmail.com>
8
8
# Copyright (C) 2006 Marien Zwart <marienz@gentoo.org>
9
 
# Copyright (C) 2006, 2007 Panoramic Feedback <abentley@panoramicfeedback.com>
 
9
# Copyright (C) 2006,2007 Panoramic Feedback <abentley@panoramicfeedback.com>
10
10
# Copyright (C) 2006,2008,2009 Jelmer Vernooij <jelmer@samba.org>
11
11
# Copyright (C) 2009,2010 Martin von Gagern <Martin.vGagern@gmx.net>
12
12
# All rights reserved.
40
40
import fnmatch
41
41
 
42
42
import trac
43
 
from trac import versioncontrol, core, config, mimeview, wiki
 
43
from trac import versioncontrol, core, config, mimeview, util, wiki
44
44
from trac.web.chrome import Chrome
45
45
from trac.util.html import html, Markup
46
46
 
47
47
trac_version = (int(trac.__version__[0]), int(trac.__version__[2:4]))
48
48
 
 
49
if trac_version >= (0,12):
 
50
    def _trac_construct(init):
 
51
        def wrapped_init(self, bzr_repo, *args, **kwargs):
 
52
            init(self, bzr_repo, *args, **kwargs)
 
53
        return wrapped_init
 
54
else:
 
55
    def _trac_construct(init):
 
56
        def wrapped_init(self, bzr_repo, *args, **kwargs):
 
57
            init(self, *args, **kwargs)
 
58
        return wrapped_init
 
59
    
49
60
if trac_version >= (0,11):
50
61
    from trac.util.datefmt import utc
51
62
    # Check trac version.  trac 0.11 uses datetime objects for
86
97
        if hasattr(self.env, 'systeminfo'):
87
98
            bzr_version = '%i.%i.%i' % bzrlib.api.get_current_api_version(None)
88
99
            self.env.systeminfo.append(('Bazaar', bzr_version))
 
100
            try:
 
101
                import tracbzr as tracbzr_mod
 
102
                tracbzr_version = util.get_pkginfo(tracbzr_mod).get('version')
 
103
            except Exception, e:
 
104
                self.log.warn(e)
 
105
                tracbzr_version = 'unknown'
 
106
            self.env.systeminfo.append(('TracBzr', tracbzr_version))
89
107
 
90
108
    def get_supported_types(self):
91
109
        """Support for `repository_type = bzr`"""
92
110
        yield ('bzr', 8)
93
111
 
94
 
    def get_repository(self, repos_type, repos_dir, authname):
 
112
    def get_repository(self, repos_type, repos_dir, authname_or_params):
95
113
        """Return a `BzrRepository`"""
96
114
        assert repos_type == 'bzr'
97
 
        return BzrRepository(repos_dir, self)
 
115
        return BzrRepository(repos_dir, authname_or_params, self)
98
116
 
99
117
class BzrWikiMacros(core.Component):
100
118
    """Component for macros related to bzr."""
233
251
    """Present a bzr branch as a trac repository."""
234
252
 
235
253
    primary_branches = config.ListOption(
236
 
        config_section, 'primary_branches', ',trunk', keep_empty = True, 
 
254
        config_section, 'primary_branches', 'trunk', keep_empty = True, 
237
255
        doc = """Ordered list of primary branches.
238
256
 
239
257
        These will be listed first in the Branches macro. When viewing
243
261
        empty list element can be used to denote the branch at the
244
262
        root of the repository.
245
263
 
246
 
        Defaults to ',trunk'.""")
247
 
 
248
 
    def __init__(self, location, component):
249
 
        versioncontrol.Repository.__init__(self, location, None, component.log)
 
264
        Defaults to 'trunk'.""")
 
265
 
 
266
    include_sideline_changes = config.BoolOption(
 
267
        config_section, 'include_sideline_changes', True,
 
268
        doc = """Include sideline changes in the list of changes.
 
269
 
 
270
        This option controls whether sideline changes (i.e. changes
 
271
        with dotted revision numbers only) are included in the list of
 
272
        changes as reported by the timeline view. Note that there
 
273
        might be other plugins using that information as well, so
 
274
        there might be other components beside the timeline view that
 
275
        get affected by this setting.
 
276
 
 
277
        Defaults to True.""")
 
278
 
 
279
    def __init__(self, location, authname_or_params, component):
 
280
        versioncontrol.Repository.__init__(self, location, authname_or_params,
 
281
                                           component.log)
250
282
        self.component = component
251
283
        self.config = component.config
252
284
        self.root_transport = transport.get_transport(location)
506
538
            else:
507
539
                rhs = []
508
540
            rhss.append(rhs)
509
 
        for (relpath, branch), rhs in zip(branches, rhss):
510
 
            cache = self.get_branch_cache(branch)
511
 
            while rhs:
512
 
                revid = rhs.pop()
513
 
                new_rhs = walk(cache, revid)
514
 
                if new_rhs:
515
 
                    rhs.extend(new_rhs)
 
541
        if self.include_sideline_changes:
 
542
            for (relpath, branch), rhs in zip(branches, rhss):
 
543
                cache = self.get_branch_cache(branch)
 
544
                while rhs:
 
545
                    revid = rhs.pop()
 
546
                    new_rhs = walk(cache, revid)
 
547
                    if new_rhs:
 
548
                        rhs.extend(new_rhs)
516
549
        inrange.sort()
517
550
        return [chgset for time, revid, chgset in inrange]
518
551
 
567
600
        # use current, then it maps out correctly.
568
601
        return self.string_rev(None, CURRENT_REVISION)
569
602
 
570
 
    def _repo_history(self):
571
 
        revisions = {}
572
 
        repos = {}
573
 
        branches = {}
574
 
        seen = set()
575
 
        for loc, branch in self._get_branches():
576
 
            repo_base = branch.repository.bzrdir.transport.base
577
 
            repos[repo_base] = branch.repository
578
 
            for revision_id in reversed(branch.revision_history()):
579
 
                if revision_id in seen:
580
 
                    break
581
 
                revisions.setdefault(repo_base, []).append(revision_id)
582
 
                branches[revision_id] = branch
583
 
                seen.add(revision_id)
584
 
        revision_set = set()
585
 
        for repo_base, revision_ids in revisions.iteritems():
586
 
            revision_set.update(repos[repo_base].get_revisions(revision_ids))
587
 
        revisions = sorted(revision_set, key=lambda x: x.timestamp)
588
 
        return [(r.revision_id, branches[r.revision_id]) for r in revisions]
589
 
 
590
603
    def previous_rev(self, rev, path=''):
591
604
        if path:
592
605
            prev = self.get_node(path, rev).get_previous()
673
686
        This turns None into a rev, and may convert a revid-based rev into
674
687
        a revno-based one.
675
688
        """
676
 
        if rev is None:
 
689
        if rev is None or rev == '':
677
690
            branch = None
678
691
            revid = CURRENT_REVISION
679
692
        else:
769
782
            self._branch_cache[branch_key] = BranchCache(self, branch)
770
783
        return self._branch_cache[branch_key]
771
784
 
772
 
    def sync(self, rev_callback=None):
773
 
        """Dummy to satisfy interface requirements"""
774
 
        # XXX should we be dumping in-mem caches?  Seems unlikely.
775
 
        pass
776
 
        
777
785
 
778
786
class BzrNode(versioncontrol.Node):
779
 
    pass
780
 
 
 
787
 
 
788
    _super_init = _trac_construct(versioncontrol.Node.__init__)
 
789
 
 
790
    def __init__(self, bzr_repo, path, rev, kind):
 
791
        self.bzr_repo = bzr_repo
 
792
        self._super_init(bzr_repo, path, rev, kind)
781
793
 
782
794
class UnversionedDirNode(BzrNode):
783
795
    def __init__(self, bzr_repo, branch, revid, path):
784
796
        rev_string = BzrRepository._escape_revid(CURRENT_REVISION)
785
 
        BzrNode.__init__(self, path, rev_string, versioncontrol.Node.DIRECTORY)
 
797
        BzrNode.__init__(self, bzr_repo, path, rev_string,
 
798
                         versioncontrol.Node.DIRECTORY)
786
799
        self.transport = bzr_repo.root_transport.clone(path)
787
 
        self.bzr_repo = bzr_repo
788
800
        self.branch = branch
789
801
        self.revid = revid
790
802
        self.path = path
847
859
                       self.bzr_repo.string_rev(self.branch, NULL_REVISION),
848
860
                       versioncontrol.Changeset.ADD)
849
861
                return
850
 
        yield (self.path, BzrRepository._escape_revid(CURRENT_REVISION), 'add')
 
862
        yield (self.path,
 
863
               BzrRepository._escape_revid(CURRENT_REVISION),
 
864
               versioncontrol.Changeset.ADD)
851
865
        return
852
866
 
853
867
 
855
869
 
856
870
    def __init__(self, bzr_repo, branch, path):
857
871
        rev_string = bzr_repo.string_rev(branch, NULL_REVISION)
858
 
        BzrNode.__init__(self, path, rev_string, versioncontrol.Node.DIRECTORY)
859
 
        self.bzr_repo = bzr_repo
 
872
        BzrNode.__init__(self, bzr_repo, path, rev_string,
 
873
                         versioncontrol.Node.DIRECTORY)
860
874
        self.branch = branch
861
875
        self.path = path
862
876
 
879
893
        return None
880
894
 
881
895
    def get_history(self, limit=None):
882
 
        return []
 
896
        yield (self.path, 
 
897
               self.bzr_repo.string_rev(self.branch, NULL_REVISION),
 
898
               versioncontrol.Changeset.ADD)
883
899
 
884
900
 
885
901
class BzrVersionedNode(BzrNode):
895
911
 
896
912
    def __init__(self, bzr_repo, branch, revisiontree, entry, path):
897
913
        """Initialize. path has to be a normalized path."""
898
 
        rev_string = bzr_repo.string_rev(branch, entry.revision)
899
 
        BzrNode.__init__(self, path, rev_string, self.kind)
 
914
        # We must Iinitialize bzr specific stuff before we call
 
915
        # get_content_revision().
900
916
        self.bzr_repo = bzr_repo
901
917
        self.log = bzr_repo.log
902
918
        self.repo = branch.repository
903
919
        self.branch = branch
904
920
        self.tree = revisiontree
905
921
        self.entry = entry
 
922
        rev_string = bzr_repo.string_rev(branch, self.get_content_revision())
 
923
        BzrNode.__init__(self, bzr_repo, path, rev_string, self.kind)
906
924
        # XXX I am not sure if this makes any sense but it does make
907
925
        # the links in the changeset viewer work.
908
926
        self.created_rev = self.rev
1031
1049
                current_tree = previous_tree
1032
1050
 
1033
1051
    def get_content_revision(self):
1034
 
        """For non-directory nodes, the content was last changed here."""
 
1052
        """Obtain the revision at which this node was last changed.
 
1053
        This should include changes to any children.
 
1054
        This will be called by BzrVersionedNode's constructor, so overriding
 
1055
        subclasses should ensure that this method can be called safely before
 
1056
        calling BzrVersionedNode.__init__().
 
1057
        """
 
1058
        # For non-directory nodes, the content was last changed here.
1035
1059
        return self.entry.revision
1036
1060
 
1037
1061
    def get_last_modified(self):
1046
1070
 
1047
1071
    def __init__(self, bzr_repo, branch, revisiontree, entry, path,
1048
1072
                 revcache=None):
1049
 
        BzrVersionedNode.__init__(self, bzr_repo, branch, revisiontree, entry, 
1050
 
                                  path)
1051
1073
        if revcache is None:
1052
1074
            revcache = _FileToRevisionCache(bzr_repo, branch, revisiontree, entry)
1053
1075
        self.revcache = revcache
1054
 
        self.rev = self.bzr_repo.string_rev(self.branch,
1055
 
                                            self.get_content_revision())
 
1076
        BzrVersionedNode.__init__(self, bzr_repo, branch, revisiontree, entry, 
 
1077
                                  path)
1056
1078
 
1057
1079
    def get_content_revision(self):
1058
1080
        """Determine the most recent change to the directory or its children."""
1180
1202
 
1181
1203
class BzrChangeset(versioncontrol.Changeset):
1182
1204
 
 
1205
    _super_init = _trac_construct(versioncontrol.Changeset.__init__)
 
1206
 
1183
1207
    def __init__(self, bzr_repo, branch, revid, log):
1184
1208
        """Initialize from a bzr repo, an unquoted revid and a logger."""
1185
1209
        assert isinstance(revid, str), "revid is %r" % type(revid)
1193
1217
            self.revision = revision.Revision(revid, committer='', 
1194
1218
                                              message='', timezone='')
1195
1219
            revidstr = bzr_repo.string_rev(branch, revid)
1196
 
            versioncontrol.Changeset.__init__(self, revidstr,
1197
 
                                              '', '', trac_timestamp(time.time()))
 
1220
            self._super_init(bzr_repo,
 
1221
                             revidstr, '', '', trac_timestamp(time.time()))
1198
1222
            return
1199
1223
        if branch is None:
1200
1224
            assert isinstance(revid, str)
1202
1226
 
1203
1227
        self.revision = bzr_repo.get_branch_cache(branch).get_revision(revid)
1204
1228
        authors = ";".join(self.revision.get_apparent_authors())
1205
 
        versioncontrol.Changeset.__init__(self,
1206
 
                                          bzr_repo.string_rev(
1207
 
                                              branch, revid),
1208
 
                                          self.revision.message,
1209
 
                                          authors,
1210
 
                                          trac_timestamp(self.revision.timestamp))
 
1229
        self._super_init(bzr_repo,
 
1230
            bzr_repo.string_rev(branch, revid), self.revision.message,
 
1231
            authors, trac_timestamp(self.revision.timestamp))
1211
1232
 
1212
1233
    def __repr__(self):
1213
1234
        return 'BzrChangeset(%r)' % (self.revision.revision_id)