Repository: conda/conda

Issue:
Problem: conda-build doesn't clean up temporary files
@gabm commented on [Thu Aug 17 2017](https://github.com/conda/conda-build/issues/2289)

It seems conda-build doesn't clean up temporary files located under `/tmp/tmpxxxxxx` or `User/../AppData/Local/tmpxxxxxx` on windows. After the build these folders contain the decompressed packages that I suppose have been installed as dependencies during the build. Maybe its also a conda problem?!

Anyway, on our Windows build machine we accumulated 25Gb within some weeks .... 

---

@gabm commented on [Thu Aug 17 2017](https://github.com/conda/conda-build/issues/2289#issuecomment-323134590)

.. the same files are located again in `miniconda3/pkgs`... 

---

@msarahan commented on [Thu Aug 17 2017](https://github.com/conda/conda-build/issues/2289#issuecomment-323158750)

Conda-build uses this functionality in conda for temporary folders: https://github.com/conda/conda/blob/dbe99de1d45206c5d6f2e19017a9e2466f81dc6d/conda/compat.py#L23-L67

When we get files from packages, we do so with the package_has_file function: https://github.com/conda/conda-build/blob/master/conda_build/utils.py#L714-L730

package_has_file does not ever extract the whole package.  This seems like a conda issue.  Sorry, I don't currently have time to investigate this more.  I can move this issue to the conda repo if you'd like.



---

@gabm commented on [Thu Aug 17 2017](https://github.com/conda/conda-build/issues/2289#issuecomment-323170508)

ok, then please move it there... If I find time, I'll have a further look. I realised some strange folders `/tmp/tmpxxxxxxx` some weeks ago, so could be easy to reproduce...




Discussion:

Resolving patch:
diff --git a/conda/gateways/disk/delete.py b/conda/gateways/disk/delete.py
--- a/conda/gateways/disk/delete.py
+++ b/conda/gateways/disk/delete.py
@@ -30,16 +30,12 @@ def rm_rf(path, max_retries=5, trash=True):
         path = abspath(path)
         log.trace("rm_rf %s", path)
         if isdir(path) and not islink(path):
-            try:
-                # On Windows, always move to trash first.
-                if trash and on_win:
-                    move_result = move_path_to_trash(path, preclean=False)
-                    if move_result:
-                        return True
-                backoff_rmdir(path)
-            finally:
-                from ...core.linked_data import delete_prefix_from_linked_data
-                delete_prefix_from_linked_data(path)
+            # On Windows, always move to trash first.
+            if trash and on_win:
+                move_result = move_path_to_trash(path, preclean=False)
+                if move_result:
+                    return True
+            backoff_rmdir(path)
         elif lexists(path):
             try:
                 backoff_unlink(path)
@@ -51,11 +47,12 @@ def rm_rf(path, max_retries=5, trash=True):
                     if move_result:
                         return True
                 log.info("Failed to remove %s.", path)
-
         else:
             log.trace("rm_rf failed. Not a link, file, or directory: %s", path)
         return True
     finally:
+        from ...core.linked_data import delete_prefix_from_linked_data
+        delete_prefix_from_linked_data(path)
         if lexists(path):
             log.info("rm_rf failed for %s", path)
             return False


Test patch:
diff --git a/tests/test_create.py b/tests/test_create.py
--- a/tests/test_create.py
+++ b/tests/test_create.py
@@ -431,6 +431,12 @@ def test_list_with_pip_egg(self):
             assert any(line.endswith("<pip>") for line in stdout_lines
                        if line.lower().startswith("flask"))
 
+            # regression test for #5847
+            #   when using rm_rf on a directory
+            assert prefix in linked_data_
+            rm_rf(join(prefix, get_python_site_packages_short_path("3.5")))
+            assert prefix not in linked_data_
+
     def test_list_with_pip_wheel(self):
         with make_temp_env("python=3.5 pip") as prefix:
             check_call(PYTHON_BINARY + " -m pip install flask==0.10.1",
@@ -444,6 +450,12 @@ def test_list_with_pip_wheel(self):
             run_command(Commands.INSTALL, prefix, "python=3.4")
             assert_package_is_installed(prefix, 'python-3.4.')
 
+            # regression test for #5847
+            #   when using rm_rf on a file
+            assert prefix in linked_data_
+            rm_rf(join(prefix, get_python_site_packages_short_path("3.4")), "os.py")
+            assert prefix not in linked_data_
+
     def test_install_tarball_from_local_channel(self):
         # Regression test for #2812
         # install from local channel