hgext3rd/evolve/exthelper.py
changeset 4331 594495e1e47e
parent 4330 9d2d0ebc6456
child 4714 c51fc0ae7a7e
equal deleted inserted replaced
4330:9d2d0ebc6456 4331:594495e1e47e
    17 )
    17 )
    18 
    18 
    19 class exthelper(object):
    19 class exthelper(object):
    20     """Helper for modular extension setup
    20     """Helper for modular extension setup
    21 
    21 
    22     A single helper should be instantiated for each extension. Helper
    22     A single helper should be instantiated for each module of an
    23     methods are then used as decorators for various purpose.
    23     extension, where a command or function needs to be wrapped, or a
       
    24     command, extension hook, fileset, revset or template needs to be
       
    25     registered.  Helper methods are then used as decorators for
       
    26     these various purposes.  If an extension spans multiple modules,
       
    27     all helper instances should be merged in the main module.
    24 
    28 
    25     All decorators return the original function and may be chained.
    29     All decorators return the original function and may be chained.
       
    30 
       
    31     Aside from the helper functions with examples below, several
       
    32     registrar method aliases are available for adding commands,
       
    33     configitems, filesets, revsets, and templates.  Simply decorate
       
    34     the appropriate methods, and assign the corresponding exthelper
       
    35     variable to a module level variable of the extension.  The
       
    36     extension loading mechanism will handle the rest.
       
    37 
       
    38     example::
       
    39 
       
    40         # ext.py
       
    41         eh = exthelper.exthelper()
       
    42 
       
    43         # As needed:
       
    44         cmdtable = eh.cmdtable
       
    45         configtable = eh.configtable
       
    46         filesetpredicate = eh.filesetpredicate
       
    47         revsetpredicate = eh.revsetpredicate
       
    48         templatekeyword = eh.templatekeyword
       
    49 
       
    50         @eh.command('mynewcommand',
       
    51             [('r', 'rev', [], _('operate on these revisions'))],
       
    52             _('-r REV...'),
       
    53             helpcategory=command.CATEGORY_XXX)
       
    54         def newcommand(ui, repo, *revs, **opts):
       
    55             # implementation goes here
       
    56 
       
    57         eh.configitem('experimental', 'foo',
       
    58             default=False,
       
    59         )
       
    60 
       
    61         @eh.filesetpredicate('lfs()')
       
    62         def filesetbabar(mctx, x):
       
    63             return mctx.predicate(...)
       
    64 
       
    65         @eh.revsetpredicate('hidden')
       
    66         def revsetbabar(repo, subset, x):
       
    67             args = revset.getargs(x, 0, 0, 'babar accept no argument')
       
    68             return [r for r in subset if 'babar' in repo[r].description()]
       
    69 
       
    70         @eh.templatekeyword('babar')
       
    71         def kwbabar(ctx):
       
    72             return 'babar'
    26     """
    73     """
    27 
    74 
    28     def __init__(self):
    75     def __init__(self):
    29         self._uipopulatecallables = []
    76         self._uipopulatecallables = []
    30         self._uicallables = []
    77         self._uicallables = []
   267         """Decorated function is to be added to the container
   314         """Decorated function is to be added to the container
   268 
   315 
   269         This function takes two arguments, the container and the name of the
   316         This function takes two arguments, the container and the name of the
   270         function to wrap. The wrapping is performed during `uisetup`.
   317         function to wrap. The wrapping is performed during `uisetup`.
   271 
   318 
   272         example::
   319         Adding attributes to a container like this is discouraged, because the
   273 
   320         container modification is visible even in repositories that do not
   274             @eh.function(context.changectx, 'babar')
   321         have the extension loaded.  Therefore, care must be taken that the
       
   322         function doesn't make assumptions that the extension was loaded for the
       
   323         current repository.  For `ui` and `repo` instances, a better option is
       
   324         to subclass the instance in `uipopulate` and `reposetup` respectively.
       
   325 
       
   326         https://www.mercurial-scm.org/wiki/WritingExtensions
       
   327 
       
   328         example::
       
   329 
       
   330             @eh.addattr(context.changectx, 'babar')
   275             def babar(ctx):
   331             def babar(ctx):
   276                 return 'babar' in ctx.description
   332                 return 'babar' in ctx.description
   277         """
   333         """
   278         def dec(func):
   334         def dec(func):
   279             self._duckpunchers.append((container, funcname, func))
   335             self._duckpunchers.append((container, funcname, func))