Edgewall Software

Ticket #7687: svn-externals-7687-2.patch

File svn-externals-7687-2.patch, 6.2 KB (added by eblot, 3 years ago)

New version of the patch: svn:url removed (use svn:externals instead), simpler implementation

  • trac/versioncontrol/svn_fs.py

     
    321321     
    322322    def render_property(self, name, mode, context, props): 
    323323        if name == 'svn:externals': 
    324             return self._render_externals(props[name]) 
     324            return self._render_externals(props[name], context) 
    325325        elif name == 'svn:mergeinfo' or name.startswith('svnmerge-'): 
    326326            return self._render_mergeinfo(props[name]) 
    327327        elif name == 'svn:needs-lock': 
    328328            return self._render_needslock(context) 
    329329 
    330     def _render_externals(self, prop): 
     330    def _render_externals(self, prop, context): 
    331331        if not self._externals_map: 
    332332            for dummykey, value in self.config.options('svn:externals'): 
    333333                value = value.split() 
     
    340340                self._externals_map[key] = value.replace('%', '%%') \ 
    341341                                           .replace('$path', '%(path)s') \ 
    342342                                           .replace('$rev', '%(rev)s') 
    343         externals = [] 
     343        externals_data = [] 
     344        def add_externals_url(localpath, url, rev, href):  
     345            label = localpath 
     346            if url is None: 
     347                title = '' 
     348            elif href: 
     349                if rev: 
     350                    title = _('%s at revision %s' % (url, rev)) 
     351                else: 
     352                    title = url 
     353                if url: 
     354                    label = _('%s in %s' % (localpath, title)) 
     355            else: 
     356                title = _('No svn:externals configured in trac.ini') 
     357            externals_data.append((label, href, title)) 
    344358        for external in prop.splitlines(): 
    345359            elements = external.split() 
    346360            if not elements: 
    347361                continue 
    348             localpath, rev, url = elements[0], '', elements[-1] 
    349             if localpath.startswith('#'): 
    350                 externals.append((external, None, None, None, None)) 
    351                 continue 
    352             if len(elements) == 3: 
    353                 rev = elements[1] 
    354                 rev = rev.replace('-r', '') 
     362            if elements[-1].find(u'://') != -1: 
     363                # old-style externals syntax 
     364                localpath, rev, url = elements[0], '', elements[-1] 
     365                if localpath.startswith('#'): 
     366                    externals_data.append((external, None, None)) 
     367                    continue 
     368                if len(elements) > 2: 
     369                    rev = elements[len(elements)==4 and 3 or 2] 
     370                    rev = rev.replace('-r', '') 
     371            elif len(elements) > 1: 
     372                # new-style externals syntax 
     373                resource = context.resource 
     374                localpath = resource.id 
     375                url, localpath = elements[-2], elements[-1] 
     376                if len(elements) > 2: 
     377                    rev = elements[len(elements)==4 and 1 or 0] 
     378                    rev = rev.replace('-r', '') 
     379                else: 
     380                    rev = '' 
     381                    if '@' in url: 
     382                        (url, rev) = url.split('@')  
     383                if url.startswith(u'^/'): 
     384                    # relative to repository root 
     385                    href = context.req.href.browser(url[1:], rev=rev) 
     386                    add_externals_url(localpath, url[1:], rev, href) 
     387                    continue 
     388                elif url.startswith(u'../'): 
     389                    # relative to the directory 
     390                    remotepath = localpath 
     391                    while url.startswith(u'../'): 
     392                        url = url[3:] 
     393                        (remotepath, child) = posixpath.split(remotepath) 
     394                    remotepath = posixpath.join('/'+remotepath, url) 
     395                    href = context.req.href.browser(url, rev=rev) 
     396                    add_externals_url(localpath, remotepath, rev, href) 
     397                    continue 
     398                elif url.startswith(u'/'): 
     399                    # relative to server root or to scheme 
     400                    while url.startswith(u'//'): 
     401                        # relative to scheme, handle as server root 
     402                        url = url[1:]  
     403                    # relative to server root 
    355404            # retrieve a matching entry in the externals map 
    356405            prefix = [] 
    357406            base_url = url 
    358407            while base_url: 
    359408                if base_url in self._externals_map or base_url==u'/': 
    360409                    break 
     410                if base_url.endswith(':'): 
     411                    prefix.append(base_url+'//') 
     412                    base_url = '' 
     413                    break 
    361414                base_url, pref = posixpath.split(base_url) 
    362415                prefix.append(pref) 
    363416            href = self._externals_map.get(base_url) 
    364             revstr = rev and ' at revision '+rev or '' 
    365417            if not href and (url.startswith('http://') or  
    366418                             url.startswith('https://')): 
    367419                href = url.replace('%', '%%') 
     
    369421                remotepath = '' 
    370422                if prefix: 
    371423                    remotepath = posixpath.join(*reversed(prefix)) 
    372                 externals.append((localpath, revstr, base_url, remotepath, 
    373                                   href % {'path': remotepath, 'rev': rev})) 
     424                add_externals_url(localpath, url, rev, 
     425                                  href % {'path': remotepath, 'rev': rev}) 
    374426            else: 
    375                 externals.append((localpath, revstr, url, None, None)) 
    376         externals_data = [] 
    377         for localpath, rev, url, remotepath, href in externals: 
    378             label = localpath 
    379             if url is None: 
    380                 title = '' 
    381             elif href: 
    382                 if url: 
    383                     url = ' in ' + url 
    384                 label += rev + url 
    385                 title = ''.join((remotepath, rev, url)) 
    386             else: 
    387                 title = _('No svn:externals configured in trac.ini') 
    388             externals_data.append((label, href, title)) 
     427                add_externals_url(localpath, url, rev, None) 
    389428        return tag.ul([tag.li(tag.a(label, href=href, title=title)) 
    390429                       for label, href, title in externals_data]) 
    391430