diff --git a/appveyor.yml b/appveyor.yml index 91030b6f13..00438476d6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,16 +6,16 @@ environment: CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\tools\\appveyor\\run_with_env.cmd" matrix: - - PYTHON: "C:\\Miniconda36-x64" - PYTHON_VERSION: "3.6" - PYTHON_ARCH: "64" + - SYS_PYTHON: "C:\\Miniconda36-x64" + SYS_PYTHON_VERSION: "3.6" + SYS_PYTHON_ARCH: "64" - - PYTHON: "C:\\Miniconda-x64" - PYTHON_VERSION: "2.7" - PYTHON_ARCH: "64" + - SYS_PYTHON: "C:\\Miniconda-x64" + SYS_PYTHON_VERSION: "2.7" + SYS_PYTHON_ARCH: "64" init: - - ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH% %HOME% + - ECHO %SYS_PYTHON% %SYS_PYTHON_VERSION% %SYS_PYTHON_ARCH% %HOME% install: @@ -30,8 +30,8 @@ install: throw "There are newer queued builds for this pull request, failing early." } # these correspond to folder naming of miniconda installs on appveyor. See # https://www.appveyor.com/docs/installed-software#python - - if "%PYTHON_VERSION%" == "3.6" set "BASE_PYTHON_VERSION=36" - - if "%PYTHON_ARCH%" == "64" set "ARCH_LABEL=-x64" + - if "%SYS_PYTHON_VERSION%" == "3.6" set "BASE_PYTHON_VERSION=36" + - if "%SYS_PYTHON_ARCH%" == "64" set "ARCH_LABEL=-x64" # These are already installed on appveyor. Update them. - set "CONDA_ROOT=C:\Miniconda%BASE_PYTHON_VERSION%%ARCH_LABEL%" - set "PATH=%CONDA_ROOT%;%CONDA_ROOT%\Scripts;%CONDA_ROOT%\Library\bin;%PATH%" @@ -44,7 +44,7 @@ install: - python -c "import sys; print(sys.prefix)" - conda update -q --all - conda install -q pip pytest pytest-cov jinja2 patch flake8 mock requests contextlib2 chardet glob2 perl pyflakes pycrypto posix m2-git anaconda-client numpy conda-verify beautifulsoup4 pytest-xdist pytest-mock filelock pkginfo psutil - - if "%PYTHON_VERSION%" == "2.7" conda install -q scandir + - if "%SYS_PYTHON_VERSION%" == "2.7" conda install -q scandir # this is to ensure dependencies - python --version - python -c "import struct; print(struct.calcsize('P') * 8)" @@ -71,7 +71,6 @@ test_script: - mkdir C:\cbtmp # unset other language env vars - we only want to test if conda-build sets them itself - set PERL= - - set PYTHON= - set LUA= - set R= # cache several files to avoid race condition errors @@ -81,7 +80,7 @@ test_script: - conda create -n blarg -yq --download-only python=3.4 libpng=1.6.17 - conda create -n blarg -yq --download-only python=3.5 libpng=1.6.17 # no libpng here because we already have the right version from the 3.5 install - - conda create -n blarg -yq --download-only python=3.6 + - conda create -n blarg -yq --download-only python - conda create -n blarg -yq --download-only cmake - py.test --color=yes -v --cov conda_build --cov-report xml tests --basetemp C:\cbtmp -n 0 -m "serial" # remove all folders to avoid permission errors. Leave root files (may have coverage info there) @@ -96,4 +95,4 @@ test_script: on_success: - conda install -c conda-forge codecov - - codecov --env PYTHON_VERSION --file C:\projects\conda-build\coverage.xml + - codecov --env SYS_PYTHON_VERSION --file C:\projects\conda-build\coverage.xml diff --git a/conda_build/environ.py b/conda_build/environ.py index 1f8961a0de..e67982bfd6 100644 --- a/conda_build/environ.py +++ b/conda_build/environ.py @@ -242,7 +242,7 @@ def get_hg_build_info(repo): return d -def get_dict(m, prefix=None, for_env=True, skip_build_id=False): +def get_dict(m, prefix=None, for_env=True, skip_build_id=False, escape_backslash=False): if not prefix: prefix = m.config.host_prefix @@ -250,10 +250,10 @@ def get_dict(m, prefix=None, for_env=True, skip_build_id=False): d = conda_build_vars(prefix, m.config) # languages - d.update(python_vars(m, prefix)) - d.update(perl_vars(m, prefix)) - d.update(lua_vars(m, prefix)) - d.update(r_vars(m, prefix)) + d.update(python_vars(m, prefix, escape_backslash)) + d.update(perl_vars(m, prefix, escape_backslash)) + d.update(lua_vars(m, prefix, escape_backslash)) + d.update(r_vars(m, prefix, escape_backslash)) if m: d.update(meta_vars(m, skip_build_id=skip_build_id)) @@ -302,21 +302,33 @@ def conda_build_vars(prefix, config): } -def python_vars(metadata, prefix): +def python_vars(metadata, prefix, escape_backslash): py_ver = get_py_ver(metadata.config) + stdlib_dir = utils.get_stdlib_dir(prefix, py_ver) + sp_dir = utils.get_site_packages(prefix, py_ver) + + if utils.on_win and escape_backslash: + stdlib_dir = stdlib_dir.replace('\\', '\\\\') + sp_dir = sp_dir.replace('\\', '\\\\') + vars_ = { 'CONDA_PY': ''.join(py_ver.split('.')[:2]), 'PY3K': str(int(int(py_ver[0]) >= 3)), 'PY_VER': py_ver, - 'STDLIB_DIR': utils.get_stdlib_dir(prefix, py_ver), - 'SP_DIR': utils.get_site_packages(prefix, py_ver), + 'STDLIB_DIR': stdlib_dir, + 'SP_DIR': sp_dir, } build_or_host = 'host' if metadata.is_cross else 'build' deps = [str(ms.name) for ms in metadata.ms_depends(build_or_host)] if 'python' in deps or metadata.name(fail_ok=True) == 'python': + python_bin = metadata.config.python_bin(prefix, metadata.config.host_subdir) + + if utils.on_win and escape_backslash: + python_bin = python_bin.replace('\\', '\\\\') + vars_.update({ # host prefix is always fine, because it is the same as build when is_cross is False - 'PYTHON': metadata.config.python_bin(prefix, metadata.config.host_subdir), + 'PYTHON': python_bin, }) np_ver = metadata.config.variant.get('numpy', get_default_variant(metadata.config)['numpy']) @@ -326,7 +338,7 @@ def python_vars(metadata, prefix): return vars_ -def perl_vars(metadata, prefix): +def perl_vars(metadata, prefix, escape_backslash): vars_ = { 'PERL_VER': get_perl_ver(metadata.config), 'CONDA_PERL': get_perl_ver(metadata.config), @@ -334,14 +346,19 @@ def perl_vars(metadata, prefix): build_or_host = 'host' if metadata.is_cross else 'build' deps = [str(ms.name) for ms in metadata.ms_depends(build_or_host)] if 'perl' in deps or metadata.name(fail_ok=True) == 'perl': + perl_bin = metadata.config.perl_bin(prefix, metadata.config.host_subdir) + + if utils.on_win and escape_backslash: + perl_bin = perl_bin.replace('\\', '\\\\') + vars_.update({ # host prefix is always fine, because it is the same as build when is_cross is False - 'PERL': metadata.config.perl_bin(prefix, metadata.config.host_subdir), + 'PERL': perl_bin, }) return vars_ -def lua_vars(metadata, prefix): +def lua_vars(metadata, prefix, escape_backslash): vars_ = { 'LUA_VER': get_lua_ver(metadata.config), 'CONDA_LUA': get_lua_ver(metadata.config), @@ -349,15 +366,21 @@ def lua_vars(metadata, prefix): build_or_host = 'host' if metadata.is_cross else 'build' deps = [str(ms.name) for ms in metadata.ms_depends(build_or_host)] if 'lua' in deps: + lua_bin = metadata.config.lua_bin(prefix, metadata.config.host_subdir) + lua_include_dir = get_lua_include_dir(metadata.config) + + if utils.on_win and escape_backslash: + lua_bin = lua_bin.replace('\\', '\\\\') + lua_include_dir = lua_include_dir.replace('\\', '\\\\') + vars_.update({ - 'LUA': metadata.config.lua_bin(prefix, - metadata.config.host_subdir), - 'LUA_INCLUDE_DIR': get_lua_include_dir(metadata.config), + 'LUA': lua_bin, + 'LUA_INCLUDE_DIR': lua_include_dir, }) return vars_ -def r_vars(metadata, prefix): +def r_vars(metadata, prefix, escape_backslash): vars_ = { 'R_VER': get_r_ver(metadata.config), 'CONDA_R': get_r_ver(metadata.config), @@ -367,8 +390,13 @@ def r_vars(metadata, prefix): deps = [str(ms.name) for ms in metadata.ms_depends(build_or_host)] if 'r-base' in deps or 'mro-base' in deps or metadata.name(fail_ok=True) in ( 'r-base', 'mro-base'): + r_bin = metadata.config.r_bin(prefix, metadata.config.host_subdir) + + if utils.on_win and escape_backslash: + r_bin = r_bin.replace('\\', '\\\\') + vars_.update({ - 'R': metadata.config.r_bin(prefix, metadata.config.host_subdir), + 'R': r_bin, }) return vars_ diff --git a/conda_build/jinja_context.py b/conda_build/jinja_context.py index 28dc3ded38..3dcb5e5887 100644 --- a/conda_build/jinja_context.py +++ b/conda_build/jinja_context.py @@ -14,7 +14,7 @@ from .utils import (get_installed_packages, apply_pin_expressions, get_logger, HashableDict, string_types) from .render import get_env_dependencies -from .utils import copy_into, check_call_env, rm_rf, ensure_valid_spec +from .utils import copy_into, check_call_env, rm_rf, ensure_valid_spec, on_win from .variants import DEFAULT_COMPILERS from .exceptions import CondaBuildException from . import _load_setup_py_data @@ -492,7 +492,8 @@ def context_processor(initial_metadata, recipe_dir, config, permit_undefined_jin initial_metadata: Augment the context with values from this MetaData object. Used to bootstrap metadata contents via multiple parsing passes. """ - ctx = get_environ(m=initial_metadata, for_env=False, skip_build_id=skip_build_id) + ctx = get_environ(m=initial_metadata, for_env=False, skip_build_id=skip_build_id, + escape_backslash=True) environ = dict(os.environ) environ.update(get_environ(m=initial_metadata, skip_build_id=skip_build_id)) diff --git a/conda_build/metadata.py b/conda_build/metadata.py index 2e076e7023..e613951a15 100644 --- a/conda_build/metadata.py +++ b/conda_build/metadata.py @@ -218,6 +218,8 @@ def yamlize(data): jinja2 # Avoid pyflakes failure: 'jinja2' imported but unused except ImportError: raise exceptions.UnableToParseMissingJinja2(original=e) + print("Problematic recipe:", file=sys.stderr) + print(data, file=sys.stderr) raise exceptions.UnableToParse(original=e) diff --git a/conda_build/skeletons/pypi.py b/conda_build/skeletons/pypi.py index c8e0e2c05d..b1a53490f2 100644 --- a/conda_build/skeletons/pypi.py +++ b/conda_build/skeletons/pypi.py @@ -341,9 +341,10 @@ def skeletonize(packages, output_dir=".", version=None, recursive=False, '--ignore-installed --no-cache-dir -vvv ' + ' '.join(setup_options) + '"') - # Always require python as a dependency + # Always require python as a dependency. Pip is because we use pip for + # the install line. ordered_recipe['requirements'] = OrderedDict() - ordered_recipe['requirements']['host'] = sorted(['python'] + + ordered_recipe['requirements']['host'] = sorted(['python', 'pip'] + list(set(d['build_depends']))) ordered_recipe['requirements']['run'] = sorted(['python'] + list(set(d['run_depends'])))