By default run Mercurial tests + enable the topic extension from code (no need for config file)
MODIFY
.github/workflows/test.yml
.github/workflows/test.yml
@@ -106,6 +106,7 @@ jobs:
python setup.py bdist_wheel
pip install dist/*.whl
pip freeze
+ pip install mercurial hg-evolve
- name: "Run tests"
run: |

MODIFY
Dockerfile
Dockerfile
@@ -18,9 +18,8 @@ FROM alpine:${ALPINE_VERSION}
# install python, git, bash, mercurial
RUN apk add --no-cache git git-lfs python3 py-pip bash docker mercurial
-# install and activate the evolve and topic Mercurial extensions
+# install hg-evolve (Mercurial extensions)
RUN pip3 install hg-evolve --user --no-cache-dir
-RUN mkdir -p /etc/mercurial/hgrc.d && echo -e "[extensions]\nevolve =\ntopic =\n" > /etc/mercurial/hgrc.d/evolve.rc
# install repo2docker
COPY --from=0 /tmp/wheelhouse /tmp/wheelhouse

MODIFY
repo2docker/contentproviders/mercurial.py
repo2docker/contentproviders/mercurial.py
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")
+args_enabling_topic = ["--config", "extensions.topic="]
class Mercurial(ContentProvider):
@@ -43,12 +14,11 @@ class Mercurial(ContentProvider):
return None
try:
subprocess.check_output(
- ["hg", "identify", source, "--config", "extensions.hggit=!"],
+ ["hg", "identify", source, "--config", "extensions.hggit=!"]
+ + args_enabling_topic,
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}
@@ -66,7 +36,7 @@ class Mercurial(ContentProvider):
output_dir,
"--config",
"phases.publish=False",
- ]
+ ] + args_enabling_topic
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
@@ -85,7 +55,7 @@ class Mercurial(ContentProvider):
if ref is not None:
try:
for line in execute_cmd(
- ["hg", "update", "--clean", ref],
+ ["hg", "update", "--clean", ref] + args_enabling_topic,
cwd=output_dir,
capture=yield_output,
):
@@ -96,7 +66,7 @@ class Mercurial(ContentProvider):
)
raise ValueError("Failed to update to ref {}".format(ref))
- cmd = ["hg", "identify", "-i"]
+ cmd = ["hg", "identify", "-i"] + args_enabling_topic
sha1 = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=output_dir)
self._node_id = sha1.stdout.read().decode().strip()

MODIFY
tests/unit/contentproviders/test_mercurial.py
tests/unit/contentproviders/test_mercurial.py
from pathlib import Path
import subprocess
from tempfile import TemporaryDirectory
+import os
+from distutils.util import strtobool
import pytest
from repo2docker.contentproviders import Mercurial
-from repo2docker.contentproviders.mercurial import (
- HG_REQUIRED,
- HG_EVOLVE_REQUIRED,
- is_mercurial_available,
+from repo2docker.contentproviders.mercurial import args_enabling_topic
+
+SKIP_HG = strtobool(os.environ.get("REPO2DOCKER_SKIP_HG_TESTS", "False"))
+SKIP_HG_EVOLVE = SKIP_HG or strtobool(
+ os.environ.get("REPO2DOCKER_SKIP_HG_EVOLVE_TESTS", "False")
)
-skip_if_no_hg = pytest.mark.skipif(
- not HG_REQUIRED and not is_mercurial_available(),
- reason="not HG_REQUIRED and Mercurial not available",
+skip_if_no_hg_tests = pytest.mark.skipif(
+ SKIP_HG,
+ reason="REPO2DOCKER_SKIP_HG_TESTS",
+)
+skip_if_no_evolve_tests = pytest.mark.skipif(
+ SKIP_HG_EVOLVE,
+ reason="REPO2DOCKER_SKIP_HG_EVOLVE_TESTS",
)
+if SKIP_HG_EVOLVE:
+ args_enabling_topic = []
-def is_evolve_available():
- if not is_mercurial_available():
- return False
- output = subprocess.getoutput("hg version -v")
- return " evolve " in output
+@skip_if_no_hg_tests
+def test_if_mercurial_is_available():
+ subprocess.check_output(["hg", "version"])
-EVOLVE_AVAILABLE = is_evolve_available()
-if HG_EVOLVE_REQUIRED and not EVOLVE_AVAILABLE:
- raise RuntimeError("HG_EVOLVE_REQUIRED and not EVOLVE_AVAILABLE")
+@skip_if_no_evolve_tests
+def test_if_topic_is_available():
+ """Check that the topic extension can be enabled"""
+ output = subprocess.getoutput("hg version -v --config extensions.topic=")
+ assert "failed to import extension topic" not in output
def _add_content_to_hg(repo_dir):
@@ -39,19 +48,22 @@ 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)
+ if not SKIP_HG_EVOLVE:
+
+ def check_call(command):
+ subprocess.check_call(command + args_enabling_topic, cwd=repo_dir)
+
+ check_call(["hg", "topic", "test-topic"])
+ check_call(["hg", "commit", "-m", "Test commit in topic test-topic"])
+ check_call(["hg", "up", "default"])
def _get_node_id(repo_dir):
"""Get repository's current commit node ID (currently SHA1)."""
node_id = subprocess.Popen(
- ["hg", "identify", "-i"], stdout=subprocess.PIPE, cwd=repo_dir
+ ["hg", "identify", "-i"] + args_enabling_topic,
+ stdout=subprocess.PIPE,
+ cwd=repo_dir,
)
return node_id.stdout.read().decode().strip()
@@ -77,7 +89,7 @@ def hg_repo_with_content(hg_repo):
yield hg_repo, node_id
-@skip_if_no_hg
+@skip_if_no_hg_tests
def test_detect_mercurial(hg_repo_with_content, repo_with_content):
mercurial = Mercurial()
assert mercurial.detect("this-is-not-a-directory") is None
@@ -90,7 +102,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
+@skip_if_no_hg_tests
def test_clone(hg_repo_with_content):
"""Test simple hg clone to a target dir"""
upstream, node_id = hg_repo_with_content
@@ -105,7 +117,7 @@ def test_clone(hg_repo_with_content):
assert mercurial.content_id == node_id
-@skip_if_no_hg
+@skip_if_no_hg_tests
def test_bad_ref(hg_repo_with_content):
"""
Test trying to update to a ref that doesn't exist
@@ -118,11 +130,7 @@ def test_bad_ref(hg_repo_with_content):
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
+@skip_if_no_evolve_tests
def test_ref_topic(hg_repo_with_content):
"""
Test trying to update to a topic

By default run Mercurial tests + enable the topic extension from code (no need for config file)