Mercurial optional

pull/950/head
paugier 2020-09-10 07:58:21 +02:00
rodzic 96914545e1
commit 5bb586931b
2 zmienionych plików z 105 dodań i 4 usunięć

Wyświetl plik

@ -1,8 +1,39 @@
import subprocess
import os
from distutils.util import strtobool
from .base import ContentProvider, ContentProviderException
from ..utils import execute_cmd
HG_EVOLVE_REQUIRED = strtobool(
os.environ.get("REPO2DOCKER_HG_EVOLVE_REQUIRED", "False")
)
if HG_EVOLVE_REQUIRED:
if "REPO2DOCKER_HG_REQUIRED" in os.environ:
HG_REQUIRED = strtobool(os.environ["REPO2DOCKER_HG_REQUIRED"])
if not HG_REQUIRED:
raise ValueError(
"Incompatible values for environment variables "
"REPO2DOCKER_HG_EVOLVE_REQUIRED=1 and REPO2DOCKER_HG_REQUIRED=0"
)
else:
HG_REQUIRED = True
else:
HG_REQUIRED = strtobool(os.environ.get("REPO2DOCKER_HG_REQUIRED", "False"))
def is_mercurial_available():
try:
subprocess.check_output(["hg", "version"])
except subprocess.CalledProcessError:
return False
return True
if HG_REQUIRED and not is_mercurial_available():
raise RuntimeError("REPO2DOCKER_HG_REQUIRED but the command `hg` is not available")
class Mercurial(ContentProvider):
"""Provide contents of a remote Mercurial repository."""
@ -16,6 +47,8 @@ class Mercurial(ContentProvider):
stderr=subprocess.DEVNULL,
)
except subprocess.CalledProcessError:
# warning: if hg is not installed and `not HG_REQUIRED`,
# we return None even for a hg repo
return None
return {"repo": source, "ref": ref}
@ -26,7 +59,14 @@ class Mercurial(ContentProvider):
# make a clone of the remote repository
try:
cmd = ["hg", "clone", repo, output_dir]
cmd = [
"hg",
"clone",
repo,
output_dir,
"--config",
"phases.publish=False",
]
if ref is not None:
# don't update so the clone will include an empty working
# directory, the given ref will be updated out later
@ -35,9 +75,9 @@ class Mercurial(ContentProvider):
yield line
except subprocess.CalledProcessError as error:
msg = "Failed to clone repository from {repo}".format(repo=repo)
msg = f"Failed to clone repository from {repo}"
if ref is not None:
msg += " (ref {ref})".format(ref=ref)
msg += f" (ref {ref})"
msg += "."
raise ContentProviderException(msg) from error

Wyświetl plik

@ -5,6 +5,29 @@ from tempfile import TemporaryDirectory
import pytest
from repo2docker.contentproviders import Mercurial
from repo2docker.contentproviders.mercurial import (
HG_REQUIRED,
HG_EVOLVE_REQUIRED,
is_mercurial_available,
)
skip_if_no_hg = pytest.mark.skipif(
not HG_REQUIRED and not is_mercurial_available(),
reason="not HG_REQUIRED and Mercurial not available",
)
def is_evolve_available():
if not is_mercurial_available():
return False
output = subprocess.getoutput("hg version -v")
return " evolve " in output
EVOLVE_AVAILABLE = is_evolve_available()
if HG_EVOLVE_REQUIRED and not EVOLVE_AVAILABLE:
raise RuntimeError("HG_EVOLVE_REQUIRED and not EVOLVE_AVAILABLE")
def _add_content_to_hg(repo_dir):
@ -16,6 +39,14 @@ def _add_content_to_hg(repo_dir):
subprocess.check_call(["hg", "add", "test"], cwd=repo_dir)
subprocess.check_call(["hg", "commit", "-m", "Test commit"], cwd=repo_dir)
if EVOLVE_AVAILABLE:
subprocess.check_call(["hg", "topic", "test-topic"], cwd=repo_dir)
subprocess.check_call(
["hg", "commit", "-m", "Test commit in topic test-topic"],
cwd=repo_dir,
)
subprocess.check_call(["hg", "up", "default"], cwd=repo_dir)
def _get_node_id(repo_dir):
"""Get repository's current commit node ID (currently SHA1)."""
@ -46,6 +77,7 @@ def hg_repo_with_content(hg_repo):
yield hg_repo, node_id
@skip_if_no_hg
def test_detect_mercurial(hg_repo_with_content, repo_with_content):
mercurial = Mercurial()
assert mercurial.detect("this-is-not-a-directory") is None
@ -58,6 +90,7 @@ def test_detect_mercurial(hg_repo_with_content, repo_with_content):
assert mercurial.detect(hg_repo) == {"repo": hg_repo, "ref": None}
@skip_if_no_hg
def test_clone(hg_repo_with_content):
"""Test simple hg clone to a target dir"""
upstream, node_id = hg_repo_with_content
@ -72,9 +105,10 @@ def test_clone(hg_repo_with_content):
assert mercurial.content_id == node_id
@skip_if_no_hg
def test_bad_ref(hg_repo_with_content):
"""
Test trying to checkout a ref that doesn't exist
Test trying to update to a ref that doesn't exist
"""
upstream, node_id = hg_repo_with_content
with TemporaryDirectory() as clone_dir:
@ -82,3 +116,30 @@ def test_bad_ref(hg_repo_with_content):
with pytest.raises(ValueError):
for _ in Mercurial().fetch(spec, clone_dir):
pass
@pytest.mark.skipif(
not HG_EVOLVE_REQUIRED and not EVOLVE_AVAILABLE,
reason="not HG_EVOLVE_REQUIRED and hg-evolve not available",
)
@skip_if_no_hg
def test_ref_topic(hg_repo_with_content):
"""
Test trying to update to a topic
"""
upstream, node_id = hg_repo_with_content
node_id = subprocess.Popen(
["hg", "identify", "-i", "-r", "topic(test-topic)"],
stdout=subprocess.PIPE,
cwd=upstream,
)
node_id = node_id.stdout.read().decode().strip()
with TemporaryDirectory() as clone_dir:
spec = {"repo": upstream, "ref": "test-topic"}
mercurial = Mercurial()
for _ in mercurial.fetch(spec, clone_dir):
pass
assert (Path(clone_dir) / "test").exists()
assert mercurial.content_id == node_id