Repository: conan-io/conan

Issue:
[bug][2.0] full_deploy of Skip'd requirements
- [X] I've read the [CONTRIBUTING guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).

When deploying an application (gnuradio) to a target folder, transitive dependencies not required at runtime break my installs due to the dep.package_folder=None. It looks like any requied, non-build package marked "Skip" in the dependency graph has package_folder=None in the deployer.

Ex: `zlib/1.2.12#... - Skip`

_Is this desired functionality (i.e. My recipes are misconfigured), or a potential bug in full_deploy?_

I'm in the process of tracing the logic for Skipping a requirement, but figured I'd ask here in the event someone is familiar with my problem.

The DEBUG prints in the command output are print(dep.package_folder, new_folder). I can include the conanfile if desired, but it's a lengthy dependency tree so I held off for now.

### **Command:**
`conan install --requires=gnuradio/3.10.4.0@  --deploy=full_deploy -of=/apps/gnuradio`

### **Environment:**

```
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=9
os=Linux
os.distro=Ubuntu20.04
```

### **Command Output:**
```
...
virtual: Conan built-in full deployer to /apps/gnuradio
DEBUG: /root/.conan2/p/73babd2cee08d654/p /apps/gnuradio/host/gnuradio/3.10.4.0/Release/x86_64
DEBUG: /root/.conan2/p/06e437af43aba52d/p /apps/gnuradio/host/volk/2.5.0/Release/x86_64
DEBUG: /root/.conan2/p/e9046e7f1ab78fd7/p /apps/gnuradio/host/boost/1.76.0/Release/x86_64
DEBUG: None /apps/gnuradio/host/zlib/1.2.12/Release/x86_64
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/conan/cli/cli.py", line 170, in run
    command.run(self._conan_api, self._commands[command_argument].parser, args[0][1:])
  File "/usr/local/lib/python3.8/dist-packages/conan/cli/command.py", line 176, in run
    info = self._method(conan_api, parser, *args)
  File "/usr/local/lib/python3.8/dist-packages/conan/cli/commands/install.py", line 179, in install
    conan_api.install.install_consumer(deps_graph=deps_graph,
  File "/usr/local/lib/python3.8/dist-packages/conan/api/subapi/install.py", line 52, in install_consumer
    _do_deploys(self.conan_api, deps_graph, deploy, base_folder)
  File "/usr/local/lib/python3.8/dist-packages/conan/api/subapi/install.py", line 97, in _do_deploys
    deployer(conanfile=conanfile, output_folder=deploy_folder)
  File "/usr/local/lib/python3.8/dist-packages/conan/api/subapi/install.py", line 121, in full_deploy
    shutil.copytree(dep.package_folder, new_folder)
  File "/usr/lib/python3.8/shutil.py", line 557, in copytree
    return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
  File "/usr/lib/python3.8/shutil.py", line 465, in _copytree
    srcname = os.path.join(src, srcentry.name)
  File "/usr/lib/python3.8/posixpath.py", line 76, in join
    a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not NoneType
```

### **full_deploy (conan/api/subapi/install.py:100) source:**
```
def full_deploy(conanfile, output_folder):
    """
    Deploys to output_folder + host/dep/0.1/Release/x86_64 subfolder
    """
    # TODO: This deployer needs to be put somewhere else
    # TODO: Document that this will NOT work with editables
    import os
    import shutil

    conanfile.output.info(f"Conan built-in full deployer to {output_folder}")
    for dep in conanfile.dependencies.values():
        folder_name = os.path.join(dep.context, dep.ref.name, str(dep.ref.version))
        build_type = dep.info.settings.get_safe("build_type")
        arch = dep.info.settings.get_safe("arch")
        if build_type:
            folder_name = os.path.join(folder_name, build_type)
        if arch:
            folder_name = os.path.join(folder_name, arch)
        new_folder = os.path.join(output_folder, folder_name)
        rmdir(new_folder)
        print(dep.package_folder, new_folder)
        shutil.copytree(dep.package_folder, new_folder)
        dep.set_deploy_folder(new_folder)
```

Changing the full_deploy method to include the below allows the deploy and run successfully.
```
if dep.package_folder is None:
        continue
```



Discussion:
From inspection, here's my zlib requirement for example:
`zlib/1.2.12, Traits: build=False, headers=False, libs=False, run=False, visible=True`

which matches the funcitonality in requires.py
```
    @property
    def skip(self):
        return not (self.headers or self.libs or self.run or self.build)
```

I'm looking at correcting my recipes to remove them from the dependencies list where possible. Should skipped dependencies make a deploy call fail?
Hi @beenjohn 

No, certainly the command should not fail. I think your proposed fix makes sense, skipping packages which package_folder is not defined, do you want to submit the fix in a PR yourself?
@memsharded Glad to help. I'll give that a go now.

Resolving patch:
diff --git a/conan/api/subapi/install.py b/conan/api/subapi/install.py
--- a/conan/api/subapi/install.py
+++ b/conan/api/subapi/install.py
@@ -108,6 +108,8 @@ def full_deploy(conanfile, output_folder):
 
     conanfile.output.info(f"Conan built-in full deployer to {output_folder}")
     for dep in conanfile.dependencies.values():
+        if dep.package_folder is None:
+            continue
         folder_name = os.path.join(dep.context, dep.ref.name, str(dep.ref.version))
         build_type = dep.info.settings.get_safe("build_type")
         arch = dep.info.settings.get_safe("arch")


Test patch: