Repository: conda/conda

Issue:
Installing rstudio 1.0.44 on root, errors
```
$ conda install rstudio=1.0.44 --json
ERROR conda.core.link:_execute_actions(335): An error occurred while installing package 'defaults::rstudio-1.0.44-0'.
FileExistsError(17, 'File exists')
Attempting to roll back.

Traceback (most recent call last):
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/core/link.py", line 324, in _execute_actions
    action.execute()
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/core/path_actions.py", line 225, in execute
    force=context.force)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/gateways/disk/create.py", line 214, in create_link
    mkdir_p(dst)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/gateways/disk/create.py", line 153, in mkdir_p
    makedirs(path)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/os.py", line 220, in makedirs
    mkdir(name, mode)
FileExistsError: [Errno 17] File exists: '/Users/gpena-castellanos/anaconda/bin/pandoc'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/core/link.py", line 279, in execute
    pkg_data, actions)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/core/link.py", line 342, in _execute_actions
    reverse_excs,
conda.CondaMultiError: [Errno 17] File exists: '/Users/gpena-castellanos/anaconda/bin/pandoc'


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/exceptions.py", line 573, in conda_exception_handler
    return_value = func(*args, **kwargs)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/cli/main.py", line 134, in _main
    exit_code = args.func(args, p)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/cli/main_install.py", line 80, in execute
    install(args, parser, 'install')
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/cli/install.py", line 359, in install
    execute_actions(actions, index, verbose=not context.quiet)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/plan.py", line 800, in execute_actions
    execute_instructions(plan, index, verbose)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/instructions.py", line 247, in execute_instructions
    cmd(state, arg)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/instructions.py", line 108, in UNLINKLINKTRANSACTION_CMD
    txn.execute()
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/core/link.py", line 295, in execute
    rollback_excs,
conda.CondaMultiError: [Errno 17] File exists: '/Users/gpena-castellanos/anaconda/bin/pandoc'


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/gpena-castellanos/anaconda/bin/conda", line 6, in <module>
    sys.exit(conda.cli.main())
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/cli/main.py", line 164, in main
    return conda_exception_handler(_main, *args)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/exceptions.py", line 586, in conda_exception_handler
    print_conda_exception(e)
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/exceptions.py", line 496, in print_conda_exception
    stdoutlogger.info(json.dumps(exception.dump_map(), indent=2, sort_keys=True,
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/__init__.py", line 74, in dump_map
    errors=tuple(error.dump_map() for error in self.errors),
  File "/Users/gpena-castellanos/anaconda/lib/python3.6/site-packages/conda/__init__.py", line 74, in <genexpr>
    errors=tuple(error.dump_map() for error in self.errors),
AttributeError: 'FileExistsError' object has no attribute 'dump_map'
0316-gpena-castellanos:~ gpena-castellanos$ 



Discussion:
@kalefranz any ideas about this?

The new rstudio splits pandoc into a separate package while the old one had it bundled.

I thought the clobber stuff was turned off now?
It is. This is different than clobber.

What appears to be happening is that conda for some reason thinks it needs to create a 'bin/pandoc' *directory* after something in the transaction has already created a 'bin/pandoc' file.

This is definitely odd.

> On Mar 22, 2017, at 2:12 PM, Ray Donnelly <notifications@github.com> wrote:
> 
> Assigned #4914 to @kalefranz.
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or mute the thread.
> 

That actually makes sense. The old rstudio had bin/pandoc/pandoc executable but the new pandoc package has a bin/pandoc executable instead.

This should be allowed to happen though when clobbering is allowed.
Yeah I think we can do that. 

> On Mar 22, 2017, at 7:11 PM, Ray Donnelly <notifications@github.com> wrote:
> 
> That actually makes sense. The old rstudio had bin/pandoc/pandoc.exe, but the new pandoc package has bin/pandoc.
> 
> This should be allowed to happen though when clobbering is allowed.
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or mute the thread.
> 


Resolving patch:
diff --git a/conda/core/path_actions.py b/conda/core/path_actions.py
--- a/conda/core/path_actions.py
+++ b/conda/core/path_actions.py
@@ -96,7 +96,10 @@ def __init__(self, transaction_context, target_prefix, target_short_path):
     @property
     def target_full_path(self):
         trgt, shrt_pth = self.target_prefix, self.target_short_path
-        return join(trgt, win_path_ok(shrt_pth)) if trgt and shrt_pth else None
+        if trgt is not None and shrt_pth is not None:
+            return join(trgt, win_path_ok(shrt_pth))
+        else:
+            return None
 
 
 # ######################################################
diff --git a/conda/gateways/disk/create.py b/conda/gateways/disk/create.py
--- a/conda/gateways/disk/create.py
+++ b/conda/gateways/disk/create.py
@@ -218,6 +218,11 @@ def create_link(src, dst, link_type=LinkType.hardlink, force=False):
     if link_type == LinkType.directory:
         # A directory is technically not a link.  So link_type is a misnomer.
         #   Naming is hard.
+        if lexists(dst) and not isdir(dst):
+            if not force:
+                maybe_raise(BasicClobberError(src, dst, context), context)
+            log.info("file exists, but clobbering for directory: %r" % dst)
+            rm_rf(dst)
         mkdir_p(dst)
         return
 


Test patch: