[PATCH 1 of 7] extdata: add extdatasource reader
Yuya Nishihara
yuya at tcha.org
Sun Oct 1 12:00:12 UTC 2017
# HG changeset patch
# User Matt Mackall <mpm at selenic.com>
# Date 1473794045 18000
# Tue Sep 13 14:14:05 2016 -0500
# Node ID 4bcad24c850624811d6f4d1aa6d982c01270d2fd
# Parent 8a89dfa01997bb3dd9e89aa167f2b28ed865e9fc
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>
urls of the form shell: are launch shell commands to generate data.
This patch is slightly modified by Yuya Nishihara as follows:
- fix typo
- remove unused function
- remove future expansion point for parameter (which can be added later
as the extdata revset/template are experimental)
You can see the original patch at
https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-September/088426.html
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -35,6 +35,7 @@ from . import (
pycompat,
revsetlang,
similar,
+ url,
util,
)
@@ -1016,6 +1017,56 @@ class filecache(object):
except KeyError:
raise AttributeError(self.name)
+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 error.Abort(_("unknown extdata source '%s'") % source)
+
+ 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
+
def _locksub(repo, lock, envvar, cmd, environ=None, *args, **kwargs):
if lock is None:
raise error.LockInheritanceContractViolation(
More information about the Mercurial-devel
mailing list