Mercurial > public > mercurial-scm > hg
comparison mercurial/scmutil.py @ 32270:218ca8526ec0
scmutil: make simplekeyvaluefile able to have a non-key-value first line
To ease migration from files with version numbers in their first lines,
we want simplekeyvaluefile to support a non-key-value first line. In this
way, old versions of Mercurial will read such files, discover a newer version
than the one they know how to handle and fail gracefully, rather than with
exception. Shelve's shelvestate file is an example.
author | Kostia Balytskyi <ikostia@fb.com> |
---|---|
date | Thu, 11 May 2017 08:49:33 -0700 |
parents | ed2c44741190 |
children | 4bec8cce6a09 |
comparison
equal
deleted
inserted
replaced
32269:ed2c44741190 | 32270:218ca8526ec0 |
---|---|
915 class simplekeyvaluefile(object): | 915 class simplekeyvaluefile(object): |
916 """A simple file with key=value lines | 916 """A simple file with key=value lines |
917 | 917 |
918 Keys must be alphanumerics and start with a letter, values must not | 918 Keys must be alphanumerics and start with a letter, values must not |
919 contain '\n' characters""" | 919 contain '\n' characters""" |
920 firstlinekey = '__firstline' | |
920 | 921 |
921 def __init__(self, vfs, path, keys=None): | 922 def __init__(self, vfs, path, keys=None): |
922 self.vfs = vfs | 923 self.vfs = vfs |
923 self.path = path | 924 self.path = path |
924 | 925 |
925 def read(self): | 926 def read(self, firstlinenonkeyval=False): |
927 """Read the contents of a simple key-value file | |
928 | |
929 'firstlinenonkeyval' indicates whether the first line of file should | |
930 be treated as a key-value pair or reuturned fully under the | |
931 __firstline key.""" | |
926 lines = self.vfs.readlines(self.path) | 932 lines = self.vfs.readlines(self.path) |
933 d = {} | |
934 if firstlinenonkeyval: | |
935 if not lines: | |
936 e = _("empty simplekeyvalue file") | |
937 raise error.CorruptedState(e) | |
938 # we don't want to include '\n' in the __firstline | |
939 d[self.firstlinekey] = lines[0][:-1] | |
940 del lines[0] | |
941 | |
927 try: | 942 try: |
928 # the 'if line.strip()' part prevents us from failing on empty | 943 # the 'if line.strip()' part prevents us from failing on empty |
929 # lines which only contain '\n' therefore are not skipped | 944 # lines which only contain '\n' therefore are not skipped |
930 # by 'if line' | 945 # by 'if line' |
931 d = dict(line[:-1].split('=', 1) for line in lines if line.strip()) | 946 updatedict = dict(line[:-1].split('=', 1) for line in lines |
947 if line.strip()) | |
948 if self.firstlinekey in updatedict: | |
949 e = _("%r can't be used as a key") | |
950 raise error.CorruptedState(e % self.firstlinekey) | |
951 d.update(updatedict) | |
932 except ValueError as e: | 952 except ValueError as e: |
933 raise error.CorruptedState(str(e)) | 953 raise error.CorruptedState(str(e)) |
934 return d | 954 return d |
935 | 955 |
936 def write(self, data): | 956 def write(self, data, firstline=None): |
937 """Write key=>value mapping to a file | 957 """Write key=>value mapping to a file |
938 data is a dict. Keys must be alphanumerical and start with a letter. | 958 data is a dict. Keys must be alphanumerical and start with a letter. |
939 Values must not contain newline characters.""" | 959 Values must not contain newline characters. |
960 | |
961 If 'firstline' is not None, it is written to file before | |
962 everything else, as it is, not in a key=value form""" | |
940 lines = [] | 963 lines = [] |
964 if firstline is not None: | |
965 lines.append('%s\n' % firstline) | |
966 | |
941 for k, v in data.items(): | 967 for k, v in data.items(): |
968 if k == self.firstlinekey: | |
969 e = "key name '%s' is reserved" % self.firstlinekey | |
970 raise error.ProgrammingError(e) | |
942 if not k[0].isalpha(): | 971 if not k[0].isalpha(): |
943 e = "keys must start with a letter in a key-value file" | 972 e = "keys must start with a letter in a key-value file" |
944 raise error.ProgrammingError(e) | 973 raise error.ProgrammingError(e) |
945 if not k.isalnum(): | 974 if not k.isalnum(): |
946 e = "invalid key name in a simple key-value file" | 975 e = "invalid key name in a simple key-value file" |