comparison mercurial/sparse.py @ 48778:c4149a110b5f

sparse: add timing block for parsing sparse configs This was showing up in an operation I was doing today, and I'd like to be able to get trace spans for it instead of just profiler samples. Differential Revision: https://phab.mercurial-scm.org/D12186
author Augie Fackler <augie@google.com>
date Tue, 15 Feb 2022 13:32:30 -0500
parents a6efb9180764
children 6000f5b25c9b
comparison
equal deleted inserted replaced
48777:eb9c55453249 48778:c4149a110b5f
36 36
37 action is the command which is trigerring this read, can be narrow, sparse 37 action is the command which is trigerring this read, can be narrow, sparse
38 38
39 Returns a tuple of includes, excludes, and profiles. 39 Returns a tuple of includes, excludes, and profiles.
40 """ 40 """
41 includes = set() 41 with util.timedcm(
42 excludes = set() 42 'sparse.parseconfig(ui, %d bytes, action=%s)', len(raw), action
43 profiles = set() 43 ):
44 current = None 44 includes = set()
45 havesection = False 45 excludes = set()
46 46 profiles = set()
47 for line in raw.split(b'\n'): 47 current = None
48 line = line.strip() 48 havesection = False
49 if not line or line.startswith(b'#'): 49
50 # empty or comment line, skip 50 for line in raw.split(b'\n'):
51 continue 51 line = line.strip()
52 elif line.startswith(b'%include '): 52 if not line or line.startswith(b'#'):
53 line = line[9:].strip() 53 # empty or comment line, skip
54 if line: 54 continue
55 profiles.add(line) 55 elif line.startswith(b'%include '):
56 elif line == b'[include]': 56 line = line[9:].strip()
57 if havesection and current != includes: 57 if line:
58 # TODO pass filename into this API so we can report it. 58 profiles.add(line)
59 raise error.Abort( 59 elif line == b'[include]':
60 _( 60 if havesection and current != includes:
61 b'%(action)s config cannot have includes ' 61 # TODO pass filename into this API so we can report it.
62 b'after excludes' 62 raise error.Abort(
63 _(
64 b'%(action)s config cannot have includes '
65 b'after excludes'
66 )
67 % {b'action': action}
63 ) 68 )
64 % {b'action': action} 69 havesection = True
65 ) 70 current = includes
66 havesection = True 71 continue
67 current = includes 72 elif line == b'[exclude]':
68 continue 73 havesection = True
69 elif line == b'[exclude]': 74 current = excludes
70 havesection = True 75 elif line:
71 current = excludes 76 if current is None:
72 elif line: 77 raise error.Abort(
73 if current is None: 78 _(
74 raise error.Abort( 79 b'%(action)s config entry outside of '
75 _( 80 b'section: %(line)s'
76 b'%(action)s config entry outside of ' 81 )
77 b'section: %(line)s' 82 % {b'action': action, b'line': line},
83 hint=_(
84 b'add an [include] or [exclude] line '
85 b'to declare the entry type'
86 ),
78 ) 87 )
79 % {b'action': action, b'line': line}, 88
80 hint=_( 89 if line.strip().startswith(b'/'):
81 b'add an [include] or [exclude] line ' 90 ui.warn(
82 b'to declare the entry type' 91 _(
83 ), 92 b'warning: %(action)s profile cannot use'
84 ) 93 b' paths starting with /, ignoring %(line)s\n'
85 94 )
86 if line.strip().startswith(b'/'): 95 % {b'action': action, b'line': line}
87 ui.warn(
88 _(
89 b'warning: %(action)s profile cannot use'
90 b' paths starting with /, ignoring %(line)s\n'
91 ) 96 )
92 % {b'action': action, b'line': line} 97 continue
93 ) 98 current.add(line)
94 continue 99
95 current.add(line) 100 return includes, excludes, profiles
96
97 return includes, excludes, profiles
98 101
99 102
100 # Exists as separate function to facilitate monkeypatching. 103 # Exists as separate function to facilitate monkeypatching.
101 def readprofile(repo, profile, changeid): 104 def readprofile(repo, profile, changeid):
102 """Resolve the raw content of a sparse profile file.""" 105 """Resolve the raw content of a sparse profile file."""