On Thu, Sep 22, 2016 at 11:21 AM, Matt Mackall <m...@selenic.com> wrote:
> # HG changeset patch > # User Matt Mackall <m...@selenic.com> > # Date 1473794045 18000 > # Tue Sep 13 14:14:05 2016 -0500 > # Node ID 19bf2776dfe39befdc479253e1e7d030b41c08f9 > # Parent 5271ae66615207f39cc41d78f4541bc6f8ca6ff6 > extdata: add extdatasource reader > > This adds basic support for extdata, a way to add external data > sources for revsets and templates. An extdata data source is simply a > list of lines of the form: > > <revision identifier>[<space><freeform text>]\n > > An extdata source is configured thusly: > > [extdata] > name = <a url or path> > I like "extdata" for internal terminology but I have hesitations about using an abbreviation in the user-facing config. How about [externaldata]? Or perhaps something more generic like [datasource(s)]? > > urls of the form shell: are launch shell commands to generate data. > > diff -r 5271ae666152 -r 19bf2776dfe3 mercurial/scmutil.py > --- a/mercurial/scmutil.py Wed Sep 21 17:05:27 2016 -0400 > +++ b/mercurial/scmutil.py Tue Sep 13 14:14:05 2016 -0500 > @@ -29,6 +29,7 @@ > phases, > revset, > similar, > + url, > util, > ) > > @@ -1418,3 +1419,66 @@ > return > > self._queue.put(fh, block=True, timeout=None) > + > +def extdatasources(repo): > + sources = set() > + for k, v in repo.ui.configitems("extdata"): > + sources.add(k) > + return sources > + > +def extdatasource(repo, source): > + """gather a map of rev -> value dict from the specified source > + > + A source spec is treated as a URL, with a special case shell: type > + for parsing the output from a shell command. > + > + The data is parsed as a series of newline-separated records where > + each record is a revision specifier optionally followed by a space > + and a freeform string value. If the revision is known locally, it > + is converted to a rev, otherwise the record is skipped. > + > + Note that both key and value are treated as UTF-8 and converted to > + the local encoding. This allows uniformity between local and > + remote data sources. > + """ > + > + spec = repo.ui.config("extdata", source) > + if not spec: > + raise util.Abourt(_("unknown extdata source '%s'") % source) > + > + try: > + # prepare for future expansion > + expand = spec % () > + except TypeError: > + raise error.Abort(_("extdata doesn't support parameters yet"), > + hint=_("use double % for escaping")) > + > + data = {} > + if spec.startswith("shell:"): > + # external commands should be run relative to the repo root > + cmd = spec[6:] > + cwd = os.getcwd() > + os.chdir(repo.root) > + try: > + src = util.popen(cmd) > + finally: > + os.chdir(cwd) > + else: > + # treat as a URL or file > + src = url.open(repo.ui, spec) > + > + try: > + for l in src.readlines(): > + if " " in l: > + k, v = l.strip().split(" ", 1) > + else: > + k, v = l.strip(), "" > + > + k = encoding.tolocal(k) > + if k in repo: > + # we ignore data for nodes that don't exist locally > + data[repo[k].rev()] = encoding.tolocal(v) > + finally: > + src.close() > + > + return data > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >
_______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel