Changeset 199 in tracdarcs


Ignore:
Timestamp:
07/30/10 14:08:49 (22 months ago)
Author:
lele@…
Hash name:
20100730120849-7a6fb-6b7c92483ad8f00bbd506a3b70615b4d20432992
Message:

Added a way to group together different repositories, for the "MissingIn?" attribute on changesets

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • README.rst

    r191 r199  
    110110__ http://trac.edgewall.org/wiki/0.12/TracRepositoryAdmin#ExplicitSync 
    111111__ http://darcs.net/manual/node7.html#SECTION00712000000000000000 
     112 
     113Related repositories 
     114-------------------- 
     115 
     116When you manage multiple branches of the same darcs repository, you 
     117may find useful to inform trac+darcs about that, so that it will show 
     118additional properties on each changeset: 
     119 
     120* a list of other "instances" of the same patch, that is when the 
     121  changeset is present in other related repositories, 
     122 
     123* a list of related repositories where the changeset is *not* present. 
     124 
     125To do that, you simply group together the related repositories giving 
     126them a common ``identity``, an arbitrary string. 
     127 
     128You can see current identity of a repository with:: 
     129 
     130  $ trac-admin . repository identity master 
     131  No identity set on repository master 
     132 
     133and you can set it with:: 
     134 
     135  $ trac-admin . repository identity master ProjectFoo 
     136  Identity of repository master set to ProjectFoo 
     137 
     138You can adjust it with:: 
     139 
     140  $ trac-admin . repository identity master ProjectBar 
     141  Identity of repository master set to ProjectBar (was ProjectFoo) 
     142 
     143or remove it:: 
     144 
     145  $ trac-admin . repository identity master "" 
     146  Identity removed from repository oldgam 
  • tracdarcs/components.py

    r197 r199  
    1616from genshi.builder import tag 
    1717 
     18from trac.admin import IAdminCommandProvider 
    1819from trac.config import BoolOption, Option 
    1920from trac.core import Component, implements 
    2021from trac.db import Column, DatabaseManager, Index, Table 
    2122from trac.env import IEnvironmentSetupParticipant 
    22 from trac.util.text import shorten_line, to_unicode 
    23 from trac.versioncontrol import IRepositoryConnector, NoSuchChangeset 
     23from trac.util.text import printout, shorten_line, to_unicode 
     24from trac.versioncontrol import IRepositoryConnector, NoSuchChangeset, \ 
     25                                RepositoryManager 
    2426from trac.versioncontrol.web_ui import IPropertyRenderer, RenderedProperty 
    2527 
     
    131133    """ 
    132134 
    133     implements(IEnvironmentSetupParticipant) 
     135    implements(IAdminCommandProvider, IEnvironmentSetupParticipant) 
    134136 
    135137    def environment_created(self): 
     
    221223                c.execute(stmt) 
    222224 
     225    # IAdminCommandProvider methods 
     226 
     227    def get_admin_commands(self): 
     228        yield ('repository identity', '<repos> [identity]', 
     229               'Get or set the identity tag of a repository', 
     230               self._complete_repos, self._do_repository_identity) 
     231 
     232    def _get_reponames(self): 
     233        rm = RepositoryManager(self.env) 
     234        return [reponame or '(default)' for reponame 
     235                in rm.get_all_repositories()] 
     236 
     237    def _complete_repos(self, args): 
     238        if len(args) == 1: 
     239            return self._get_reponames() 
     240 
     241    def _do_repository_identity(self, reponame, identity=None): 
     242        rm = RepositoryManager(self.env) 
     243        repo = rm.get_repository(reponame) 
     244        if repo is None: 
     245            printout("Invalid repository!") 
     246            return 
     247 
     248        repoid = repo.id 
     249 
     250        db = self.env.get_db_cnx() 
     251        cursor = db.cursor() 
     252 
     253        cursor.execute("SELECT value FROM repository " 
     254                       "WHERE id=%s AND name='identity'", (repoid,)) 
     255        row = cursor.fetchone() 
     256 
     257        if identity is None: 
     258            if row is not None: 
     259                printout("Identity of repository %s: %s" % 
     260                         (reponame, row[0])) 
     261            else: 
     262                printout("No identity set on repository %s" % 
     263                         reponame) 
     264        else: 
     265            @self.env.with_transaction() 
     266            def set_identity(db): 
     267                if row is None and identity: 
     268                    cursor.execute("INSERT INTO repository (id, name, value) " 
     269                                   "VALUES (%s, 'identity', %s)", (repoid, identity)) 
     270                    printout("Identity of repository %s set to %s" % 
     271                             (reponame, identity)) 
     272                elif not identity: 
     273                    if row is not None: 
     274                        cursor.execute("DELETE FROM repository " 
     275                                       "WHERE id=%s AND name='identity'", (repoid,)) 
     276                    printout("Identity removed from repository %s" % 
     277                             reponame) 
     278                elif identity != row[0]: 
     279                    cursor.execute("UPDATE repository SET value=%s " 
     280                                   "WHERE id=%s AND name='identity'", 
     281                                   (identity, repoid)) 
     282                    printout("Identity of repository %s set to %s " 
     283                             "(was %s)" % (reponame, identity, row[0])) 
     284                else: 
     285                    printout("Identity of repository %s is already set to %s" 
     286                             % (reponame, identity)) 
     287 
    223288class EquivalentChangesetsRenderer(Component): 
    224289    implements(IPropertyRenderer) 
    225290 
    226291    def match_property(self, name, mode): 
    227         return (mode == 'revprop' and name == 'EqChangesets') and 5 or 0 
     292        return (mode == 'revprop' and name == 'PresentIn') and 5 or 0 
    228293 
    229294    def render_property(self, name, mode, context, props): 
     
    238303                                content=tag([(link, ', ') for link in eqlinks[:-1]], 
    239304                                            eqlinks[-1])) 
     305 
     306class MissingInReposRenderer(Component): 
     307    implements(IPropertyRenderer) 
     308 
     309    def match_property(self, name, mode): 
     310        return (mode == 'revprop' and name == 'MissingIn') and 5 or 0 
     311 
     312    def render_property(self, name, mode, context, props): 
     313        mir = props[name] 
     314        return RenderedProperty(name='Missing in:', 
     315                                name_attributes=[("class", "property")], 
     316                                content=tag([(repo, ', ') for repo in mir[:-1]], 
     317                                            mir[-1])) 
  • tracdarcs/repository.py

    r198 r199  
    617617        props = dict(Hashname=self.__hash) 
    618618 
     619        # See if there are any "related repository", with a common "identity" 
     620        # property. 
     621 
     622        c = self.repos.db.cursor() 
     623        c.execute("SELECT rep2.id " 
     624                  "FROM repository rep, repository rep2 " 
     625                  "WHERE rep.id=%s" 
     626                  "  AND rep.name='identity'" 
     627                  "  AND rep2.id<>rep.id" 
     628                  "  AND rep2.name='identity'" 
     629                  "  AND rep2.value=rep.value", (self.repos.id,)) 
     630        other_rids = [r[0] for r in c.fetchall()] 
     631 
     632        if not other_rids: 
     633            return props 
     634 
    619635        # Compute a list of "equivalent changesets", when the same 
    620         # changeset is present in other repositories. 
    621  
    622         c = self.repos.db.cursor() 
    623         c.execute('SELECT rep.value, dcs.rev ' 
    624                   'FROM darcs_changesets dcs, darcs_changesets dcs2, repository rep ' 
    625                   'WHERE dcs2.repo_id = %s AND dcs2.rev = %s ' 
    626                   '  AND dcs.hash = dcs2.hash ' 
    627                   '  AND dcs.repo_id <> dcs2.repo_id' 
    628                   '  AND rep.id = dcs.repo_id AND rep.name = \'name\'' 
    629                   'ORDER BY rep.value', (self.repos.id, self.rev)) 
     636        # changeset is present in other related repositories. 
     637 
     638        other_rids = ','.join(str(rid) for rid in other_rids), 
     639 
     640        c.execute("SELECT rep.value, dcs.rev " 
     641                  "FROM darcs_changesets dcs, repository rep " 
     642                  "WHERE dcs.hash = %%s" 
     643                  "  AND dcs.repo_id IN (%s)" 
     644                  "  AND rep.id = dcs.repo_id AND rep.name = 'name'" 
     645                  "ORDER BY rep.value" % other_rids, 
     646                  (self.__hash,)) 
    630647        eqcsets = [(repo, rev) for repo,rev in c.fetchall()] 
    631         if eqcsets: 
    632             props['EqChangesets'] = eqcsets 
     648        props['PresentIn'] = eqcsets 
     649 
     650        # Compute the opposite list, that is the repositories where 
     651        # the changeset is missing. 
     652 
     653        c.execute("SELECT rep.value " 
     654                  "FROM repository rep " 
     655                  "WHERE rep.name='name'" 
     656                  "  AND rep.id IN (%s)" 
     657                  "  AND NOT EXISTS (" 
     658                  "SELECT dcs.rev " 
     659                  "FROM darcs_changesets dcs " 
     660                  "WHERE dcs.repo_id=rep.id" 
     661                  "  AND dcs.hash=%%s) " 
     662                  "ORDER BY rep.value" % other_rids, 
     663                  (self.__hash,)) 
     664        mir = [r[0] for r in c.fetchall()] 
     665        props['MissingIn'] = mir 
    633666 
    634667        return props 
Note: See TracChangeset for help on using the changeset viewer.