Skip to content

Commit 850751e

Browse files
committed
enable launch from local meca file
1 parent 85ce300 commit 850751e

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

repo2docker/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ def _default_log_level(self):
153153
contentproviders.Hydroshare,
154154
contentproviders.Swhid,
155155
contentproviders.CKAN,
156+
contentproviders.Meca,
156157
contentproviders.Mercurial,
157158
contentproviders.Git,
158-
contentproviders.Meca,
159159
],
160160
config=True,
161161
help="""

repo2docker/contentproviders/meca.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import hashlib
12
import os
23
import shutil
34
import tempfile
@@ -78,35 +79,50 @@ def __init__(self):
7879
)
7980

8081
def detect(self, spec, ref=None, extra_args=None):
81-
"""`spec` contains a faux protocol of meca+http[s] for detection purposes
82+
"""`spec` contains a faux protocol of http[s]+meca for detection purposes
8283
and we assume `spec` trusted as a reachable MECA bundle from an allowed origin
8384
(binderhub RepoProvider class is already checking for this).
8485
8586
An other HEAD check in made here in order to get the content-length header
8687
"""
87-
parsed = urlparse(spec)
88-
if not parsed.scheme.endswith("+meca"):
89-
return None
90-
parsed = parsed._replace(scheme=parsed.scheme[:-5])
91-
url = urlunparse(parsed)
92-
93-
headers = self.session.head(url).headers
94-
changes_with_content = headers.get("ETag") or headers.get("Content-Length")
88+
is_local_file = False
89+
if spec.endswith(".meca.zip") and os.path.isfile(spec):
90+
url = os.path.abspath(spec)
91+
is_local_file = True
92+
with open(url, "rb") as f:
93+
file_hash = hashlib.blake2b()
94+
while chunk := f.read(8192):
95+
file_hash.update(chunk)
96+
changes_with_content = file_hash.hexdigest()
97+
else:
98+
parsed = urlparse(spec)
99+
if not parsed.scheme.endswith("+meca"):
100+
return None
101+
parsed = parsed._replace(scheme=parsed.scheme[:-5])
102+
url = urlunparse(parsed)
103+
104+
headers = self.session.head(url).headers
105+
changes_with_content = headers.get("ETag") or headers.get("Content-Length")
95106

96107
self.hashed_slug = get_hashed_slug(url, changes_with_content)
97108

98-
return {"url": url, "slug": self.hashed_slug}
109+
return {"url": url, "slug": self.hashed_slug, "is_local_file": is_local_file}
99110

100111
def fetch(self, spec, output_dir, yield_output=False):
101112
hashed_slug = spec["slug"]
102113
url = spec["url"]
114+
is_local_file = spec["is_local_file"]
103115

104116
yield f"Creating temporary directory.\n"
105117
with tempfile.TemporaryDirectory() as tmpdir:
106118
yield f"Temporary directory created at {tmpdir}.\n"
107119

108-
yield f"Fetching MECA Bundle {url}.\n"
109-
zip_filename = fetch_zipfile(self.session, url, tmpdir)
120+
if is_local_file:
121+
yield f"Found MECA Bundle {url}.\n"
122+
zip_filename = url
123+
else:
124+
yield f"Fetching MECA Bundle {url}.\n"
125+
zip_filename = fetch_zipfile(self.session, url, tmpdir)
110126

111127
yield f"Extracting MECA Bundle {zip_filename}.\n"
112128
is_meca, bundle_dir = extract_validate_and_identify_bundle(

0 commit comments

Comments
 (0)