comparison hgext/lfs/__init__.py @ 41048:84d61fdcefa5

lfs: convert to using exthelper to wrap functions I'm not 100% sure that upgraderequirements() can be double annotated safely, but it seems OK based on printing the address of the function being wrapped. One thing I've noticed is that @eh.reposetup doesn't do the usual check to ensure that it's a local repo. Should that be baked into @eh.reposetup() somehow, possibly with a non-default option to skip the check? It seems like a gaping hole if every function that gets registered needs to add this check.
author Matt Harbison <matt_harbison@yahoo.com>
date Tue, 27 Nov 2018 22:10:07 -0500
parents ef0baff11aea
children 70ca0e846d25
comparison
equal deleted inserted replaced
41047:555215e2b051 41048:84d61fdcefa5
127 import sys 127 import sys
128 128
129 from mercurial.i18n import _ 129 from mercurial.i18n import _
130 130
131 from mercurial import ( 131 from mercurial import (
132 bundle2,
133 changegroup,
134 cmdutil,
135 config, 132 config,
136 context,
137 error, 133 error,
138 exchange, 134 exchange,
139 extensions, 135 extensions,
136 exthelper,
140 filelog, 137 filelog,
141 filesetlang, 138 filesetlang,
142 localrepo, 139 localrepo,
143 minifileset, 140 minifileset,
144 node, 141 node,
146 registrar, 143 registrar,
147 repository, 144 repository,
148 revlog, 145 revlog,
149 scmutil, 146 scmutil,
150 templateutil, 147 templateutil,
151 upgrade,
152 util, 148 util,
153 vfs as vfsmod,
154 wireprotoserver,
155 wireprotov1server,
156 ) 149 )
157 150
158 from . import ( 151 from . import (
159 blobstore, 152 blobstore,
160 wireprotolfsserver, 153 wireprotolfsserver,
165 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should 158 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
166 # be specifying the version(s) of Mercurial they are tested with, or 159 # be specifying the version(s) of Mercurial they are tested with, or
167 # leave the attribute unspecified. 160 # leave the attribute unspecified.
168 testedwith = 'ships-with-hg-core' 161 testedwith = 'ships-with-hg-core'
169 162
170 configtable = {} 163 eh = exthelper.exthelper()
171 configitem = registrar.configitem(configtable) 164 eh.merge(wrapper.eh)
172 165 eh.merge(wireprotolfsserver.eh)
173 configitem('experimental', 'lfs.serve', 166
167 cmdtable = eh.cmdtable
168 configtable = eh.configtable
169 extsetup = eh.finalextsetup
170 uisetup = eh.finaluisetup
171 reposetup = eh.finalreposetup
172
173 eh.configitem('experimental', 'lfs.serve',
174 default=True, 174 default=True,
175 ) 175 )
176 configitem('experimental', 'lfs.user-agent', 176 eh.configitem('experimental', 'lfs.user-agent',
177 default=None, 177 default=None,
178 ) 178 )
179 configitem('experimental', 'lfs.disableusercache', 179 eh.configitem('experimental', 'lfs.disableusercache',
180 default=False, 180 default=False,
181 ) 181 )
182 configitem('experimental', 'lfs.worker-enable', 182 eh.configitem('experimental', 'lfs.worker-enable',
183 default=False, 183 default=False,
184 ) 184 )
185 185
186 configitem('lfs', 'url', 186 eh.configitem('lfs', 'url',
187 default=None, 187 default=None,
188 ) 188 )
189 configitem('lfs', 'usercache', 189 eh.configitem('lfs', 'usercache',
190 default=None, 190 default=None,
191 ) 191 )
192 # Deprecated 192 # Deprecated
193 configitem('lfs', 'threshold', 193 eh.configitem('lfs', 'threshold',
194 default=None, 194 default=None,
195 ) 195 )
196 configitem('lfs', 'track', 196 eh.configitem('lfs', 'track',
197 default='none()', 197 default='none()',
198 ) 198 )
199 configitem('lfs', 'retry', 199 eh.configitem('lfs', 'retry',
200 default=5, 200 default=5,
201 ) 201 )
202
203 cmdtable = {}
204 command = registrar.command(cmdtable)
205
206 templatekeyword = registrar.templatekeyword() 202 templatekeyword = registrar.templatekeyword()
207 filesetpredicate = registrar.filesetpredicate() 203 filesetpredicate = registrar.filesetpredicate()
208 204
209 lfsprocessor = ( 205 lfsprocessor = (
210 wrapper.readfromstore, 206 wrapper.readfromstore,
214 210
215 def featuresetup(ui, supported): 211 def featuresetup(ui, supported):
216 # don't die on seeing a repo with the lfs requirement 212 # don't die on seeing a repo with the lfs requirement
217 supported |= {'lfs'} 213 supported |= {'lfs'}
218 214
219 def uisetup(ui): 215 @eh.uisetup
216 def _uisetup(ui):
220 localrepo.featuresetupfuncs.add(featuresetup) 217 localrepo.featuresetupfuncs.add(featuresetup)
221 218
222 def reposetup(ui, repo): 219 @eh.reposetup
220 def _reposetup(ui, repo):
223 # Nothing to do with a remote repo 221 # Nothing to do with a remote repo
224 if not repo.local(): 222 if not repo.local():
225 return 223 return
226 224
227 repo.svfs.lfslocalblobstore = blobstore.local(repo) 225 repo.svfs.lfslocalblobstore = blobstore.local(repo)
303 301
304 return False 302 return False
305 303
306 return _match 304 return _match
307 305
306 # Called by remotefilelog
308 def wrapfilelog(filelog): 307 def wrapfilelog(filelog):
309 wrapfunction = extensions.wrapfunction 308 wrapfunction = extensions.wrapfunction
310 309
311 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision) 310 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision)
312 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed) 311 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
313 wrapfunction(filelog, 'size', wrapper.filelogsize) 312 wrapfunction(filelog, 'size', wrapper.filelogsize)
314 313
314 @eh.wrapfunction(localrepo, 'resolverevlogstorevfsoptions')
315 def _resolverevlogstorevfsoptions(orig, ui, requirements, features): 315 def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
316 opts = orig(ui, requirements, features) 316 opts = orig(ui, requirements, features)
317 for name, module in extensions.extensions(ui): 317 for name, module in extensions.extensions(ui):
318 if module is sys.modules[__name__]: 318 if module is sys.modules[__name__]:
319 if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']: 319 if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']:
324 opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor 324 opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor
325 break 325 break
326 326
327 return opts 327 return opts
328 328
329 def extsetup(ui): 329 @eh.extsetup
330 def _extsetup(ui):
330 wrapfilelog(filelog.filelog) 331 wrapfilelog(filelog.filelog)
331
332 wrapfunction = extensions.wrapfunction
333
334 wrapfunction(localrepo, 'makefilestorage', wrapper.localrepomakefilestorage)
335 wrapfunction(localrepo, 'resolverevlogstorevfsoptions',
336 _resolverevlogstorevfsoptions)
337
338 wrapfunction(cmdutil, '_updatecatformatter', wrapper._updatecatformatter)
339 wrapfunction(scmutil, 'wrapconvertsink', wrapper.convertsink)
340
341 wrapfunction(upgrade, '_finishdatamigration',
342 wrapper.upgradefinishdatamigration)
343
344 wrapfunction(upgrade, 'preservedrequirements',
345 wrapper.upgraderequirements)
346
347 wrapfunction(upgrade, 'supporteddestrequirements',
348 wrapper.upgraderequirements)
349
350 wrapfunction(changegroup,
351 'allsupportedversions',
352 wrapper.allsupportedversions)
353
354 wrapfunction(exchange, 'push', wrapper.push)
355 wrapfunction(wireprotov1server, '_capabilities', wrapper._capabilities)
356 wrapfunction(wireprotoserver, 'handlewsgirequest',
357 wireprotolfsserver.handlewsgirequest)
358
359 wrapfunction(context.basefilectx, 'cmp', wrapper.filectxcmp)
360 wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary)
361 context.basefilectx.islfs = wrapper.filectxislfs
362 332
363 scmutil.fileprefetchhooks.add('lfs', wrapper._prefetchfiles) 333 scmutil.fileprefetchhooks.add('lfs', wrapper._prefetchfiles)
364 334
365 # Make bundle choose changegroup3 instead of changegroup2. This affects 335 # Make bundle choose changegroup3 instead of changegroup2. This affects
366 # "hg bundle" command. Note: it does not cover all bundle formats like 336 # "hg bundle" command. Note: it does not cover all bundle formats like
367 # "packed1". Using "packed1" with lfs will likely cause trouble. 337 # "packed1". Using "packed1" with lfs will likely cause trouble.
368 exchange._bundlespeccontentopts["v2"]["cg.version"] = "03" 338 exchange._bundlespeccontentopts["v2"]["cg.version"] = "03"
369
370 # bundlerepo uses "vfsmod.readonlyvfs(othervfs)", we need to make sure lfs
371 # options and blob stores are passed from othervfs to the new readonlyvfs.
372 wrapfunction(vfsmod.readonlyvfs, '__init__', wrapper.vfsinit)
373
374 # when writing a bundle via "hg bundle" command, upload related LFS blobs
375 wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle)
376 339
377 @filesetpredicate('lfs()') 340 @filesetpredicate('lfs()')
378 def lfsfileset(mctx, x): 341 def lfsfileset(mctx, x):
379 """File that uses LFS storage.""" 342 """File that uses LFS storage."""
380 # i18n: "lfs" is a keyword 343 # i18n: "lfs" is a keyword
407 370
408 # TODO: make the separator ', '? 371 # TODO: make the separator ', '?
409 f = templateutil._showcompatlist(context, mapping, 'lfs_file', files) 372 f = templateutil._showcompatlist(context, mapping, 'lfs_file', files)
410 return templateutil.hybrid(f, files, makemap, pycompat.identity) 373 return templateutil.hybrid(f, files, makemap, pycompat.identity)
411 374
412 @command('debuglfsupload', 375 @eh.command('debuglfsupload',
413 [('r', 'rev', [], _('upload large files introduced by REV'))]) 376 [('r', 'rev', [], _('upload large files introduced by REV'))])
414 def debuglfsupload(ui, repo, **opts): 377 def debuglfsupload(ui, repo, **opts):
415 """upload lfs blobs added by the working copy parent or given revisions""" 378 """upload lfs blobs added by the working copy parent or given revisions"""
416 revs = opts.get(r'rev', []) 379 revs = opts.get(r'rev', [])
417 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs)) 380 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
418 wrapper.uploadblobs(repo, pointers) 381 wrapper.uploadblobs(repo, pointers)