Repository: conan-io/conan

Issue:
Possible "conan config get storage.path" regression
On a clean install of conan, starting from version 1.15.0:

```
$ conan config get storage.path
./data
```

On older versions: 
```
$ conan config get storage.path
~/.conan/data
```

I suspect this affects new installs and not upgrades.  To reproduce:
```
rm -rf ~/.conan
pip install -I conan==1.15.0
conan config get storage.path
rm -rf ~/.conan
pip install -I conan==1.14.5
```

Saludos!







Discussion:
Yes, the default path in the ``[storage]`` section has changed its default representation, but it still resolves to the same folder, right? Or is that failing in some case? The new ``./data`` representation is relative to the ``conan.conf`` location, which is more intutive for most cases, and removes the annoying ``.conan`` intermediate folder. But using the old one should totally work, please tell if it doesn't.

How would one get the absolute path then?

I currently use the following commands, because its otherwise not possible to use conan with a properly isolated build environment (#4967).
I would need the ideally fully resolved path to the data directory.

```cmake
execute_process(COMMAND conan config get storage.path OUTPUT_VARIABLE CMAKE_CONAN_STORAGE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_STAGING_PREFIX "${CMAKE_CONAN_STORAGE_PATH}")

```
Hi @nolange 

I am not fully sure what is the purpose of setting this path for CMAKE_STAGING_PREFIX. I have tried reading the docs for that var, but not very informative. Also in internet, but still can't fully understand. What if you directly set?
```cmake
set(CMAKE_STAGING_PREFIX "~")
```
Assuming that cmake knows how to expand ``~`` as the userhome, otherwise, it will not work anyway. Does cmake expand correctly ``~``?

What would be the difference of setting up that or:
```cmake
set(CMAKE_STAGING_PREFIX "~/.conan")
# or
set(CMAKE_STAGING_PREFIX "~/.conan/data")
```

Also, what happens to packages which final path is not really there, but mapped elsewhere, like when using ``short_paths``?

Needing to setup something in the build system that points to the storage path sounds like it could be problematic. I understand the need to restrict cmake to NOT look in other paths than those given by the conan generators, but can't fully understand this CMAKE_STAGING_PREFIX variable.

It might be possible to return the fully evaluated path for ``storage.path`` field, but sounds a bit hacky, I am investigating other possibilities.

> Yes, the default path in the `[storage]` section has changed its default representation, but it still resolves to the same folder, right? Or is that failing in some case? The new `./data` representation is relative to the `conan.conf` location, which is more intutive for most cases, and removes the annoying `.conan` intermediate folder. But using the old one should totally work, please tell if it doesn't.

Yup, as far as `conan.conf` is concerned, I think the new layout makes sense as it is clearer now where it is relative to.  

My specific issue has more to do with the output of  `conan config get storage.path` itself: prior to this version, I feel like it could be used to retrieve and compute the path programmatically, e.g. `~/.conan/data` can be expanded to the full path depending on whether `CONAN_USER_HOME` is set (I could be mistaken, I dont use `CONAN_USER_HOME` very often).

Whereas, an output like  `./data` seems to be lacking some information. From an outside perspective, would it be safe to assume that the path is relative to `<HOME>/.conan/`  (depending on whether `CONAN_USER_HOME` is overriding the user home?) That would work for my use case.

On the other hand, it would seem that the output of `conan config get storage.path` would need to be handled differently depending on the conan version.

This is getting a bit off-topic, the linked bug has more information, as well as the documentation for `find_package`.

I have a cross-toolchain, which also sets those variables (exemplary values):

```cmake
set(CMAKE_SYSROOT /opt/customroot)
# thats ensuring you dont end up with a system-installed package
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
```

and a path set by the generated `conan_paths.cmake`

```cmake
set(CMAKE_PREFIX_PATH "/home/me/.conan/data/gtest...." ${CMAKE_PREFIX_PATH} ${CMAKE_CURRENT_LIST_DIR})
```

What will happen, is that `find_package` will re-root the prefix under `/opt/customroot`, and thus search in `/opt/customroot/home/me/.conan/data/gtest....`. Naturally there is nothing to be found.

the directory in `CMAKE_STAGING_PREFIX` will be excluded from the re-rooting, hence the need to set it to the data directory.

> What if you directly set?
> 
> ```cmake
> set(CMAKE_STAGING_PREFIX "~")
> ```
> 
> Assuming that cmake knows how to expand `~` as the userhome, otherwise, it will not work anyway. Does cmake expand correctly `~`?

Then I am hard-coding assumptions about conan and its directories, likely need different values across Linux/Windows/Mac, and its not restrictive as it could be. CMake cant resolve `~` correctly under all circumstances, as this is affected by `CONAN_USER_HOME`.

> Also, what happens to packages which final path is not really there, but mapped elsewhere, like when using `short_paths`?

I would like conan to give me the relevant path (thats the whole idea behind not hard-coding)

> Needing to setup something in the build system that points to the storage path sounds like it could be problematic. I understand the need to restrict cmake to NOT look in other paths than those given by the conan generators, but can't fully understand this CMAKE_STAGING_PREFIX variable.

Yeah, thats why I opened issue 4967 to figure out a good solution, until then this is the best I could come up with (now it's broken with a new default config)

> It might be possible to return the fully evaluated path for `storage.path` field, but sounds a bit hacky, I am investigating other possibilities.

I would prefer conan to set a variable like `CONAN_STORAGE_PATH` in the file `conan_paths.cmake`



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
@@ -567,8 +567,12 @@ def install(self, path="", name=None, version=None, user=None, channel=None,
     @api_method
     def config_get(self, item):
         config_parser = ConanClientConfigParser(self._cache.conan_conf_path)
-        self._user_io.out.info(config_parser.get_item(item))
-        return config_parser.get_item(item)
+        if item == "storage.path":
+            result = config_parser.storage_path
+        else:
+            result = config_parser.get_item(item)
+        self._user_io.out.info(result)
+        return result
 
     @api_method
     def config_set(self, item, value):
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -363,10 +363,6 @@ def cache_no_locks(self):
         except ConanException:
             return False
 
-    @property
-    def storage(self):
-        return dict(self.get_conf("storage"))
-
     @property
     def request_timeout(self):
         timeout = os.getenv("CONAN_REQUEST_TIMEOUT")
@@ -416,7 +412,7 @@ def storage_path(self):
                 current_dir = os.path.dirname(self.filename)
                 # if env var is declared, any specified path will be relative to CONAN_USER_HOME
                 # even with the ~/
-                result = self.storage["path"]
+                result = dict(self.get_conf("storage"))["path"]
                 if result.startswith("."):
                     result = os.path.abspath(os.path.join(current_dir, result))
                 elif result[:2] == "~/":


Test patch:
diff --git a/conans/test/functional/command/config_test.py b/conans/test/functional/command/config_test.py
--- a/conans/test/functional/command/config_test.py
+++ b/conans/test/functional/command/config_test.py
@@ -1,3 +1,4 @@
+import os
 import unittest
 
 from conans.test.utils.tools import TestClient
@@ -21,8 +22,9 @@ def storage_test(self):
         self.assertIn("path = ./data", self.client.user_io.out)
 
         self.client.run("config get storage.path")
-        self.assertIn("./data", self.client.user_io.out)
-        self.assertNotIn("path:", self.client.user_io.out)
+        full_path = os.path.join(self.client.base_folder, "data")
+        self.assertIn(full_path, self.client.out)
+        self.assertNotIn("path:", self.client.out)
 
     def errors_test(self):
         self.client.run("config get whatever", assert_error=True)