##// END OF EJS Templates
errors: stop passing non-strings to Abort's constructor...
errors: stop passing non-strings to Abort's constructor The next patch will change `Abort`'s constructor and `__bytes__` functions and they will start assuming that the first argument is the messages as `bytes`. Differential Revision: https://phab.mercurial-scm.org/D9178

File last commit:

r44937:9d2b2df2 default
r46273:a736ab68 default
Show More
basestore.py
179 lines | 6.4 KiB | text/x-python | PythonLexer
various
hgext: add largefiles extension...
r15168 # Copyright 2009-2010 Gregory P. Ward
# Copyright 2009-2010 Intelerad Medical Systems Incorporated
# Copyright 2010-2011 Fog Creek Software
# Copyright 2010-2011 Unity Technologies
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 '''base class for store implementations and store-related utility code'''
liscju
py3: make largefiles/basestore.py use absolute_import
r29307 from __future__ import absolute_import
various
hgext: add largefiles extension...
r15168
from mercurial.i18n import _
liscju
py3: make largefiles/basestore.py use absolute_import
r29307 from mercurial import node, util
from . import lfutil
various
hgext: add largefiles extension...
r15168
Augie Fackler
formatting: blacken the codebase...
r43346
various
hgext: add largefiles extension...
r15168 class StoreError(Exception):
'''Raised when there is a problem getting files from or putting
files to a central store.'''
Augie Fackler
formatting: blacken the codebase...
r43346
various
hgext: add largefiles extension...
r15168 def __init__(self, filename, hash, url, detail):
self.filename = filename
self.hash = hash
self.url = url
self.detail = detail
def longmessage(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return _(b"error getting id %s from url %s for file %s: %s\n") % (
Augie Fackler
formatting: blacken the codebase...
r43346 self.hash,
util.hidepassword(self.url),
self.filename,
self.detail,
)
various
hgext: add largefiles extension...
r15168
def __str__(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"%s: %s" % (util.hidepassword(self.url), self.detail)
various
hgext: add largefiles extension...
r15168
Augie Fackler
formatting: blacken the codebase...
r43346
various
hgext: add largefiles extension...
r15168 class basestore(object):
def __init__(self, ui, repo, url):
self.ui = ui
self.repo = repo
self.url = url
def put(self, source, hash):
Mads Kiilerich
largefiles: 'put' should store 'source' file in under 'hash', also in localstore
r19007 '''Put source file into the store so it can be retrieved by hash.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: batch statlfile requests when pushing a largefiles repo (issue3386)...
r17127 def exists(self, hashes):
Mads Kiilerich
largefiles: fold oddly named _verify into remotestore.exists
r18573 '''Check to see if the store contains the given hashes. Given an
iterable of hashes it returns a mapping from hash to bool.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')
various
hgext: add largefiles extension...
r15168
def get(self, files):
'''Get the specified largefiles from the store and write to local
files under repo.root. files is a list of (filename, hash)
Mads Kiilerich
fix trivial spelling errors
r17424 tuples. Return (success, missing), lists of files successfully
various
hgext: add largefiles extension...
r15168 downloaded and those not found in the store. success is a list
of (filename, hash) tuples; missing is a list of filenames that
we could not get. (The detailed error message will already have
been presented to the user, so missing is just supplied as a
summary.)'''
success = []
missing = []
ui = self.ui
at = 0
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 available = self.exists({hash for (_filename, hash) in files})
Augie Fackler
formatting: blacken the codebase...
r43346 with ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'getting largefiles'), unit=_(b'files'), total=len(files)
Augie Fackler
formatting: blacken the codebase...
r43346 ) as progress:
Matt Harbison
largefiles: use a context manager to control the progress bar lifetime
r39427 for filename, hash in files:
progress.update(at)
at += 1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.note(_(b'getting %s:%s\n') % (filename, hash))
various
hgext: add largefiles extension...
r15168
Matt Harbison
largefiles: use a context manager to control the progress bar lifetime
r39427 if not available.get(hash):
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: largefile %s not available from %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (filename, hash, util.hidepassword(self.url))
)
Matt Harbison
largefiles: use a context manager to control the progress bar lifetime
r39427 missing.append(filename)
continue
Mads Kiilerich
largefiles: stat all largefiles in one batch before downloading...
r19008
Matt Harbison
largefiles: use a context manager to control the progress bar lifetime
r39427 if self._gethash(filename, hash):
success.append((filename, hash))
else:
missing.append(filename)
various
hgext: add largefiles extension...
r15168
return (success, missing)
Mads Kiilerich
largefiles: refactor basestore, extract _gethash method
r19918 def _gethash(self, filename, hash):
"""Get file with the provided hash and store it in the local repo's
store and in the usercache.
filename is for informational messages only.
"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 util.makedirs(lfutil.storepath(self.repo, b''))
Mads Kiilerich
largefiles: refactor basestore, extract _gethash method
r19918 storefilename = lfutil.storepath(self.repo, hash)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmpname = storefilename + b'.tmp'
Augie Fackler
formatting: blacken the codebase...
r43346 with util.atomictempfile(
tmpname, createmode=self.repo.store.createmode
) as tmpfile:
Mads Kiilerich
largefiles: use context for file closing...
r30142 try:
gothash = self._getfile(tmpfile, filename, hash)
except StoreError as err:
self.ui.warn(err.longmessage())
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 gothash = b""
Mads Kiilerich
largefiles: refactor basestore, extract _gethash method
r19918
if gothash != hash:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if gothash != b"":
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: data corruption (expected %s, got %s)\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (filename, hash, gothash)
)
Mads Kiilerich
largefiles: refactor basestore, extract _gethash method
r19918 util.unlink(tmpname)
return False
util.rename(tmpname, storefilename)
lfutil.linktousercache(self.repo, hash)
return True
various
hgext: add largefiles extension...
r15168 def verify(self, revs, contents=False):
'''Verify the existence (and, optionally, contents) of every big
file revision referenced by every changeset in revs.
Return 0 if all is well, non-zero on any errors.'''
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'searching %d changesets for largefiles\n') % len(revs)
Augie Fackler
formatting: blacken the codebase...
r43346 )
verified = set() # set of (filename, filenode) tuples
filestocheck = [] # list of (cset, filename, expectedhash)
various
hgext: add largefiles extension...
r15168 for rev in revs:
cctx = self.repo[rev]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cset = b"%d:%s" % (cctx.rev(), node.short(cctx.node()))
various
hgext: add largefiles extension...
r15168
Mads Kiilerich
largefiles: verify all files in each revision and report errors in any revision...
r18486 for standin in cctx:
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 filename = lfutil.splitstandin(standin)
if filename:
fctx = cctx[standin]
key = (filename, fctx.filenode())
if key not in verified:
verified.add(key)
FUJIWARA Katsunori
largefiles: use readasstandin() to read hex hash directly from filectx...
r31740 expectedhash = lfutil.readasstandin(fctx)
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 filestocheck.append((cset, filename, expectedhash))
failed = self._verifyfiles(contents, filestocheck)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 numrevs = len(verified)
Martin von Zweigbergk
cleanup: use set literals where possible...
r42224 numlfiles = len({fname for (fname, fnode) in verified})
various
hgext: add largefiles extension...
r15168 if contents:
Mads Kiilerich
largefiles: verify status should be written as status, not as write...
r18546 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'verified contents of %d revisions of %d largefiles\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (numrevs, numlfiles)
)
various
hgext: add largefiles extension...
r15168 else:
Mads Kiilerich
largefiles: verify status should be written as status, not as write...
r18546 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'verified existence of %d revisions of %d largefiles\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (numrevs, numlfiles)
)
various
hgext: add largefiles extension...
r15168 return int(failed)
def _getfile(self, tmpfile, filename, hash):
'''Fetch one revision of one file from the store and write it
to tmpfile. Compute the hash of the file on-the-fly as it
Mads Kiilerich
largefiles: refactoring - return hex from _getfile and copyandhash
r18999 downloads and return the hash. Close tmpfile. Raise
various
hgext: add largefiles extension...
r15168 StoreError if unable to download the file (e.g. it does not
exist in the store).'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')
various
hgext: add largefiles extension...
r15168
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 def _verifyfiles(self, contents, filestocheck):
'''Perform the actual verification of files in the store.
Mads Kiilerich
largefiles: docstrings for verify methods
r18574 'contents' controls verification of content hash.
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 'filestocheck' is list of files to check.
Returns _true_ if any problems are found!
various
hgext: add largefiles extension...
r15168 '''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')