Mercurial > hg
comparison mercurial/hg.py @ 49683:d9791643aab7
peer-or-repo: make sure object in "scheme" have a `instance` object
The previous form of having heterogeneous object in the dictionnary makes things
more complicated than they needed to be. I am not super happy about the current
(especially around 'islocal', that most item do not have), but this is already
much better.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 29 Nov 2022 19:54:55 +0100 |
parents | 1e6c37360527 |
children | 229e0ed88895 |
comparison
equal
deleted
inserted
replaced
49682:1e6c37360527 | 49683:d9791643aab7 |
---|---|
63 | 63 |
64 # shared features | 64 # shared features |
65 sharedbookmarks = b'bookmarks' | 65 sharedbookmarks = b'bookmarks' |
66 | 66 |
67 | 67 |
68 def _local(path): | |
69 path = util.expandpath(urlutil.urllocalpath(path)) | |
70 | |
71 try: | |
72 # we use os.stat() directly here instead of os.path.isfile() | |
73 # because the latter started returning `False` on invalid path | |
74 # exceptions starting in 3.8 and we care about handling | |
75 # invalid paths specially here. | |
76 st = os.stat(path) | |
77 isfile = stat.S_ISREG(st.st_mode) | |
78 except ValueError as e: | |
79 raise error.Abort( | |
80 _(b'invalid path %s: %s') % (path, stringutil.forcebytestr(e)) | |
81 ) | |
82 except OSError: | |
83 isfile = False | |
84 | |
85 return isfile and bundlerepo or localrepo | |
86 | |
87 | |
88 def addbranchrevs(lrepo, other, branches, revs): | 68 def addbranchrevs(lrepo, other, branches, revs): |
89 peer = other.peer() # a courtesy to callers using a localrepo for other | 69 peer = other.peer() # a courtesy to callers using a localrepo for other |
90 hashbranch, branches = branches | 70 hashbranch, branches = branches |
91 if not hashbranch and not branches: | 71 if not hashbranch and not branches: |
92 x = revs or None | 72 x = revs or None |
127 if not primary(hashbranch): | 107 if not primary(hashbranch): |
128 revs.append(hashbranch) | 108 revs.append(hashbranch) |
129 return revs, revs[0] | 109 return revs, revs[0] |
130 | 110 |
131 | 111 |
112 def _isfile(path): | |
113 try: | |
114 # we use os.stat() directly here instead of os.path.isfile() | |
115 # because the latter started returning `False` on invalid path | |
116 # exceptions starting in 3.8 and we care about handling | |
117 # invalid paths specially here. | |
118 st = os.stat(path) | |
119 except ValueError as e: | |
120 msg = stringutil.forcebytestr(e) | |
121 raise error.Abort(_(b'invalid path %s: %s') % (path, msg)) | |
122 except OSError: | |
123 return False | |
124 else: | |
125 return stat.S_ISREG(st.st_mode) | |
126 | |
127 | |
128 class LocalFactory: | |
129 """thin wrapper to dispatch between localrepo and bundle repo""" | |
130 | |
131 @staticmethod | |
132 def islocal(path: bytes) -> bool: | |
133 path = util.expandpath(urlutil.urllocalpath(path)) | |
134 return not _isfile(path) | |
135 | |
136 @staticmethod | |
137 def instance(ui, path, *args, **kwargs): | |
138 path = util.expandpath(urlutil.urllocalpath(path)) | |
139 if _isfile(path): | |
140 cls = bundlerepo | |
141 else: | |
142 cls = localrepo | |
143 return cls.instance(ui, path, *args, **kwargs) | |
144 | |
145 | |
132 schemes = { | 146 schemes = { |
133 b'bundle': bundlerepo, | 147 b'bundle': bundlerepo, |
134 b'union': unionrepo, | 148 b'union': unionrepo, |
135 b'file': _local, | 149 b'file': LocalFactory, |
136 b'http': httppeer, | 150 b'http': httppeer, |
137 b'https': httppeer, | 151 b'https': httppeer, |
138 b'ssh': sshpeer, | 152 b'ssh': sshpeer, |
139 b'static-http': statichttprepo, | 153 b'static-http': statichttprepo, |
140 } | 154 } |
142 | 156 |
143 def _peerlookup(path): | 157 def _peerlookup(path): |
144 u = urlutil.url(path) | 158 u = urlutil.url(path) |
145 scheme = u.scheme or b'file' | 159 scheme = u.scheme or b'file' |
146 thing = schemes.get(scheme) or schemes[b'file'] | 160 thing = schemes.get(scheme) or schemes[b'file'] |
147 try: | 161 return thing |
148 return thing(path) | |
149 except TypeError: | |
150 # we can't test callable(thing) because 'thing' can be an unloaded | |
151 # module that implements __call__ | |
152 if not util.safehasattr(thing, b'instance'): | |
153 raise | |
154 return thing | |
155 | 162 |
156 | 163 |
157 def islocal(repo): | 164 def islocal(repo): |
158 '''return true if repo (or path pointing to repo) is local''' | 165 '''return true if repo (or path pointing to repo) is local''' |
159 if isinstance(repo, bytes): | 166 if isinstance(repo, bytes): |