Repository: conan-io/conan

Issue:
[bug] conan export-pkg doesn't fail when exporting a package folder that does not exist
### Environment Details
  * Operating System+version: Debian unstable
  * Compiler+version: N/A
  * Conan version: 1.22.0
  * Python version: 3.7.5

### Steps to reproduce

- Assuming you have a conan repository with a conanfile.py in ~/myproject
- Run `conan export-pkg --force --package-folder /this/folder/does/not/exist ~/myproject`
- conan will just warn `WARN: No files in this package!` and exit successfully

It is ok to export an empty package, but I would have expected conan to show an error since the folder doesn't exist at all.

### Logs

```
$ conan export-pkg --package-folder /this/folder/does/not/exist ~/work/tanker/conan/cppcodec 
Exporting package recipe
cppcodec/edf46ab: A new conanfile.py version was exported
cppcodec/edf46ab: Folder: /home/philippe/.conan/data/cppcodec/edf46ab/_/_/export
cppcodec/edf46ab: Using the exported files summary hash as the recipe revision: b068bd011732194d966f09f269d94124 
cppcodec/edf46ab: Exported revision: b068bd011732194d966f09f269d94124
cppcodec/edf46ab: Forced build from source
Packaging to 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
cppcodec/edf46ab: Exporting to cache existing package from user folder
cppcodec/edf46ab: Package folder /home/philippe/.conan/data/cppcodec/edf46ab/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
cppcodec/edf46ab: WARN: No files in this package!
cppcodec/edf46ab: Package '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' created
cppcodec/edf46ab: Created package revision 62acfcc1c48ee02e1a4300df700347a4
```



Discussion:
Hi @blastrock,
I have reproduced the issue, and I also think that an error should rise if the folder does not exist.
Thanks a lot for reporting!

Resolving patch:
diff --git a/conans/client/conan_api.py b/conans/client/conan_api.py
--- a/conans/client/conan_api.py
+++ b/conans/client/conan_api.py
@@ -402,6 +402,12 @@ def export_pkg(self, conanfile_path, name, channel, source_folder=None, build_fo
             source_folder = _make_abs_path(source_folder, cwd,
                                            default=os.path.dirname(conanfile_path))
 
+            for folder, path in {"source": source_folder, "build": build_folder,
+                                 "package": package_folder}.items():
+                if path and not os.path.exists(path):
+                    raise ConanException("The {} folder '{}' does not exist."
+                                         .format(folder, path))
+
             lockfile = _make_abs_path(lockfile, cwd) if lockfile else None
             # Checks that no both settings and info files are specified
             graph_info = get_graph_info(profile_names, settings, options, env, cwd, install_folder,


Test patch:
diff --git a/conans/test/functional/command/export_pkg_test.py b/conans/test/functional/command/export_pkg_test.py
--- a/conans/test/functional/command/export_pkg_test.py
+++ b/conans/test/functional/command/export_pkg_test.py
@@ -480,7 +480,16 @@ class TestConan(ConanFile):
         self.assertIn("set(CONAN_LIBS_HELLO1 mycoollib)", cmakeinfo)
         self.assertIn("set(CONAN_LIBS mycoollib ${CONAN_LIBS})", cmakeinfo)
 
-    def export_pkg_json_test(self):
+    def test_export_pkg_json(self):
+
+        def _check_json_output_no_folder():
+            json_path = os.path.join(self.client.current_folder, "output.json")
+            self.assertTrue(os.path.exists(json_path))
+            json_content = load(json_path)
+            output = json.loads(json_content)
+            self.assertEqual(True, output["error"])
+            self.assertEqual([], output["installed"])
+            self.assertEqual(2, len(output))
 
         def _check_json_output(with_error=False):
             json_path = os.path.join(self.client.current_folder, "output.json")
@@ -513,7 +522,7 @@ class MyConan(ConanFile):
         self.client.run("export-pkg . danimtb/testing -bf build -sf sources "
                         "--json output.json", assert_error=True)
 
-        _check_json_output(with_error=True)
+        _check_json_output_no_folder()
 
         # Deafult folders
         self.client.run("export-pkg . danimtb/testing --json output.json --force")
@@ -530,7 +539,7 @@ class MyConan(ConanFile):
         self.client.run("export-pkg . danimtb/testing -pf package --json output.json --force")
         _check_json_output()
 
-    def json_with_dependencies_test(self):
+    def test_json_with_dependencies(self):
 
         def _check_json_output(with_error=False):
             json_path = os.path.join(self.client.current_folder, "output.json")
@@ -618,3 +627,15 @@ def build(self):
         self.assertFalse(is_dirty(package_folder))
         client.run("install pkg/0.1@")
         self.assertIn("pkg/0.1: Already installed!", client.out)
+
+    def test_invalid_folder(self):
+        """ source, build and package path must exists, otherwise, raise ConanException
+        """
+        for folder in ["source", "build", "package"]:
+            client = TestClient()
+            client.save({CONANFILE: GenConanfile().with_name("foo").with_version("0.1.0")})
+
+            client.run("export-pkg . foo/0.1.0@user/testing -{}f={}".format(folder[0], folder),
+                       assert_error=True)
+            self.assertIn("ERROR: The {} folder '{}' does not exist."
+                          .format(folder, os.path.join(client.current_folder, folder)), client.out)