|
@@ -122,7 +122,8 @@ class FileDirCAS(object): |
|
|
return False |
|
|
return False |
|
|
|
|
|
|
|
|
def fetch_data(self, url): |
|
|
def fetch_data(self, url): |
|
|
'''Given the URL (must be a hash URL), return the code for it.''' |
|
|
|
|
|
|
|
|
'''Given the URL (must be a hash URL), return the code for |
|
|
|
|
|
it.''' |
|
|
|
|
|
|
|
|
self.refresh_dir() |
|
|
self.refresh_dir() |
|
|
|
|
|
|
|
@@ -150,8 +151,10 @@ class CASFinder(MetaPathFinder, Loader): |
|
|
self._loaders = [] |
|
|
self._loaders = [] |
|
|
self._aliases = {} |
|
|
self._aliases = {} |
|
|
|
|
|
|
|
|
if [ x for x in sys.meta_path if isinstance(x, self.__class__) ]: |
|
|
|
|
|
raise RuntimeError('cannot register more than on CASFinder') |
|
|
|
|
|
|
|
|
if [ x for x in sys.meta_path if |
|
|
|
|
|
isinstance(x, self.__class__) ]: |
|
|
|
|
|
raise RuntimeError( |
|
|
|
|
|
'cannot register more than on CASFinder') |
|
|
|
|
|
|
|
|
sys.meta_path.append(self) |
|
|
sys.meta_path.append(self) |
|
|
|
|
|
|
|
@@ -164,7 +167,8 @@ class CASFinder(MetaPathFinder, Loader): |
|
|
def load_aliases(self, name): |
|
|
def load_aliases(self, name): |
|
|
'''Load the aliases from the module with the passed in name.''' |
|
|
'''Load the aliases from the module with the passed in name.''' |
|
|
|
|
|
|
|
|
aliases = importlib.resources.read_text(sys.modules[name], 'cas_aliases.txt') |
|
|
|
|
|
|
|
|
aliases = importlib.resources.read_text(sys.modules[name], |
|
|
|
|
|
'cas_aliases.txt') |
|
|
self._aliases.update(self._parsealiases(aliases)) |
|
|
self._aliases.update(self._parsealiases(aliases)) |
|
|
|
|
|
|
|
|
@staticmethod |
|
|
@staticmethod |
|
@@ -189,8 +193,10 @@ class CASFinder(MetaPathFinder, Loader): |
|
|
|
|
|
|
|
|
# split out the hashes |
|
|
# split out the hashes |
|
|
for items in list(ret.values()): |
|
|
for items in list(ret.values()): |
|
|
lst = [ x for x in items if not x.startswith('hash://') ] |
|
|
|
|
|
for h in [ x for x in items if x.startswith('hash://') ]: |
|
|
|
|
|
|
|
|
lst = [ x for x in items if |
|
|
|
|
|
not x.startswith('hash://') ] |
|
|
|
|
|
for h in [ x for x in items if |
|
|
|
|
|
x.startswith('hash://') ]: |
|
|
h = cls._makebasichashurl(h) |
|
|
h = cls._makebasichashurl(h) |
|
|
ret[h] = lst |
|
|
ret[h] = lst |
|
|
|
|
|
|
|
@@ -228,7 +234,8 @@ class CASFinder(MetaPathFinder, Loader): |
|
|
ver, typ, arg = parts[1].split('_') |
|
|
ver, typ, arg = parts[1].split('_') |
|
|
if typ == 'f': |
|
|
if typ == 'f': |
|
|
# make hash url: |
|
|
# make hash url: |
|
|
hashurl = 'hash://sha256/%s' % bytes.fromhex(arg).hex() |
|
|
|
|
|
|
|
|
hashurl = ('hash://sha256/%s' % |
|
|
|
|
|
bytes.fromhex(arg).hex()) |
|
|
hashurl = urllib.parse.urlparse(hashurl) |
|
|
hashurl = urllib.parse.urlparse(hashurl) |
|
|
for l in self._loaders: |
|
|
for l in self._loaders: |
|
|
ispkg = l.is_package(hashurl) |
|
|
ispkg = l.is_package(hashurl) |
|
@@ -244,7 +251,8 @@ class CASFinder(MetaPathFinder, Loader): |
|
|
else: |
|
|
else: |
|
|
raise ValueError('unable to find bash hash url for alias %s' % repr(arg)) |
|
|
raise ValueError('unable to find bash hash url for alias %s' % repr(arg)) |
|
|
|
|
|
|
|
|
ms = ModuleSpec(fullname, self, is_package=False, loader_state=(hashurl,)) |
|
|
|
|
|
|
|
|
ms = ModuleSpec(fullname, self, is_package=False, |
|
|
|
|
|
loader_state=(hashurl,)) |
|
|
|
|
|
|
|
|
return ms |
|
|
return ms |
|
|
|
|
|
|
|
@@ -265,7 +273,8 @@ class CASFinder(MetaPathFinder, Loader): |
|
|
pass |
|
|
pass |
|
|
|
|
|
|
|
|
else: |
|
|
else: |
|
|
for url in self._aliases[self._makebasichashurl(url)]: |
|
|
|
|
|
|
|
|
for url in self._aliases[ |
|
|
|
|
|
self._makebasichashurl(url)]: |
|
|
url = urllib.parse.urlparse(url) |
|
|
url = urllib.parse.urlparse(url) |
|
|
for load in self._loaders: |
|
|
for load in self._loaders: |
|
|
try: |
|
|
try: |
|
@@ -338,7 +347,8 @@ class Test(unittest.TestCase): |
|
|
def setUp(self): |
|
|
def setUp(self): |
|
|
# clear out the default casfinder if there is one |
|
|
# clear out the default casfinder if there is one |
|
|
self.old_meta_path = sys.meta_path |
|
|
self.old_meta_path = sys.meta_path |
|
|
sys.meta_path = [ x for x in sys.meta_path if not isinstance(x, CASFinder) ] |
|
|
|
|
|
|
|
|
sys.meta_path = [ x for x in sys.meta_path if |
|
|
|
|
|
not isinstance(x, CASFinder) ] |
|
|
|
|
|
|
|
|
# setup temporary directory |
|
|
# setup temporary directory |
|
|
d = pathlib.Path(os.path.realpath(tempfile.mkdtemp())) |
|
|
d = pathlib.Path(os.path.realpath(tempfile.mkdtemp())) |
|
@@ -346,7 +356,8 @@ class Test(unittest.TestCase): |
|
|
self.tempdir = d / 'subdir' |
|
|
self.tempdir = d / 'subdir' |
|
|
self.tempdir.mkdir() |
|
|
self.tempdir.mkdir() |
|
|
|
|
|
|
|
|
self.fixtures = pathlib.Path(__file__).parent.parent / 'fixtures' |
|
|
|
|
|
|
|
|
self.fixtures = \ |
|
|
|
|
|
pathlib.Path(__file__).parent.parent / 'fixtures' |
|
|
|
|
|
|
|
|
def tearDown(self): |
|
|
def tearDown(self): |
|
|
# restore environment |
|
|
# restore environment |
|
@@ -451,12 +462,13 @@ class Test(unittest.TestCase): |
|
|
with tempset(os.environ, 'HOME', str(temphome)): |
|
|
with tempset(os.environ, 'HOME', str(temphome)): |
|
|
try: |
|
|
try: |
|
|
with CASFinder() as f, \ |
|
|
with CASFinder() as f, \ |
|
|
tempattrset(sys.modules[__name__], 'load_aliases', |
|
|
|
|
|
f.load_aliases): |
|
|
|
|
|
|
|
|
tempattrset(sys.modules[__name__], |
|
|
|
|
|
'load_aliases', f.load_aliases): |
|
|
defaultinit(f) |
|
|
defaultinit(f) |
|
|
|
|
|
|
|
|
# and that hello.py is in the cache |
|
|
# and that hello.py is in the cache |
|
|
shutil.copy(self.fixtures / 'hello.py', cachedir) |
|
|
|
|
|
|
|
|
shutil.copy(self.fixtures / 'hello.py', |
|
|
|
|
|
cachedir) |
|
|
|
|
|
|
|
|
# that the import is successful |
|
|
# that the import is successful |
|
|
import randpkg |
|
|
import randpkg |
|
@@ -504,13 +516,13 @@ class Test(unittest.TestCase): |
|
|
|
|
|
|
|
|
def test_overlappingaliases(self): |
|
|
def test_overlappingaliases(self): |
|
|
# make sure that an aliases file is consistent and does not |
|
|
# make sure that an aliases file is consistent and does not |
|
|
# override other urls. That is that any hashes are consistent, |
|
|
|
|
|
# and that they have at least one root hash that is the same, and |
|
|
|
|
|
# will be used for fetching. |
|
|
|
|
|
|
|
|
# override other urls. That is that any hashes are |
|
|
|
|
|
# consistent, and that they have at least one root hash that |
|
|
|
|
|
# is the same, and will be used for fetching. |
|
|
# |
|
|
# |
|
|
# Likely will also have to deal w/ an issue where two aliases share |
|
|
|
|
|
# sha256, and a third shares sha512, which in this case, BOTH hashse |
|
|
|
|
|
# have to be checked. |
|
|
|
|
|
|
|
|
# Likely will also have to deal w/ an issue where two |
|
|
|
|
|
# aliases share sha256, and a third shares sha512, which in |
|
|
|
|
|
# this case, BOTH hashse have to be checked. |
|
|
pass |
|
|
pass |
|
|
|
|
|
|
|
|
def test_loaderpriority(self): |
|
|
def test_loaderpriority(self): |
|
|