[PATCH] alias: support for $ escaping in shell-alias definition

Steve Losh steve at stevelosh.com
Thu Feb 10 14:51:13 CST 2011


On 02/09/11 at 05:24P, Roman Sokolov wrote:
> # HG changeset patch
> # User Roman Sokolov <sokolov.r.v at gmail.com>
> # Date 1297261323 -10800
> # Node ID f996022846eac117abcdb934c0a6e06e0c25f6c5
> # Parent  8f5c865b7b4a947b6eb2089ea31ebcc91132cc7f
> alias: support for $ escaping in shell-alias definition
> 
> Allows using double sigil in alias definition to avoid its substitution.
> 
> diff -r 8f5c865b7b4a -r f996022846ea mercurial/dispatch.py
> --- a/mercurial/dispatch.py	Tue Feb 01 17:53:50 2011 -0600
> +++ b/mercurial/dispatch.py	Wed Feb 09 17:22:03 2011 +0300
> @@ -224,12 +224,16 @@
>                      if int(m.groups()[0]) <= len(args):
>                          return m.group()
>                      else:
> +                        ui.warn(_(
> +                            "No argument found for substitution of %i variable"
> +                            "in alias definition." % int(m.groups()[0])))

This message doesn't really have anything to do with the $$ escaping, so could
probably be its own patch.

I'm not sure how I feel about the message itself.  It could help catch some
errors, but it would also make some aliases that can normally fail gracefully
more wordy.

I'm 100% for it as a ui.debug message, just a bit wary of a warn().

>                          return ''
> -                cmd = re.sub(r'\$(\d+)', _checkvar, self.definition[1:])
> +                cmd = re.sub(r'(?<!\$)\$(\d+)', _checkvar, self.definition[1:])
>                  replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
>                  replace['0'] = self.name
>                  replace['@'] = ' '.join(args)
> -                cmd = util.interpolate(r'\$', replace, cmd)
> +                cmd = util.interpolate(r'(?<!\$)\$', replace, cmd)
> +                cmd = cmd.replace(r'$$', r'$')

This doesn't quite work.  The problem is that it changes the prefix to "any
$ that doesn't have another $ before it".  Here's an example of where that
breaks:

    [alias]
    sample = !echo '$$$1'

    $ hg sample test
    $$test

The output should actually be '$test' (this first two $'s should collapse into
a literal $, and the third should be combined with the 1 and replaced by the
argument).

I think that using regexes as prefixes in calls to util.interpolate is the
wrong way to do this.  It seems like it would be better to add another
parameter to util.interpolate so that callers could specify an "escape
character" for the prefix and let the function manage the replacement.


>                  return util.system(cmd, environ=env)
>              self.fn = fn
>              return
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

-- 
Steve Losh


More information about the Mercurial-devel mailing list