Repository: conan-io/conan

Issue:
Environment variable to set [general]default_profile 
To help us debug your issue please explain:

- [x] I've read the [CONTRIBUTING guide](https://raw.githubusercontent.com/conan-io/conan/develop/.github/CONTRIBUTING.md).
- [ ] I've specified the Conan version, operating system version and any tool that can be relevant.
- [x] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.

This idea was initially proposed at https://github.com/conan-io/conan/issues/1221#issuecomment-403961457

It would be nice if there was an environment variable (perhaps `CONAN_DEFAULT_PROFILE`?) which, if set, would override `[general]default_profile` from `conan.conf `. In an IDE workflow, a project file might be set up to obtain its own dependencies by calling `conan install` (e.g. https://github.com/conan-io/cmake-conan), but it feels wrong to hard-code a desired profile into the call to conan install. Most project systems like this support multiple configurations (e.g. Qt Creator has [kits](http://doc.qt.io/qtcreator/creator-configuring-projects.html), MSVC supports setting up multiple configurations. conan_cmake_settings(...) makes an effort to reverse-engineer the settings from the compiler detection variables, but it's not particularly complete, and in any case a sophisticated profile might have content (e.g. build_requires for toolchains) arguably could never get in this fashion. 

IDE features to define a build template like this usually have a mechanism to add environment variables to the build invocation, and a way to set the default profile through the environment seems consistent with the existing ability to override specific settings from it using [CONAN_ENV_XXXX_YYYY](https://docs.conan.io/en/latest/reference/env_vars.html#conan-env-xxxx-yyyy).





Discussion:
Should be an easy to implement feature, something like:

````python
"CONAN_BASH_PATH": self._env_c("general.bash_path", "CONAN_BASH_PATH", None),
``` 

in ``ConanClientConfigParser``
I think that it will be enough to modify the line where default profile is retrieved:

```python
class ConanClientConfigParser(ConfigParser, object):
    ...
    @property
    def default_profile(self):
        try:
            return self.get_item("general.default_profile")
        except ConanException:
            return DEFAULT_PROFILE_NAME
```

to something like

```python
class ConanClientConfigParser(ConfigParser, object):
    ...
    @property
    def default_profile(self):
        return self._env_c("general.default_profile", "CONAN_ENV_DEFAULT_PROFILE", DEFAULT_PROFILE_NAME)
```

but I'm afraid it could interfere with existing behavior (I've created a [branch](https://github.com/jgsogo/conan/tree/issue/3193) and [marked a couple of places](https://github.com/jgsogo/conan/commit/c58d5ab843c8221318c21c3542cb35ae470643aa) where there can be a problem).

We've been discussing a little me and @jgsogo sogo and probably the most reasonable is:

- In the `default_profile()`: If the env var exists and points to a non-existent path, raise.
- So the `client_cache` won't ever detect a profile if the var contains a valid path, that could be dangerous (unexpected) in a CI environment.
- This approach seems to be the more valid, but it is not useful if the user intention is to just change the location of the default profile (and the user doesn't create it). 
That seems like a good way to resolve the tension. I'm definitely only wanting a way to change which (exisiting) profile is used by default, not a way to change where the profile created by autodetection is stored. In fact I didn't intend to set it to an absolute path, just the name (which would then be searched/resolved as usual).

In fact, in my situation (many cross-toolchains, and profiles that set up PATH/PKG_CONFIG_LIBDIR/etc accordingly) I'd really rather that conan *never* autodetect (except when I explicitly asked it to with `conan profile new --detect <name>`. I've considered just setting the actual general.default_profile to /dev/null or some such to poison it. so calls where you don't say which toolchain to use always fail.
> I've considered just setting the actual general.default_profile to /dev/null or some such to poison it. so calls where you don't say which toolchain to use always fail.

Yes, this might be a good practice to make sure you are always calling your own profiles. Not something we can do without breaking the world. You know that ``conan.conf`` can get defined, merged with ``conan config install``?


Oh, I agree it's a special case, and the current behavior is the right default.

And yes, we already use conan config install to share some parts of our profiles (though they rely in include files to tell, though it's a bit of a hassle that this doesn't support authentication (since that precludes just pushing the config zip into artifactory, where everything else gets distributed).
> though it's a bit of a hassle that this doesn't support authentication (since that precludes just pushing the config zip into artifactory

Recently, the ``--args`` argument was added to provide extra information to ``conan config install`` while using ``git cloned`` config repos. Something similar might be possible to provide authentication, so this sounds would be a valid feature request, please consider submitting it, specifying what would be the preferred UI (password in plain text as an argument? interactive? (bad for CI)). Thanks!
Why did this end up being required to be an absolute path? Espescially if it's required to exist, why not just resolve relative paths against $CONAN_USER_HOME/.conan/profiles, like [general]default_profile, `conan install --profile <foo>` and `conan profile show` currently do?
That is a good point. I think it should be consistent with the way it is specified in ``conan.conf`` and that allows defining relative paths too, right? Please @jgsogo feedback
Yes, conan.conf allows default_profile = name or default_profile = subfolder/name
Or even weird things like default_profile = ../some_folder/name. 
All resolve relative to $CONAN_USER_HOME/.conan/profiles

`--profile x` will also look relative to the cwd if it's not in $CONAN_USER_HOME/.conan/profiles.

It seems like the environment variable should be like conan.conf here; relative to $CONAN_USER_HOME/.conan/profiles, but never checking the cwd.

Resolving patch:
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
@@ -290,8 +290,10 @@ def default_profile(self):
         ret = os.environ.get("CONAN_DEFAULT_PROFILE_PATH", None)
         if ret:
             if not os.path.isabs(ret):
-                raise ConanException("Environment variable 'CONAN_DEFAULT_PROFILE_PATH' must point "
-                                     "to an absolute path.")
+                from conans.client.client_cache import PROFILES_FOLDER
+                profiles_folder = os.path.join(os.path.dirname(self.filename), PROFILES_FOLDER)
+                ret = os.path.abspath(os.path.join(profiles_folder, ret))
+
             if not os.path.exists(ret):
                 raise ConanException("Environment variable 'CONAN_DEFAULT_PROFILE_PATH' must point to "
                                      "an existing profile file.")


Test patch:
diff --git a/conans/test/functional/default_profile_test.py b/conans/test/functional/default_profile_test.py
--- a/conans/test/functional/default_profile_test.py
+++ b/conans/test/functional/default_profile_test.py
@@ -7,6 +7,7 @@
 from conans.test.utils.tools import TestClient
 from conans.util.files import save
 from conans import tools
+from conans.client.client_cache import PROFILES_FOLDER
 
 
 class DefaultProfileTest(unittest.TestCase):
@@ -161,10 +162,15 @@ def build(self):
             self.assertIn(">>> " + env_variable, client.out)
 
         # Use relative path defined in environment variable
-        with tools.environment_append({'CONAN_DEFAULT_PROFILE_PATH': '../whatever'}):
-            client.run("create . name/version@user/channel", ignore_error=True)
-            self.assertIn("Environment variable 'CONAN_DEFAULT_PROFILE_PATH' must point to "
-                          "an absolute path", client.out)
+        env_variable = "env_variable=relative_profile"
+        rel_path = os.path.join('..', 'env_rel_profile')
+        self.assertFalse(os.path.isabs(rel_path))
+        default_profile_path = os.path.join(client.client_cache.conan_folder,
+                                            PROFILES_FOLDER, rel_path)
+        save(default_profile_path, "[env]\n" + env_variable)
+        with tools.environment_append({'CONAN_DEFAULT_PROFILE_PATH': rel_path}):
+            client.run("create . name/version@user/channel")
+            self.assertIn(">>> " + env_variable, client.out)
 
         # Use non existing path
         profile_path = os.path.join(tmp, "this", "is", "a", "path")