comparison mercurial/sparse.py @ 38838:8fe62ad9f4ff

sparse: add an action argument to parseconfig() This will help us in reusing this function to parse narrow config files and unfiying the config file parsing logic. Differential Revision: https://phab.mercurial-scm.org/D4056
author Pulkit Goyal <pulkit@yandex-team.ru>
date Fri, 03 Aug 2018 22:24:58 +0530
parents 6ef94f24aa82
children 49505ec24e8f
comparison
equal deleted inserted replaced
38837:fa64a229f24b 38838:8fe62ad9f4ff
29 # Whether sparse features are enabled. This variable is intended to be 29 # Whether sparse features are enabled. This variable is intended to be
30 # temporary to facilitate porting sparse to core. It should eventually be 30 # temporary to facilitate porting sparse to core. It should eventually be
31 # a per-repo option, possibly a repo requirement. 31 # a per-repo option, possibly a repo requirement.
32 enabled = False 32 enabled = False
33 33
34 def parseconfig(ui, raw): 34 def parseconfig(ui, raw, action):
35 """Parse sparse config file content. 35 """Parse sparse config file content.
36
37 action is the command which is trigerring this read, can be narrow, sparse
36 38
37 Returns a tuple of includes, excludes, and profiles. 39 Returns a tuple of includes, excludes, and profiles.
38 """ 40 """
39 includes = set() 41 includes = set()
40 excludes = set() 42 excludes = set()
52 if line: 54 if line:
53 profiles.add(line) 55 profiles.add(line)
54 elif line == '[include]': 56 elif line == '[include]':
55 if havesection and current != includes: 57 if havesection and current != includes:
56 # TODO pass filename into this API so we can report it. 58 # TODO pass filename into this API so we can report it.
57 raise error.Abort(_('sparse config cannot have includes ' + 59 raise error.Abort(_('%s config cannot have includes ' +
58 'after excludes')) 60 'after excludes') % action)
59 havesection = True 61 havesection = True
60 current = includes 62 current = includes
61 continue 63 continue
62 elif line == '[exclude]': 64 elif line == '[exclude]':
63 havesection = True 65 havesection = True
64 current = excludes 66 current = excludes
65 elif line: 67 elif line:
66 if current is None: 68 if current is None:
67 raise error.Abort(_('sparse config entry outside of ' 69 raise error.Abort(_('%s config entry outside of '
68 'section: %s') % line, 70 'section: %s') % (action, line),
69 hint=_('add an [include] or [exclude] line ' 71 hint=_('add an [include] or [exclude] line '
70 'to declare the entry type')) 72 'to declare the entry type'))
71 73
72 if line.strip().startswith('/'): 74 if line.strip().startswith('/'):
73 ui.warn(_('warning: sparse profile cannot use' + 75 ui.warn(_('warning: %s profile cannot use' +
74 ' paths starting with /, ignoring %s\n') % line) 76 ' paths starting with /, ignoring %s\n')
77 % (action, line))
75 continue 78 continue
76 current.add(line) 79 current.add(line)
77 80
78 return includes, excludes, profiles 81 return includes, excludes, profiles
79 82
100 103
101 if rev is None: 104 if rev is None:
102 raise error.Abort(_('cannot parse sparse patterns from working ' 105 raise error.Abort(_('cannot parse sparse patterns from working '
103 'directory')) 106 'directory'))
104 107
105 includes, excludes, profiles = parseconfig(repo.ui, raw) 108 includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse')
106 ctx = repo[rev] 109 ctx = repo[rev]
107 110
108 if profiles: 111 if profiles:
109 visited = set() 112 visited = set()
110 while profiles: 113 while profiles:
126 repo.ui.warn(msg) 129 repo.ui.warn(msg)
127 else: 130 else:
128 repo.ui.debug(msg) 131 repo.ui.debug(msg)
129 continue 132 continue
130 133
131 pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw) 134 pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw, 'sparse')
132 includes.update(pincludes) 135 includes.update(pincludes)
133 excludes.update(pexcludes) 136 excludes.update(pexcludes)
134 profiles.update(subprofs) 137 profiles.update(subprofs)
135 138
136 profiles = visited 139 profiles = visited
514 517
515 def _updateconfigandrefreshwdir(repo, includes, excludes, profiles, 518 def _updateconfigandrefreshwdir(repo, includes, excludes, profiles,
516 force=False, removing=False): 519 force=False, removing=False):
517 """Update the sparse config and working directory state.""" 520 """Update the sparse config and working directory state."""
518 raw = repo.vfs.tryread('sparse') 521 raw = repo.vfs.tryread('sparse')
519 oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw) 522 oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw, 'sparse')
520 523
521 oldstatus = repo.status() 524 oldstatus = repo.status()
522 oldmatch = matcher(repo) 525 oldmatch = matcher(repo)
523 oldrequires = set(repo.requirements) 526 oldrequires = set(repo.requirements)
524 527
554 The remaining sparse config only has profiles, if defined. The working 557 The remaining sparse config only has profiles, if defined. The working
555 directory is refreshed, as needed. 558 directory is refreshed, as needed.
556 """ 559 """
557 with repo.wlock(): 560 with repo.wlock():
558 raw = repo.vfs.tryread('sparse') 561 raw = repo.vfs.tryread('sparse')
559 includes, excludes, profiles = parseconfig(repo.ui, raw) 562 includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse')
560 563
561 if not includes and not excludes: 564 if not includes and not excludes:
562 return 565 return
563 566
564 _updateconfigandrefreshwdir(repo, set(), set(), profiles, force=force) 567 _updateconfigandrefreshwdir(repo, set(), set(), profiles, force=force)
570 is refreshed, as needed. 573 is refreshed, as needed.
571 """ 574 """
572 with repo.wlock(): 575 with repo.wlock():
573 # read current configuration 576 # read current configuration
574 raw = repo.vfs.tryread('sparse') 577 raw = repo.vfs.tryread('sparse')
575 includes, excludes, profiles = parseconfig(repo.ui, raw) 578 includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse')
576 aincludes, aexcludes, aprofiles = activeconfig(repo) 579 aincludes, aexcludes, aprofiles = activeconfig(repo)
577 580
578 # Import rules on top; only take in rules that are not yet 581 # Import rules on top; only take in rules that are not yet
579 # part of the active rules. 582 # part of the active rules.
580 changed = False 583 changed = False
581 for p in paths: 584 for p in paths:
582 with util.posixfile(util.expandpath(p), mode='rb') as fh: 585 with util.posixfile(util.expandpath(p), mode='rb') as fh:
583 raw = fh.read() 586 raw = fh.read()
584 587
585 iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw) 588 iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw,
589 'sparse')
586 oldsize = len(includes) + len(excludes) + len(profiles) 590 oldsize = len(includes) + len(excludes) + len(profiles)
587 includes.update(iincludes - aincludes) 591 includes.update(iincludes - aincludes)
588 excludes.update(iexcludes - aexcludes) 592 excludes.update(iexcludes - aexcludes)
589 profiles.update(iprofiles - aprofiles) 593 profiles.update(iprofiles - aprofiles)
590 if len(includes) + len(excludes) + len(profiles) > oldsize: 594 if len(includes) + len(excludes) + len(profiles) > oldsize:
613 617
614 The new config is written out and a working directory refresh is performed. 618 The new config is written out and a working directory refresh is performed.
615 """ 619 """
616 with repo.wlock(): 620 with repo.wlock():
617 raw = repo.vfs.tryread('sparse') 621 raw = repo.vfs.tryread('sparse')
618 oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw) 622 oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw,
623 'sparse')
619 624
620 if reset: 625 if reset:
621 newinclude = set() 626 newinclude = set()
622 newexclude = set() 627 newexclude = set()
623 newprofiles = set() 628 newprofiles = set()