Mercurial > public > mercurial-scm > hg
comparison mercurial/scmutil.py @ 34456:7757cc48b766
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
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 13 Sep 2016 14:14:05 -0500 |
parents | f61f5af5ed31 |
children | d5c5cc767b7e |
comparison
equal
deleted
inserted
replaced
34455:5c122b410706 | 34456:7757cc48b766 |
---|---|
33 pathutil, | 33 pathutil, |
34 phases, | 34 phases, |
35 pycompat, | 35 pycompat, |
36 revsetlang, | 36 revsetlang, |
37 similar, | 37 similar, |
38 url, | |
38 util, | 39 util, |
39 ) | 40 ) |
40 | 41 |
41 if pycompat.osname == 'nt': | 42 if pycompat.osname == 'nt': |
42 from . import scmwindows as scmplatform | 43 from . import scmwindows as scmplatform |
1014 try: | 1015 try: |
1015 del obj.__dict__[self.name] | 1016 del obj.__dict__[self.name] |
1016 except KeyError: | 1017 except KeyError: |
1017 raise AttributeError(self.name) | 1018 raise AttributeError(self.name) |
1018 | 1019 |
1020 def extdatasource(repo, source): | |
1021 """Gather a map of rev -> value dict from the specified source | |
1022 | |
1023 A source spec is treated as a URL, with a special case shell: type | |
1024 for parsing the output from a shell command. | |
1025 | |
1026 The data is parsed as a series of newline-separated records where | |
1027 each record is a revision specifier optionally followed by a space | |
1028 and a freeform string value. If the revision is known locally, it | |
1029 is converted to a rev, otherwise the record is skipped. | |
1030 | |
1031 Note that both key and value are treated as UTF-8 and converted to | |
1032 the local encoding. This allows uniformity between local and | |
1033 remote data sources. | |
1034 """ | |
1035 | |
1036 spec = repo.ui.config("extdata", source) | |
1037 if not spec: | |
1038 raise error.Abort(_("unknown extdata source '%s'") % source) | |
1039 | |
1040 data = {} | |
1041 if spec.startswith("shell:"): | |
1042 # external commands should be run relative to the repo root | |
1043 cmd = spec[6:] | |
1044 cwd = os.getcwd() | |
1045 os.chdir(repo.root) | |
1046 try: | |
1047 src = util.popen(cmd) | |
1048 finally: | |
1049 os.chdir(cwd) | |
1050 else: | |
1051 # treat as a URL or file | |
1052 src = url.open(repo.ui, spec) | |
1053 | |
1054 try: | |
1055 for l in src.readlines(): | |
1056 if " " in l: | |
1057 k, v = l.strip().split(" ", 1) | |
1058 else: | |
1059 k, v = l.strip(), "" | |
1060 | |
1061 k = encoding.tolocal(k) | |
1062 if k in repo: | |
1063 # we ignore data for nodes that don't exist locally | |
1064 data[repo[k].rev()] = encoding.tolocal(v) | |
1065 finally: | |
1066 src.close() | |
1067 | |
1068 return data | |
1069 | |
1019 def _locksub(repo, lock, envvar, cmd, environ=None, *args, **kwargs): | 1070 def _locksub(repo, lock, envvar, cmd, environ=None, *args, **kwargs): |
1020 if lock is None: | 1071 if lock is None: |
1021 raise error.LockInheritanceContractViolation( | 1072 raise error.LockInheritanceContractViolation( |
1022 'lock can only be inherited while held') | 1073 'lock can only be inherited while held') |
1023 if environ is None: | 1074 if environ is None: |