Repository: conda/conda-build

Issue:
conda-build 2.0 is ignoring detect_binary_files_with_prefix
After updating to conda-build 2.0 I noticed that some packages were being build with prefix detection even though they were setting `detect_binary_files_with_prefix: false`

Checking out the code, I found that this commit removed the handling of this: https://github.com/conda/conda-build/commit/2b611bc4bb58f354abb5c5e1f52c6f75ac02380b#diff-ac55d744935b1f37a3369258b88e8f1fL278

Was this intentional? The documentation stills refers to this setting

In this package specifically (``gcc`), I don't want conda to replace prefixes in binaries because basically all gcc binaries have them. So when installing gcc in an environment conda needs to make a copy of every binary and this occupy a lot of space



Discussion:
Sorry, that's a regression.  It should respect that setting when it is false.  I tore it out because I changed the default behavior from not detecting to yes detecting.

As a workaround, there is a new argument, ignore_prefix_files that you can use right now.  I will restore the behavior for detect_binary_files_with_prefix being set to false in the next release.

http://conda.pydata.org/docs/building/meta-yaml.html#ignore-prefix-files

> As a workaround, there is a new argument, ignore_prefix_files that you can use right now. I will restore the behavior for detect_binary_files_with_prefix being set to false in the next release.

Yeah, but I still want the other relocation stuff. Also there are too many files to ignore. I will just use `1.21.14` to build `gcc` for now as this is the only package where I need to explicitly ignore this feature.

Thanks!

OK, clear.  Thanks.  I think tying the relocation stuff to ignore_prefix_files was a mistake, anyway.


Resolving patch:
diff --git a/conda_build/build.py b/conda_build/build.py
--- a/conda_build/build.py
+++ b/conda_build/build.py
@@ -242,12 +242,15 @@ def detect_and_record_prefix_files(m, files, prefix, config):
     text_has_prefix_files = m.has_prefix_files()
 
     ignore_files = m.ignore_prefix_files()
-    if ignore_files:
-        # do we have a list of files, or just ignore everything?
-        if hasattr(ignore_files, "__iter__"):
-            files_with_prefix = [f for f in files_with_prefix if f[2] not in ignore_files]
-        else:
-            files_with_prefix = []
+    ignore_types = set()
+    if not hasattr(ignore_files, "__iter__"):
+        if  ignore_files == True:
+            ignore_types.update(('text', 'binary'))
+        ignore_files = []
+    if not m.get_value('build/detect_binary_files_with_prefix', True):
+        ignore_types.update(('binary',))
+    ignore_files.extend([f[2] for f in files_with_prefix if f[1] in ignore_types and f[2] not in ignore_files])
+    files_with_prefix = [f for f in files_with_prefix if f[2] not in ignore_files]
 
     is_noarch = m.get_value('build/noarch_python') or is_noarch_python(m) or m.get_value('build/noarch')
 


Test patch:
diff --git a/tests/test-recipes/metadata/_detect_binary_files_with_prefix/bld.bat b/tests/test-recipes/metadata/_detect_binary_files_with_prefix/bld.bat
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_detect_binary_files_with_prefix/bld.bat
@@ -0,0 +1 @@
+python %RECIPE_DIR%\write_binary_has_prefix.py
diff --git a/tests/test-recipes/metadata/detect_binary_files_with_prefix/build.sh b/tests/test-recipes/metadata/_detect_binary_files_with_prefix/build.sh
similarity index 100%
rename from tests/test-recipes/metadata/detect_binary_files_with_prefix/build.sh
rename to tests/test-recipes/metadata/_detect_binary_files_with_prefix/build.sh
diff --git a/tests/test-recipes/metadata/detect_binary_files_with_prefix/meta.yaml b/tests/test-recipes/metadata/_detect_binary_files_with_prefix/meta.yaml
similarity index 100%
rename from tests/test-recipes/metadata/detect_binary_files_with_prefix/meta.yaml
rename to tests/test-recipes/metadata/_detect_binary_files_with_prefix/meta.yaml
diff --git a/tests/test-recipes/metadata/detect_binary_files_with_prefix/run_test.sh b/tests/test-recipes/metadata/_detect_binary_files_with_prefix/run_test.sh
similarity index 100%
rename from tests/test-recipes/metadata/detect_binary_files_with_prefix/run_test.sh
rename to tests/test-recipes/metadata/_detect_binary_files_with_prefix/run_test.sh
diff --git a/tests/test-recipes/metadata/detect_binary_files_with_prefix/write_binary_has_prefix.py b/tests/test-recipes/metadata/_detect_binary_files_with_prefix/write_binary_has_prefix.py
similarity index 100%
rename from tests/test-recipes/metadata/detect_binary_files_with_prefix/write_binary_has_prefix.py
rename to tests/test-recipes/metadata/_detect_binary_files_with_prefix/write_binary_has_prefix.py
diff --git a/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/bld.bat b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/bld.bat
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/bld.bat
@@ -0,0 +1 @@
+python %RECIPE_DIR%\write_binary_has_prefix.py
diff --git a/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/build.sh b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/build.sh
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/build.sh
@@ -0,0 +1 @@
+python $RECIPE_DIR/write_binary_has_prefix.py
diff --git a/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/meta.yaml b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/meta.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/meta.yaml
@@ -0,0 +1,6 @@
+package:
+  name: conda-build-test-skip-detect-binary-files-with-prefix
+  version: 1.0
+
+build:
+  detect_binary_files_with_prefix: false
diff --git a/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/run_test.sh b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/run_test.sh
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/run_test.sh
@@ -0,0 +1,3 @@
+cd $PREFIX
+cat binary-has-prefix
+cat binary-has-prefix | grep --invert-match $PREFIX
diff --git a/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/write_binary_has_prefix.py b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/write_binary_has_prefix.py
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_skip_detect_binary_files_with_prefix/write_binary_has_prefix.py
@@ -0,0 +1,10 @@
+import os
+
+prefix = os.environ['PREFIX']
+fn = '%s/binary-has-prefix' % prefix
+
+if not os.path.isdir(prefix):
+    os.makedirs(prefix)
+
+with open(fn, 'wb') as f:
+    f.write(prefix.encode('utf-8') + b'\x00')
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
@@ -672,6 +672,42 @@ def test_skip_compile_pyc(test_config):
     assert pyc_count == 2, "there should be 2 .pyc files, instead there were {}".format(pyc_count)
 
 
+#@pytest.mark.skipif(on_win, reason="binary prefixes not supported on Windows")
+def test_detect_binary_files_with_prefix(test_config):
+    recipe = os.path.join(metadata_dir, "_detect_binary_files_with_prefix")
+    fn = api.get_output_file_path(recipe, config=test_config)
+    api.build(recipe, config=test_config)
+    matches = []
+    with tarfile.open(fn) as tf:
+        has_prefix = tf.extractfile('info/has_prefix')
+        contents = [p.strip().decode('utf-8') for p in
+                    has_prefix.readlines()]
+        has_prefix.close()
+        matches = [entry for entry in contents if entry.endswith('binary-has-prefix') or
+                                                  entry.endswith('"binary-has-prefix"')]
+    assert len(matches) == 1, "binary-has-prefix not recorded in info/has_prefix"
+    assert ' binary ' in matches[0], "binary-has-prefix not recorded as binary in info/has_prefix"
+
+
+def test_skip_detect_binary_files_with_prefix(test_config):
+    recipe = os.path.join(metadata_dir, "_skip_detect_binary_files_with_prefix")
+    fn = api.get_output_file_path(recipe, config=test_config)
+    api.build(recipe, config=test_config)
+    matches = []
+    with tarfile.open(fn) as tf:
+        try:
+            has_prefix = tf.extractfile('info/has_prefix')
+            contents = [p.strip().decode('utf-8') for p in
+                        has_prefix.readlines()]
+            has_prefix.close()
+            matches = [entry for entry in contents if entry.endswith('binary-has-prefix') or
+                                                      entry.endswith('"binary-has-prefix"')]
+        except:
+            pass
+    assert len(matches) == 0, "binary-has-prefix recorded in info/has_prefix despite:" \
+                              "build/detect_binary_files_with_prefix: false"
+
+
 def test_fix_permissions(test_config):
     recipe = os.path.join(metadata_dir, "fix_permissions")
     fn = api.get_output_file_path(recipe, config=test_config)