comparison mercurial/scmutil.py @ 31553:56acc4250900

scmutil: add a simple key-value file helper The purpose of the added class is to serve purposes like save files of shelve or state files of shelve, rebase and histedit. Keys of these files can be alphanumeric and start with letters, while values must not contain newlines. In light of Mercurial's reluctancy to use Python's json module, this tries to provide a reasonable alternative for a non-nested named data. Comparing to current approach of storing state in plain text files, where semantic meaning of lines of text is only determined by their oreder, simple key-value file allows for reordering lines and thus helps handle optional values. Initial use-case I see for this is obs-shelve's shelve files. Later we can possibly migrate state files to this approach. The test is in a new file beause I did not figure out where to put it within existing test suite. If you give me a better idea, I will gladly follow it.
author Kostia Balytskyi <ikostia@fb.com>
date Fri, 10 Mar 2017 14:33:42 -0800
parents 1fc3d1f02865
children 0f8ba0bc1154
comparison
equal deleted inserted replaced
31552:d0b9e9803caf 31553:56acc4250900
963 def gddeltaconfig(ui): 963 def gddeltaconfig(ui):
964 """helper function to know if incoming delta should be optimised 964 """helper function to know if incoming delta should be optimised
965 """ 965 """
966 # experimental config: format.generaldelta 966 # experimental config: format.generaldelta
967 return ui.configbool('format', 'generaldelta', False) 967 return ui.configbool('format', 'generaldelta', False)
968
969 class simplekeyvaluefile(object):
970 """A simple file with key=value lines
971
972 Keys must be alphanumerics and start with a letter, values must not
973 contain '\n' characters"""
974
975 def __init__(self, vfs, path, keys=None):
976 self.vfs = vfs
977 self.path = path
978
979 def read(self):
980 lines = self.vfs.readlines(self.path)
981 try:
982 d = dict(line[:-1].split('=', 1) for line in lines if line)
983 except ValueError as e:
984 raise error.CorruptedState(str(e))
985 return d
986
987 def write(self, data):
988 """Write key=>value mapping to a file
989 data is a dict. Keys must be alphanumerical and start with a letter.
990 Values must not contain newline characters."""
991 lines = []
992 for k, v in data.items():
993 if not k[0].isalpha():
994 e = "keys must start with a letter in a key-value file"
995 raise error.ProgrammingError(e)
996 if not k.isalnum():
997 e = "invalid key name in a simple key-value file"
998 raise error.ProgrammingError(e)
999 if '\n' in v:
1000 e = "invalid value in a simple key-value file"
1001 raise error.ProgrammingError(e)
1002 lines.append("%s=%s\n" % (k, v))
1003 with self.vfs(self.path, mode='wb', atomictemp=True) as fp:
1004 fp.write(''.join(lines))
1005