Repository: conda/conda-build

Issue:
Bug/regression in meta.yaml 'build/no_link' handling: overwriting no_link list with boolean
conda-build version 2.0.12

The bug is that at https://github.com/conda/conda-build/blob/master/conda_build/build.py#L563 the list gets created:

`    no_link = m.get_value('build/no_link')`

but then the same variable is overwritten with a bool at https://github.com/conda/conda-build/blob/master/conda_build/build.py#L574

`        no_link = is_no_link(no_link, fi)`

so next time around the loop, it gives the traceback:

```
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 255, in main
    execute(sys.argv[1:])
  File "C:\Anaconda3\lib\site-packages\conda_build\cli\main_build.py", line 247, in execute
    already_built=None, config=config, noverify=args.no_verify)
  File "C:\Anaconda3\lib\site-packages\conda_build\api.py", line 75, in build
    need_source_download=need_source_download, config=config)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 1231, in build_tree
    config=recipe_config)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 924, in build
    create_info_files(m, pkg_files, config=config, prefix=config.build_prefix)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 469, in create_info_files
    create_info_files_json(m, config.info_dir, prefix, files, files_with_prefix)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 570, in create_info_files_json
    files_json_files = build_info_files_json(m, prefix, files, files_with_prefix)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 550, in build_info_files_json
    no_link = is_no_link(no_link, fi)
  File "C:\Anaconda3\lib\site-packages\conda_build\build.py", line 517, in is_no_link
    if no_link is not None and short_path in no_link:
TypeError: argument of type 'bool' is not iterable
```


Discussion:

Resolving patch:
diff --git a/conda_build/build.py b/conda_build/build.py
--- a/conda_build/build.py
+++ b/conda_build/build.py
@@ -560,7 +560,7 @@ def path_type(path):
 
 
 def build_info_files_json_v1(m, prefix, files, files_with_prefix):
-    no_link = m.get_value('build/no_link')
+    no_link_files = m.get_value('build/no_link')
     files_json = []
     for fi in sorted(files):
         prefix_placeholder, file_mode = has_prefix(fi, files_with_prefix)
@@ -571,7 +571,7 @@ def build_info_files_json_v1(m, prefix, files, files_with_prefix):
             "size_in_bytes": os.path.getsize(path),
             "path_type": path_type(path),
         }
-        no_link = is_no_link(no_link, fi)
+        no_link = is_no_link(no_link_files, fi)
         if no_link:
             file_info["no_link"] = no_link
         if prefix_placeholder and file_mode:
@@ -981,10 +981,9 @@ def build(m, config, post=None, need_source_download=True, need_reparse_in_env=F
             f.write(u'\n')
 
         # Use script from recipe?
-        script = m.get_value('build/script', None)
+        script = utils.ensure_list(m.get_value('build/script', None))
         if script:
-            if isinstance(script, list):
-                script = '\n'.join(script)
+            script = '\n'.join(script)
 
         if isdir(src_dir):
             if utils.on_win:


Test patch:
diff --git a/tests/test-recipes/metadata/no_link/meta.yaml b/tests/test-recipes/metadata/no_link/meta.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/no_link/meta.yaml
@@ -0,0 +1,13 @@
+package:
+  name: test_no_link
+  version: 1.0
+
+build:
+  no_link:
+    - no_link_file.example
+    - no_link_file.example2
+  script:
+    - echo "something" > $PREFIX/no_link_file.example  # [not win]
+    - echo "something_else" > $PREFIX/no_link_file.example2  # [not win]
+    - echo "something" > %PREFIX%/no_link_file.example  # [win]
+    - echo "something_else" > %PREFIX%/no_link_file.example2  # [win]
diff --git a/tests/test-recipes/metadata/no_link/run_test.py b/tests/test-recipes/metadata/no_link/run_test.py
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/no_link/run_test.py
@@ -0,0 +1,5 @@
+import os
+f = os.path.join(os.getenv('PREFIX'), 'no_link_file.example')
+assert os.path.isfile(f), "File does not exist"
+assert os.stat(f).st_nlink <= 1, "File is hard-linked where it should not be (link count = {})".format(os.stat(f).st_nlink)
+assert not os.path.islink(f), "File is a symlink where it should not be"