Repository: conda/conda-build

Issue:
Error about mercurial, while it is not being used.
When trying to build my recipe for sdl2, which worked correctly before, I now get the error `ValueError: Your recipe uses mercurial in build, but mercurial does not yet support Python 3.  Please handle all of your mercurial actions outside of your build script.`, even though I am not using any mercurial feature at all.

Here is the full traceback (if it is of any use):

~~~
PS > conda build sdl2
BUILD START: sdl2-2.0.4-vc14_0
    (actual version deferred until further download or env creation)
updating index in: C:\Anaconda3\conda-bld\win-64
updating index in: C:\Anaconda3\conda-bld\noarch

The following NEW packages will be INSTALLED:

    cmake:          3.3.1-0
    pip:            8.1.2-py35_0
    python:         3.5.2-0
    setuptools:     27.2.0-py35_1
    vs2015_runtime: 14.0.25123-0
    wheel:          0.29.0-py35_0

Traceback (most recent call last):
  File "C:\Anaconda3\Scripts\conda-build-script.py", line 5, in <module>
    sys.exit(conda_build.cli.main_build.main())
  File "C:\Anaconda3\lib\site-packages\conda_build\cli\main_build.py", line 242, in main
    execute(sys.argv[1:])
  File "C:\Anaconda3\lib\site-packages\conda_build\cli\main_build.py", line 234, in execute
    already_built=None, config=config)
  File "C:\Anaconda3\lib\site-packages\conda_build\api.py", line 77, in build
    need_source_download=need_source_download, config=config)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 1099, in build_tree
    config=recipe_config)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 654, in build
    raise ValueError("Your recipe uses mercurial in build, but mercurial"
ValueError: Your recipe uses mercurial in build, but mercurial does not yet support Python 3.  Please handle all of your mercurial actions outside of your build script.
~~~




Discussion:
duplicate of #1488 I think.  Closing to consolidate discussion there.

I should add that if you can link to your SDL2 recipe, that would be extremely helpful.

Sure, here it is: https://github.com/conda-forge/staged-recipes/tree/d3efa39c64534d6ead3faebd6ec9a97d5d5d2550/recipes/sdl2

Judging by the other issue report, the culprit is probably this line: `dev_url: http://hg.libsdl.org/SDL`


Resolving patch:
diff --git a/conda_build/metadata.py b/conda_build/metadata.py
--- a/conda_build/metadata.py
+++ b/conda_build/metadata.py
@@ -825,23 +825,6 @@ def __repr__(self):
         '''
         return self.__str__()
 
-    @property
-    def uses_vcs_in_meta(self):
-        """returns name of vcs used if recipe contains metadata associated with version control systems.
-        If this metadata is present, a download/copy will be forced in parse_or_try_download.
-        """
-        vcs_types = ["git", "svn", "hg"]
-        # We would get here if we use Jinja2 templating, but specify source with path.
-        with open(self.meta_path) as f:
-            metayaml = f.read()
-            for vcs in vcs_types:
-                matches = re.findall(r"{}_[^\.\s\'\"]+".format(vcs.upper()), metayaml)
-                if len(matches) > 0:
-                    if vcs == "hg":
-                        vcs = "mercurial"
-                    return vcs
-        return None
-
     @property
     def uses_setup_py_in_meta(self):
         with open(self.meta_path) as f:
@@ -867,18 +850,41 @@ def uses_jinja(self):
             matches = re.findall(r"{{.*}}", metayaml)
         return len(matches) > 0
 
+    @property
+    def uses_vcs_in_meta(self):
+        """returns name of vcs used if recipe contains metadata associated with version control systems.
+        If this metadata is present, a download/copy will be forced in parse_or_try_download.
+        """
+        vcs_types = ["git", "svn", "hg"]
+        # We would get here if we use Jinja2 templating, but specify source with path.
+        with open(self.meta_path) as f:
+            metayaml = f.read()
+            for vcs in vcs_types:
+                matches = re.findall(r"{}_[^\.\s\'\"]+".format(vcs.upper()), metayaml)
+                if len(matches) > 0:
+                    if vcs == "hg":
+                        vcs = "mercurial"
+                    return vcs
+        return None
+
     @property
     def uses_vcs_in_build(self):
         build_script = "bld.bat" if on_win else "build.sh"
         build_script = os.path.join(os.path.dirname(self.meta_path), build_script)
-        if os.path.isfile(build_script):
-            vcs_types = ["git", "svn", "hg"]
-            with open(self.meta_path) as f:
-                build_script = f.read()
-                for vcs in vcs_types:
-                    matches = re.findall(r"{}(?:\.exe)?".format(vcs), build_script)
-                    if len(matches) > 0:
-                        if vcs == "hg":
-                            vcs = "mercurial"
-                        return vcs
+        for recipe_file in (build_script, self.meta_path):
+            if os.path.isfile(recipe_file):
+                vcs_types = ["git", "svn", "hg"]
+                with open(recipe_file) as f:
+                    build_script = f.read()
+                    for vcs in vcs_types:
+                        # commands are assumed to have 3 parts:
+                        #   1. the vcs command, optionally with an exe extension
+                        #   2. a subcommand - for example, "clone"
+                        #   3. a target url or other argument
+                        matches = re.findall(r"{}(?:\.exe)?(?:\s+\w+\s+[\w\/\.:@]+)".format(vcs),
+                                            build_script, flags=re.IGNORECASE)
+                        if len(matches) > 0:
+                            if vcs == "hg":
+                                vcs = "mercurial"
+                            return vcs
         return None


Test patch:
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -1,8 +1,30 @@
+import os
 import unittest
 
 from conda_build.conda_interface import MatchSpec
 
 from conda_build.metadata import select_lines, handle_config_version
+from .utils import testing_workdir, test_config, test_metadata
+
+
+def test_uses_vcs_in_metadata(testing_workdir, test_metadata):
+    test_metadata.meta_path = os.path.join(testing_workdir, 'meta.yaml')
+    with open(test_metadata.meta_path, 'w') as f:
+        f.write('http://hg.something.com')
+    assert not test_metadata.uses_vcs_in_meta
+    assert not test_metadata.uses_vcs_in_build
+    with open(test_metadata.meta_path, 'w') as f:
+        f.write('hg something something')
+    assert not test_metadata.uses_vcs_in_meta
+    assert test_metadata.uses_vcs_in_build
+    with open(test_metadata.meta_path, 'w') as f:
+        f.write('hg.exe something something')
+    assert not test_metadata.uses_vcs_in_meta
+    assert test_metadata.uses_vcs_in_build
+    with open(test_metadata.meta_path, 'w') as f:
+        f.write('HG_WEEEEE')
+    assert test_metadata.uses_vcs_in_meta
+    assert not test_metadata.uses_vcs_in_build
 
 
 def test_select_lines():