Skip to content

Commit

Permalink
Add MercurialRepoProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
paugier committed Oct 5, 2020
1 parent 856589e commit 931e7f1
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 3 deletions.
3 changes: 2 additions & 1 deletion binderhub/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from .repoproviders import (GitHubRepoProvider, GitRepoProvider,
GitLabRepoProvider, GistRepoProvider,
ZenodoProvider, FigshareProvider, HydroshareProvider,
DataverseProvider)
DataverseProvider, MercurialRepoProvider)
from .metrics import MetricsHandler

from .utils import ByteSpecification, url_path_join
Expand Down Expand Up @@ -420,6 +420,7 @@ def _add_slash(self, proposal):
'figshare': FigshareProvider,
'hydroshare': HydroshareProvider,
'dataverse': DataverseProvider,
'hg': MercurialRepoProvider,
},
config=True,
help="""
Expand Down
3 changes: 2 additions & 1 deletion binderhub/event-schemas/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"Zenodo",
"Figshare",
"Hydroshare",
"Dataverse"
"Dataverse",
"Mercurial"
],
"description": "Provider for the repository being launched"
},
Expand Down
1 change: 1 addition & 0 deletions binderhub/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"figshare": "Figshare",
"hydroshare": "Hydroshare",
"dataverse": "Dataverse",
"hg": "Mercurial",
}


Expand Down
43 changes: 43 additions & 0 deletions binderhub/repoproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -899,3 +899,46 @@ async def get_resolved_spec(self):

def get_build_slug(self):
return self.gist_id


class MercurialRepoProvider(GitRepoProvider):
"""Bare bones Mercurial repo provider.
Users must provide a spec of the following form.
<url-escaped-namespace>/<unresolved_ref>
<url-escaped-namespace>/<resolved_ref>
eg:
https://foss.heptapod.net/pypy/pypy/release-pypy3.7-v7.3.2rc3
https://foss.heptapod.net/graphics/plot-covid19-fr/8e29b5b0064d
"""

name = Unicode("Mercurial")

@gen.coroutine
def get_resolved_ref(self):
if hasattr(self, 'resolved_ref'):
return self.resolved_ref

try:
# Check if the reference is a valid SHA hash
self.sha1_validate(self.unresolved_ref)
except ValueError:
# The ref is a head/tag and we resolve it using `hg identify`
command = ["hg", "identify", self.repo, "-r", self.unresolved_ref, "-T", "'{id}'"]
result = subprocess.run(command, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode:
raise RuntimeError("Unable to run hg identify to get the `resolved_ref`: {}".format(result.stderr))
if not result.stdout:
raise ValueError("The specified branch, tag or commit SHA ('{}') was not found on the remote repository."
.format(self.unresolved_ref))
resolved_ref = result.stdout.strip()
self.sha1_validate(resolved_ref)
self.resolved_ref = resolved_ref
else:
# The ref already was a valid SHA hash
self.resolved_ref = self.unresolved_ref

return self.resolved_ref
4 changes: 4 additions & 0 deletions binderhub/static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ function updateRepoText() {
$("#ref").prop("disabled", true);
$("label[for=ref]").prop("disabled", true);
}
else if (provider === "hg") {
text = "Arbitrary Mercurial repository URL (http://hg.example.com/repo)";
tag_text = "Mercurial branch, tag, topic or commit SHA";
}
$("#repository").attr('placeholder', text);
$("label[for=repository]").text(text);
$("#ref").attr('placeholder', tag_text);
Expand Down
1 change: 1 addition & 0 deletions binderhub/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ <h4 id="form-header" class='row'>Build and launch a repository</h4>
<li class="dropdown-item" value="gist"><a href="#">Gist</a></li>
<li class="dropdown-item" value="gl"><a href="#">GitLab.com</a></li>
<li class="dropdown-item" value="git"><a href="#">Git repository</a></li>
<li class="dropdown-item" value="hg"><a href="#">Mercurial repository</a></li>
<li class="dropdown-item" value="zenodo"><a href="#">Zenodo DOI</a></li>
<li class="dropdown-item" value="figshare"><a href="#">Figshare DOI</a></li>
<li class="dropdown-item" value="hydroshare"><a href="#">Hydroshare resource</a></li>
Expand Down
25 changes: 24 additions & 1 deletion binderhub/tests/test_repoproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from binderhub.repoproviders import (
tokenize_spec, strip_suffix, GitHubRepoProvider, GitRepoProvider,
GitLabRepoProvider, GistRepoProvider, ZenodoProvider, FigshareProvider,
HydroshareProvider, DataverseProvider
HydroshareProvider, DataverseProvider, MercurialRepoProvider
)


Expand Down Expand Up @@ -404,3 +404,26 @@ def test_gist_secret():

provider = GistRepoProvider(spec=spec, allow_secret_gist=True)
assert IOLoop().run_sync(provider.get_resolved_ref) is not None


@pytest.mark.parametrize('url,unresolved_ref,resolved_ref', [
['https://foss.heptapod.net/graphics/plot-covid19-fr',
'3f1209cb613a',
'3f1209cb613a1286e555d8cabe722c1be2a6f123'],
['https://foss.heptapod.net/pypy/pypy',
'release-pypy3.7-v7.3.2rc3',
'87875bf2dfd8fe682a49e010f6636a871b1308e6']
])
def test_mercurial_ref(url, unresolved_ref, resolved_ref):
spec = '{}/{}'.format(url, unresolved_ref)
provider = MercurialRepoProvider(spec=spec)
slug = provider.get_build_slug()
assert slug == url
full_url = provider.get_repo_url()
assert full_url == url
ref = IOLoop().run_sync(provider.get_resolved_ref)
assert ref == resolved_ref
ref_url = IOLoop().run_sync(provider.get_resolved_ref_url)
assert ref_url == full_url
resolved_spec = IOLoop().run_sync(provider.get_resolved_spec)
assert resolved_spec == quote(url, safe='') + f'/{resolved_ref}'

0 comments on commit 931e7f1

Please sign in to comment.