1# This software may be used and distributed according to the terms of the 2# GNU General Public License version 2 or any later version. 3 4from __future__ import absolute_import 5 6import re 7 8from mercurial.i18n import _ 9from mercurial.pycompat import getattr 10from mercurial import ( 11 error, 12 hg, 13 util, 14) 15from mercurial.utils import ( 16 urlutil, 17) 18 19from . import ( 20 lfutil, 21 localstore, 22 wirestore, 23) 24 25 26# During clone this function is passed the src's ui object 27# but it needs the dest's ui object so it can read out of 28# the config file. Use repo.ui instead. 29def openstore(repo=None, remote=None, put=False, ui=None): 30 if ui is None: 31 ui = repo.ui 32 33 if not remote: 34 lfpullsource = getattr(repo, 'lfpullsource', None) 35 if put: 36 path = urlutil.get_unique_push_path( 37 b'lfpullsource', repo, ui, lfpullsource 38 ) 39 else: 40 path, _branches = urlutil.get_unique_pull_path( 41 b'lfpullsource', repo, ui, lfpullsource 42 ) 43 44 # XXX we should not explicitly pass b'default', as this will result in 45 # b'default' being returned if no `paths.default` was defined. We 46 # should explicitely handle the lack of value instead. 47 if repo is None: 48 path, _branches = urlutil.get_unique_pull_path( 49 b'lfs', repo, ui, b'default' 50 ) 51 remote = hg.peer(repo or ui, {}, path) 52 elif path == b'default-push' or path == b'default': 53 remote = repo 54 else: 55 path, _branches = urlutil.parseurl(path) 56 remote = hg.peer(repo or ui, {}, path) 57 58 # The path could be a scheme so use Mercurial's normal functionality 59 # to resolve the scheme to a repository and use its path 60 path = util.safehasattr(remote, b'url') and remote.url() or remote.path 61 62 match = _scheme_re.match(path) 63 if not match: # regular filesystem path 64 scheme = b'file' 65 else: 66 scheme = match.group(1) 67 68 try: 69 storeproviders = _storeprovider[scheme] 70 except KeyError: 71 raise error.Abort(_(b'unsupported URL scheme %r') % scheme) 72 73 for classobj in storeproviders: 74 try: 75 return classobj(ui, repo, remote) 76 except lfutil.storeprotonotcapable: 77 pass 78 79 raise error.Abort( 80 _(b'%s does not appear to be a largefile store') 81 % urlutil.hidepassword(path) 82 ) 83 84 85_storeprovider = { 86 b'file': [localstore.localstore], 87 b'http': [wirestore.wirestore], 88 b'https': [wirestore.wirestore], 89 b'ssh': [wirestore.wirestore], 90} 91 92_scheme_re = re.compile(br'^([a-zA-Z0-9+-.]+)://') 93 94 95def getlfile(ui, hash): 96 return util.chunkbuffer(openstore(ui=ui)._get(hash)) 97