Repository: conda/conda-build

Issue:
Handling double slash
Would be nice if we could handle a double backslash [here](https://github.com/conda/conda-build/blob/a8dbb9fa1919e91dbc28a2166b7e06054a414484/conda_build/build.py#L262). This came up in this [context](https://github.com/conda-forge/conda-feedstock/pull/3#issuecomment-238559684).

cc @janschulz



Discussion:

Resolving patch:
diff --git a/conda_build/metadata.py b/conda_build/metadata.py
--- a/conda_build/metadata.py
+++ b/conda_build/metadata.py
@@ -697,7 +697,13 @@ def ignore_prefix_files(self):
         return ret
 
     def always_include_files(self):
-        return self.get_value('build/always_include_files', [])
+        files = self.get_value('build/always_include_files', [])
+        if any('\\' in i for i in files):
+            raise RuntimeError("build/always_include_files paths must use / "
+                                "as the path delimiter on Windows")
+        if on_win:
+            files = [f.replace("/", "\\") for f in files]
+        return files
 
     def include_recipe(self):
         return self.get_value('build/include_recipe', True)


Test patch:
diff --git a/conda_build/create_test.py b/conda_build/create_test.py
--- a/conda_build/create_test.py
+++ b/conda_build/create_test.py
@@ -9,7 +9,7 @@
 from os.path import join, exists, isdir
 import sys
 
-from conda_build.utils import copy_into, get_ext_files
+from conda_build.utils import copy_into, get_ext_files, on_win
 from conda_build import source
 
 
@@ -55,6 +55,9 @@ def create_files(dir_path, m, config):
     if m.get_value('test/source_files') and not isdir(config.work_dir):
         source.provide(m.path, m.get_section('source'), config=config)
     for pattern in m.get_value('test/source_files', []):
+        if on_win and '\\' in pattern:
+            raise RuntimeError("test/source_files paths must use / "
+                                "as the path delimiter on Windows")
         has_files = True
         files = glob.glob(join(config.work_dir, pattern))
         for f in files:
diff --git a/tests/test-recipes/fail/backslash_in_include_files/meta.yaml b/tests/test-recipes/fail/backslash_in_include_files/meta.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/fail/backslash_in_include_files/meta.yaml
@@ -0,0 +1,16 @@
+package:
+  name: backslash_in_include_files
+  version: 1.0
+
+build:
+  always_include_files:
+    - include\abstract.h
+    - include\\abstract.h
+
+requirements:
+  build:
+    - python
+
+test:
+  commands:
+    - IF NOT EXIST "%PREFIX%\include\abstract.h" exit 1
diff --git a/tests/test-recipes/metadata/_backslash_in_include_files/meta.yaml b/tests/test-recipes/metadata/_backslash_in_include_files/meta.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_backslash_in_include_files/meta.yaml
@@ -0,0 +1,15 @@
+package:
+  name: backslash_in_include_files
+  version: 1.0
+
+build:
+  always_include_files:
+    - include/abstract.h
+
+requirements:
+  build:
+    - python
+
+test:
+  commands:
+    - IF NOT EXIST "%PREFIX%\include\abstract.h" exit 1
diff --git a/tests/test-recipes/metadata/always_include_files_glob/meta.yaml b/tests/test-recipes/metadata/always_include_files_glob/meta.yaml
--- a/tests/test-recipes/metadata/always_include_files_glob/meta.yaml
+++ b/tests/test-recipes/metadata/always_include_files_glob/meta.yaml
@@ -7,7 +7,7 @@ build:
   always_include_files:
     - lib/libpng*.dylib  [osx]
     - lib/libpng*.so*     [linux]
-    - Library\lib\libpng*.lib [win]
+    - Library/lib/libpng*.lib [win]
 
 requirements:
     build:
diff --git a/tests/test_api_build.py b/tests/test_api_build.py
--- a/tests/test_api_build.py
+++ b/tests/test_api_build.py
@@ -426,6 +426,13 @@ def test_debug_build_option(testing_workdir, test_config, caplog, capfd):
     assert debug_message in caplog.text()
 
 
+@pytest.mark.skipif(not on_win, reason="only Windows is insane enough to have backslashes in paths")
+def test_backslash_in_always_include_files_path(test_config):
+    api.build(os.path.join(metadata_dir, '_backslash_in_include_files'))
+    with pytest.raises(RuntimeError):
+        api.build(os.path.join(fail_dir, 'backslash_in_include_files'))
+
+
 def test_build_metadata_object(test_config):
     d = defaultdict(dict)
     d['package']['name'] = 'test_package'