Edgewall Software

Ticket #7706: 7706-repo-resource-r8643.2.patch

File 7706-repo-resource-r8643.2.patch, 22.3 KB (added by rblank, 2 years ago)

Combinded patch including attachment:repo_index_repo_resources.diff

  • sample-plugins/commit_ticket_update.py

    diff --git a/sample-plugins/commit_ticket_update.py b/sample-plugins/commit_ticket_update.py
    a b  
    275275                             "ticket)", class_='hint') 
    276276        if ChangesetModule(self.env).wiki_format_messages: 
    277277            return tag.div(format_to_html(self.env, 
    278                 formatter.context('changeset', (reponame, changeset.rev)), 
     278                formatter.context('changeset', changeset.rev, 
     279                                  parent=Resource('repository', reponame)), 
    279280                changeset.message, escape_newlines=True), class_='message') 
    280281        else: 
    281282            return tag.pre(changeset.message, class_='message') 
  • trac/mimeview/api.py

    diff --git a/trac/mimeview/api.py b/trac/mimeview/api.py
    a b  
    128128 
    129129    @classmethod 
    130130    def from_request(cls, req, resource=None, id=False, version=False, 
    131                      absurls=False): 
     131                     parent=False, absurls=False): 
    132132        """Create a rendering context from a request. 
    133133 
    134134        The `perm` and `href` properties of the context will be initialized 
     
    158158        else: 
    159159            href = None 
    160160            perm = None 
    161         self = cls(Resource(resource, id=id, version=version), href=href, 
    162                    perm=perm) 
     161        self = cls(Resource(resource, id=id, version=version, parent=parent), 
     162                   href=href, perm=perm) 
    163163        self.req = req 
    164164        return self 
    165165 
     
    172172            context = context.parent 
    173173        return '<%s %s>' % (type(self).__name__, ' - '.join(reversed(path))) 
    174174 
    175     def __call__(self, resource=None, id=False, version=False): 
     175    def __call__(self, resource=None, id=False, version=False, parent=False): 
    176176        """Create a nested rendering context. 
    177177 
    178178        `self` will be the parent for the new nested context. 
     
    196196        True 
    197197        """ 
    198198        if resource: 
    199             resource = Resource(resource, id=id, version=version) 
     199            resource = Resource(resource, id=id, version=version, 
     200                                parent=parent) 
    200201        else: 
    201202            resource = self.resource 
    202203        context = Context(resource, href=self.href, perm=self.perm) 
  • trac/resource.py

    diff --git a/trac/resource.py b/trac/resource.py
    a b  
    187187        resource.parent = parent 
    188188        return resource 
    189189 
    190  
    191190    def __call__(self, realm=False, id=False, version=False, parent=False): 
    192191        """Create a new Resource using the current resource as a template. 
    193192 
     
    206205        >>> repr(Resource(None).child('attachment', 'file.txt')) 
    207206        "<Resource u', attachment:file.txt'>" 
    208207        """ 
    209         return self.__call__(realm, id, version, self) 
    210      
     208        return Resource(realm, id, version, self) 
    211209 
    212210 
    213211class ResourceSystem(Component): 
  • trac/versioncontrol/api.py

    diff --git a/trac/versioncontrol/api.py b/trac/versioncontrol/api.py
    a b  
    3333from trac.web.api import IRequestFilter 
    3434 
    3535 
     36def split_vc_resource(resource): 
     37    """Split a versioncontrol resource into reponame and path.""" 
     38    assert resource.parent.realm == 'repository' 
     39    return (resource.parent.id, resource.id) 
     40 
     41 
    3642class IRepositoryConnector(Interface): 
    3743    """Provide support for a specific version control system.""" 
    3844 
     
    343349 
    344350    # IResourceManager methods 
    345351 
    346     # Note: with multiple repository support, the repository name becomes 
    347     #       part of the 'id', which becomes a `(reponame, rev or path)` pair. 
    348  
    349352    def get_resource_realms(self): 
    350353        yield 'changeset' 
    351354        yield 'source' 
     355        yield 'repository' 
    352356 
    353357    def get_resource_description(self, resource, format=None, **kwargs): 
    354         reponame, id = resource.id 
    355358        if resource.realm == 'changeset': 
     359            (reponame, id) = split_vc_resource(resource) 
    356360            if reponame: 
    357361                return _("Changeset %(rev)s in %(repo)s", rev=id, repo=reponame) 
    358362            else: 
    359363                return _("Changeset %(rev)s", rev=id) 
    360364        elif resource.realm == 'source': 
     365            (reponame, id) = split_vc_resource(resource) 
    361366            version = in_repo = '' 
    362367            if format == 'summary': 
    363368                repos = resource.env.get_repository(reponame) 
     
    375380            if reponame: 
    376381                in_repo = _(" in %(repo)s", repo=reponame) 
    377382            return ''.join([kind, ' ', id, version, in_repo]) 
     383        elif resource.realm == 'repository': 
     384            return _("Repository %(repo)s", repo=resource.id) 
    378385 
    379386    def get_resource_url(self, resource, href, **kwargs): 
    380         if resource and resource.realm in ('source', 'changeset'): 
    381             repos, id = resource.id 
    382             if resource.realm == 'source': 
    383                 return href.source(repos, id) 
    384             else: 
    385                 return href.changeset(id, repos) 
     387        if resource.realm == 'changeset': 
     388            (reponame, id) = split_vc_resource(resource) 
     389            return href.changeset(id, reponame) 
     390        elif resource.realm == 'source': 
     391            (reponame, id) = split_vc_resource(resource) 
     392            return href.source(reponame, id) 
     393        elif resource.realm == 'repository': 
     394            return href.source(resource.id) 
    386395 
    387396    # IRepositoryProvider methods 
    388397 
     
    524533        """ 
    525534        while context: 
    526535            if context.resource.realm in ('source', 'changeset'): 
    527                 return context.resource.id[0] 
     536                return context.resource.parent.id 
    528537            context = context.parent 
    529538 
    530539    def get_all_repositories(self): 
  • trac/versioncontrol/svn_prop.py

    diff --git a/trac/versioncontrol/svn_prop.py b/trac/versioncontrol/svn_prop.py
    a b  
    2121from genshi.builder import tag 
    2222 
    2323from trac.core import * 
    24 from trac.versioncontrol import NoSuchNode 
     24from trac.versioncontrol import NoSuchNode, split_vc_resource 
    2525from trac.versioncontrol.svn_fs import _path_within_scope 
    2626from trac.versioncontrol.web_ui.browser import IPropertyRenderer 
    2727from trac.versioncontrol.web_ui.changeset import IPropertyDiffRenderer 
     
    147147        has_eligible = name in ('svnmerge-integrated', 'svn:mergeinfo') 
    148148        revs_label = (_('merged'), _('blocked'))[name.endswith('blocked')] 
    149149        revs_cols = has_eligible and 2 or None 
    150         (reponame, target_path) = context.resource.id 
     150        (reponame, target_path) = split_vc_resource(context.resource) 
    151151        repos = self.env.get_repository(reponame) 
    152152        target_rev = context.resource.version 
    153153        if has_eligible: 
     
    170170            deleted = False 
    171171            try: 
    172172                node = repos.get_node(spath, target_rev) 
    173                 if 'LOG_VIEW' in context.perm('source', spath): 
     173                resource = context.resource.parent.child('source', spath) 
     174                if 'LOG_VIEW' in context.perm(resource): 
    174175                    row = [_get_source_link(spath, context), 
    175176                           _get_revs_link(revs_label, context, spath, revs)] 
    176177                    if has_eligible: 
     
    228229 
    229230def _get_source_link(spath, context): 
    230231    """Return a link to a merge source.""" 
    231     reponame = context.resource.id[0] 
     232    reponame = context.resource.parent.id 
    232233    return tag.a('/' + spath, title=_('View merge source'), 
    233234                 href=context.href.browser(reponame, spath, 
    234235                                           rev=context.resource.version)) 
     
    238239    given, to the revision itself for a single revision, or a `<span>` 
    239240    with "no revision" for none. 
    240241    """ 
    241     reponame = context.resource.id[0] 
     242    reponame = context.resource.parent.id 
    242243    if not revs: 
    243244        return tag.span(label, title=_('No revisions')) 
    244245    elif ',' in revs or '-' in revs: 
     
    262263        # Build 3 columns table showing modifications on merge sources 
    263264        # || source || added revs || removed revs || 
    264265        # || source || removed                    || 
    265         repos = self.env.get_repository(old_context.resource.id[0]) 
     266        repos = self.env.get_repository(old_context.resource.parent.id) 
    266267        def parse_sources(props): 
    267268            sources = {} 
    268269            for line in props[name].splitlines(): 
  • trac/versioncontrol/templates/browser.html

    diff --git a/trac/versioncontrol/templates/browser.html b/trac/versioncontrol/templates/browser.html
    a b  
    111111        <tr py:if="file"> 
    112112          <td class="message searchable" py:choose=""> 
    113113            <py:when test="wiki_format_messages" xml:space="preserve"> 
    114               ${wiki_to_html(context('changeset', (reponame, file.changeset.rev)), file.changeset.message, escape_newlines=True)} 
     114              ${wiki_to_html(context('changeset', file.changeset.rev, parent=repos_resource), 
     115                             file.changeset.message, escape_newlines=True)} 
    115116            </py:when> 
    116117            <py:otherwise>${file.changeset.message}</py:otherwise> 
    117118          </td> 
  • trac/versioncontrol/templates/changeset.html

    diff --git a/trac/versioncontrol/templates/changeset.html b/trac/versioncontrol/templates/changeset.html
    a b  
    122122            &nbsp; 
    123123            </py:when> 
    124124            <py:when test="wiki_format_messages"> 
    125               ${wiki_to_html(context('changeset', (reponame, changeset.rev)), changeset.message,  
    126                              escape_newlines=True)} 
     125              ${wiki_to_html(context('changeset', changeset.rev, parent=repos_resource), 
     126                             changeset.message, escape_newlines=True)} 
    127127            </py:when> 
    128128            <py:otherwise><pre>${changeset.message}</pre></py:otherwise> 
    129129          </dd> 
  • trac/versioncontrol/templates/dir_entries.html

    diff --git a/trac/versioncontrol/templates/dir_entries.html b/trac/versioncontrol/templates/dir_entries.html
    a b  
    2424        </td> 
    2525        <td class="change"> 
    2626          <span class="author" py:if="change">${authorinfo(change.author)}:</span> 
    27           <span class="change" py:choose="" py:with="chgset_context = context('changeset', (reponame, change.rev))"> 
     27          <span class="change" py:choose="" 
     28                py:with="chgset_context = context('changeset', change.rev, parent=repos_resource)"> 
    2829            <py:when test="not change or 'CHANGESET_VIEW' not in perm(chgset_context.resource)">-</py:when> 
    2930            <py:when test="wiki_format_messages"> 
    3031              ${change and wiki_to_oneliner(chgset_context, change.message, shorten=True)} 
  • trac/versioncontrol/templates/repository_index.html

    diff --git a/trac/versioncontrol/templates/repository_index.html b/trac/versioncontrol/templates/repository_index.html
    a b  
    2828          </td> 
    2929          <td class="change"> 
    3030            <span class="author" py:if="change">${authorinfo(change.author)}:</span> 
    31             <span class="change" py:choose="" py:with="chgset_context = context('changeset', (reponame, change.rev))"> 
     31            <span class="change" py:choose="" 
     32                  py:with="chgset_context = context('changeset', change.rev, parent=Resource('repository', reponame))"> 
    3233              <em py:when="err" py:content="err" /> 
    3334              <py:when test="not change or 'CHANGESET_VIEW' not in perm(chgset_context.resource)">-</py:when> 
    3435              <py:when test="wiki_format_messages"> 
  • trac/versioncontrol/templates/revisionlog.html

    diff --git a/trac/versioncontrol/templates/revisionlog.html b/trac/versioncontrol/templates/revisionlog.html
    a b  
    110110            <py:for each="idx, item in enumerate(items)"> 
    111111              <py:with vars="change = changes[item.rev]; 
    112112                             is_separator = item.change is None; 
    113                              chgset_context = context('changeset', (reponame, change.rev)); 
     113                             chgset_context = context('changeset', change.rev, parent=repos_resource); 
    114114                             chgset_view = 'CHANGESET_VIEW' in perm(chgset_context.resource); 
    115115                             odd_even = idx % 2 and 'odd' or 'even'"> 
    116116                <!--! highlight copy or rename operations --> 
  • trac/versioncontrol/templates/revisionlog.rss

    diff --git a/trac/versioncontrol/templates/revisionlog.rss b/trac/versioncontrol/templates/revisionlog.rss
    a b  
    1717 
    1818    <item py:for="item in items"  
    1919          py:with="change = changes[item.rev];  
    20                    item_context = context('changeset', (reponame, change.rev))"> 
     20                   item_context = context('changeset', change.rev, parent=repos_resource))"> 
    2121      ${author_or_creator(change.author, email_map)} 
    2222      <pubDate>${http_date(change.date)}</pubDate> 
    2323      <title>Revision $item.rev: ${shorten_line(change.message)}</title> 
  • trac/versioncontrol/web_ui/browser.py

    diff --git a/trac/versioncontrol/web_ui/browser.py b/trac/versioncontrol/web_ui/browser.py
    a b  
    2828from trac.mimeview.api import Mimeview, is_binary, get_mimetype, \ 
    2929                              IHTMLPreviewAnnotator, Context 
    3030from trac.perm import IPermissionRequestor 
    31 from trac.resource import ResourceNotFound, Resource 
     31from trac.resource import Resource, ResourceNotFound 
    3232from trac.util import embedded_numbers 
    3333from trac.util.compat import all 
    3434from trac.util.datefmt import http_date, utc 
     
    4141from trac.wiki.api import IWikiSyntaxProvider, IWikiMacroProvider, parse_args 
    4242from trac.wiki.formatter import format_to_html, format_to_oneliner 
    4343from trac.versioncontrol.api import RepositoryManager, NoSuchChangeset, \ 
    44                                     NoSuchNode 
     44                                    NoSuchNode, split_vc_resource 
    4545from trac.versioncontrol.web_ui.util import * 
    4646 
    4747 
     
    361361                rev_or_latest = rev or repos.youngest_rev 
    362362                node = get_existing_node(req, repos, path, rev_or_latest) 
    363363            except NoSuchChangeset, e: 
    364                 raise ResourceNotFound(e.message, _('Invalid Changeset Number')) 
     364                raise ResourceNotFound(e.message, 
     365                                       _('Invalid changeset number')) 
    365366 
    366             context = context('source', (reponame, path), node.created_rev) 
     367            repos_resource = Resource('repository', reponame) 
     368            context = context(repos_resource.child('source', path, 
     369                                                   version=node.created_rev)) 
    367370 
    368371        # Prepare template data 
    369372        path_links = get_path_links(req.href, reponame, path, rev, order, desc) 
     
    390393 
    391394        data = { 
    392395            'context': context, 'reponame': reponame or None, 
     396            'repos_resource': repos and repos_resource, 
    393397            'path': path, 'rev': node and node.rev, 'stickyrev': rev, 
    394398            'created_path': node and node.created_path, 
    395399            'created_rev': node and node.created_rev, 
     
    789793    def __init__(self, env, context): 
    790794        self.env = env 
    791795        self.context = context 
    792         # `context`'s resource is ('source', (reponame, path), version=rev) 
    793         r = context.resource 
    794         self.reponame, self.path = r.id 
     796        (self.reponame, self.path) = split_vc_resource(context.resource) 
    795797        self.repos = env.get_repository(self.reponame) 
    796         self.rev = r.version 
     798        self.rev = context.resource.version 
    797799        # maintain state 
    798800        self.prev_chgset = None 
    799801        self.chgset_data = {} 
  • trac/versioncontrol/web_ui/changeset.py

    diff --git a/trac/versioncontrol/web_ui/changeset.py b/trac/versioncontrol/web_ui/changeset.py
    a b  
    307307        data['wiki_format_messages'] = self.wiki_format_messages 
    308308 
    309309        if chgset: 
    310             req.perm('changeset', new).require('CHANGESET_VIEW') 
     310            resource = Resource('repository', reponame).child('changeset', new) 
     311            req.perm(resource).require('CHANGESET_VIEW') 
    311312            chgset = repos.get_changeset(new) 
    312313 
    313314            # TODO: find a cheaper way to reimplement r2636 
     
    408409            title = _changeset_title(rev) 
    409410 
    410411            # Support for revision properties (#2545) 
    411             context = Context.from_request(req, 'changeset',  
    412                                            (reponame, chgset.rev)) 
     412            repos_resource = Resource('repository', reponame) 
     413            data['repos_resource'] = repos_resource 
     414            context = Context.from_request(req, 'changeset', chgset.rev, 
     415                                           parent=repos_resource) 
    413416            revprops = chgset.get_properties() 
    414417            data['properties'] = browser.render_properties('revprop', context, 
    415418                                                           revprops) 
     
    485488        #           with _that_ node specific history... 
    486489 
    487490        options = data['diff']['options'] 
     491        repos_resource = Resource('repository', reponame) 
    488492 
    489493        def _prop_changes(old_node, new_node): 
    490             old_source = Resource('source', (reponame, old_node.created_path), 
    491                                   version=old_node.created_rev) 
    492             new_source = Resource('source', (reponame, new_node.created_path), 
    493                                   version=new_node.created_rev) 
     494            old_source = Resource('source', old_node.created_path, 
     495                                  version=old_node.created_rev, 
     496                                  parent=repos_resource) 
     497            new_source = Resource('source', new_node.created_path, 
     498                                  version=new_node.created_rev, 
     499                                  parent=repos_resource) 
    494500            old_props = new_props = [] 
    495501            if 'FILE_VIEW' in req.perm(old_source): 
    496502                old_props = old_node.get_properties() 
     
    854860                 
    855861            uids_seen = {} 
    856862            def generate_changesets(reponame, repos): 
     863                repos_resource = Resource('repository', reponame) 
    857864                for _, changesets in groupby(repos.get_changesets(start, stop), 
    858865                                             key=collapse_changesets): 
    859866                    viewable_changesets = [] 
    860867                    for cset in changesets: 
    861                         cset_resource = Resource('changeset',  
    862                                                  (reponame, cset.rev)) 
     868                        cset_resource = Resource('changeset', cset.rev, 
     869                                                 parent=repos_resource) 
    863870                        if 'CHANGESET_VIEW' in req.perm(cset_resource): 
    864871                            repos_for_uid = [reponame] 
    865872                            uid = repos.get_changeset_uid(cset.rev) 
     
    885892        changesets, show_location, show_files = event[3] 
    886893        cset, cset_resource, repos_for_uid = changesets[0] 
    887894        message = cset.message or '' 
    888         reponame = cset_resource.id[0] # first repo 
     895        reponame = cset_resource.parent.id 
    889896        rev_b, rev_a = cset.rev, cset.rev 
    890897 
    891898        if field == 'url': 
     
    10011008            path = None 
    10021009 
    10031010        # rendering changeset link 
    1004         if repos and 'CHANGESET_VIEW' in formatter.perm('changeset',  
    1005                                                         (reponame, rev)): 
     1011        resource = Resource('repository', reponame).child('changeset', rev) 
     1012        if repos and 'CHANGESET_VIEW' in formatter.perm(resource): 
    10061013            try: 
    10071014                changeset = repos.get_changeset(rev) 
    10081015                href = formatter.href.changeset(rev, reponame or None, path) 
     
    10731080            #cset = Resource('repository', reponame).child('changeset' , rev) 
    10741081            #cset = repos.resource.child('changeset' , rev) 
    10751082            #cset = repos.changeset_resource(rev) 
    1076             cset = Resource('changeset', (reponame, rev)) 
     1083            cset = Resource('repository', reponame).child('changeset', rev) 
    10771084            if 'CHANGESET_VIEW' in req.perm(cset): 
    10781085                yield (req.href.changeset(rev, reponame), 
    10791086                       '[%s]: %s' % (rev, shorten_line(log)), 
  • trac/versioncontrol/web_ui/log.py

    diff --git a/trac/versioncontrol/web_ui/log.py b/trac/versioncontrol/web_ui/log.py
    a b  
    2626from trac.core import * 
    2727from trac.mimeview import Context 
    2828from trac.perm import IPermissionRequestor 
     29from trac.resource import Resource 
    2930from trac.util import Ranges 
    3031from trac.util.compat import any 
    3132from trac.util.datefmt import http_date 
     
    8586 
    8687        reponame, repos, path = RepositoryManager(self.env).\ 
    8788                get_repository_by_path(path, req.authname) 
     89        repos_resource = Resource('repository', reponame) 
    8890 
    8991        normpath = repos.normalize_path(path) 
    9092        # if `revs` parameter is given, then we're restricted to the  
     
    253255        if range: 
    254256            item_ranges.append(range) 
    255257        data = { 
    256             'context': Context.from_request(req, 'source', (reponame, path)), 
    257             'reponame': reponame,  
     258            'context': Context.from_request(req, 'source', path, 
     259                                            parent=repos_resource), 
     260            'reponame': reponame, 'repos_resource': repos_resource, 
    258261            'path': path, 'rev': rev, 'stop_rev': stop_rev, 
    259262            'path': path, 'rev': rev, 'stop_rev': stop_rev,  
    260263            'revranges': revranges, 
     
    269272            return 'revisionlog.txt', data, 'text/plain' 
    270273        elif req.args.get('format') == 'rss': 
    271274            data['context'] = Context.from_request(req, 'source',  
    272                                                    (reponame, path), 
     275                                                   path, parent=repos_resource, 
    273276                                                   absurls=True) 
    274277            return 'revisionlog.rss', data, 'application/rss+xml' 
    275278 
  • trac/web/chrome.py

    diff --git a/trac/web/chrome.py b/trac/web/chrome.py
    a b  
    666666 
    667667        d.update({ 
    668668            'context': req and Context.from_request(req) or None, 
     669            'Resource': Resource, 
    669670            'url_of': get_rel_url, 
    670671            'abs_url_of': get_abs_url, 
    671672            'name_of': partial(get_resource_name, self.env),