[PATCH] Add splitlines, wordN, and startswith to templates

Siddharth Agarwal sid at less-broken.com
Sat Apr 12 01:54:54 CDT 2014


On 04/11/2014 11:45 PM, Ryan McElroy wrote:
> # HG changeset patch
> # User Ryan McElroy <ryanmce at gmail.com <mailto:ryanmce at gmail.com>>
> # Date 1397283707 25200
> #      Fri Apr 11 23:21:47 2014 -0700
> # Node ID 5701aea429330d7499f2f3de6fd633559b5dfbf3
> # Parent  40800668e01921e41db1eb97d19e473971e93f5e
> Add splitlines, wordN, and startswith to templates

Please see http://mercurial.selenic.com/wiki/ContributingChanges. In 
particular, this should be split up into multiple patches, each 
introducing a keyword/function, and each with corresponding tests.


>
> This allows for much more useful description parsing techniques using
> templates. For example, in phabrictor-based workflows, the Revision ID 
> can be
> extracted from the description using a template like this:
>
> {splitlines(desc) % '{if(startswith(\"Differential Revision\", line), 
> line|word3|basename)}
>
> diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
> --- a/mercurial/templatefilters.py
> +++ b/mercurial/templatefilters.py
> @@ -302,6 +302,15 @@
>      """:shortdate: Date. Returns a date like "2006-09-18"."""
>      return util.shortdate(text)
>
> +def splitlines(text):
> +    """split text into a list of lines"""
> +    from templatekw import showlist
> +    return showlist('line', text.splitlines(), 'lines')
> +
> +def takeword(n):
> +    """return nth word from a string"""
> +    return lambda s: s.split()[n]
> +
>  def stringescape(text):
>      return text.encode('string_escape')
>
> @@ -384,6 +393,7 @@
>      "short": short,
>      "shortbisect": shortbisect,
>      "shortdate": shortdate,
> +    "splitlines": splitlines,
>      "stringescape": stringescape,
>      "stringify": stringify,
>      "strip": strip,
> @@ -392,6 +402,9 @@
>      "urlescape": urlescape,
>      "user": userfilter,
>      "emailuser": emailuser,
> +    "word1": takeword(0),
> +    "word2": takeword(1),
> +    "word3": takeword(2),

This isn't great. What about words beyond the third one?

FWIW, if there's a need for something specifically like this, we can 
implement and distribute it within FB as an extension.


>      "xmlescape": xmlescape,
>  }
>
> diff --git a/mercurial/templater.py b/mercurial/templater.py
> --- a/mercurial/templater.py
> +++ b/mercurial/templater.py
> @@ -111,7 +111,7 @@
>  def getsymbol(exp):
>      if exp[0] == 'symbol':
>          return exp[1]
> -    raise error.ParseError(_("expected a symbol"))
> +    raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])

This should be a separate patch as well.

>
>  def getlist(x):
>      if not x:
> @@ -464,6 +464,14 @@
>      src = stringify(_evalifliteral(args[2], context, mapping))
>      yield re.sub(pat, rpl, src)
>
> +def startswith(context, mapping, args):
> +    if len(args) != 2:
> +        raise error.ParseError(_("starts_with expects two arguments"))

startswith, not starts_with

> +
> +    patn = stringify(args[0][0](context, mapping, args[0][1]))
> +    text = stringify(args[1][0](context, mapping, args[1][1]))
> +    return text if text.startswith(patn) else ''
> +
>  methods = {
>      "string": lambda e, c: (runstring, e[1]),
>      "rawstring": lambda e, c: (runrawstring, e[1]),
> @@ -488,6 +496,7 @@
>      "revset": revset,
>      "rstdoc": rstdoc,
>      "shortest": shortest,
> +    "startswith": startswith,
>      "strip": strip,
>      "sub": sub,
>  }
>
>
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel



More information about the Mercurial-devel mailing list