Repository: dbt-labs/dbt-core

Issue:
dbt sometimes writes a `.user.yml` and ignores configs
## Issue
If you pass dbt a relative path to `--profiles-dir` or the `DBT_PROFILES_DIR` environment variable and execute from a subdirectory, dbt will look for the user cookie and profiles.yml in different places (the latter correct, the former incorrect).

### Results
What happened? What did you expect to happen?
I got a `./profiles/.user.yml` and my settings were ignored. I expected my settings to be respected or to receive an error, and to not have a new file.

Suggested fixes:
My preference: don't allow users to run dbt from subdirectories.
Other option: defer loading of the user config until after we've found `dbt_project.yml`.

### System information
The output of `dbt --version`:
```
0.14.0
```

The operating system you're running on:
Any

The python version you're using (probably the output of `python --version`)
Any

### Steps to reproduce
In as much detail as possible, please provide steps to reproduce the issue. Sample data that triggers the issue, example models, etc are all very helpful here.

1) Make a dbt project in `${project_root}`
2) put your profiles.yml in  `${project_root}/profiles`
3) Make a subdirectory (`${project_root}/models`) and cd into it
4) Run dbt with the relative path to the profiles directory as an argument to `--profiles-dir`: `dbt run --profiles-dir profiles`
5) You will now have a `${project_root}/models/profiles/.user.yml` with cookie information. Also, any settings in your `profiles.yml` won't be respected.



Discussion:
Let's definitely preserve the behavior where you can execute dbt from subdirs of the project. Let's instead pursue this approach:
>  defer loading of the user config until after we've found dbt_project.yml



Resolving patch:
diff --git a/core/dbt/tracking.py b/core/dbt/tracking.py
--- a/core/dbt/tracking.py
+++ b/core/dbt/tracking.py
@@ -13,8 +13,6 @@
 import yaml
 import os
 
-import dbt.clients.system
-
 sp_logger.setLevel(100)
 
 COLLECTOR_URL = "fishtownanalytics.sinter-collect.com"
@@ -91,12 +89,22 @@ def initialize(self):
         tracker.set_subject(subject)
 
     def set_cookie(self):
-        user = {"id": str(uuid.uuid4())}
+        # If the user points dbt to a profile directory which exists AND
+        # contains a profiles.yml file, then we can set a cookie. If the
+        # specified folder does not exist, or if there is not a profiles.yml
+        # file in this folder, then an inconsistent cookie can be used. This
+        # will change in every dbt invocation until the user points to a
+        # profile dir file which contains a valid profiles.yml file.
+        #
+        # See: https://github.com/fishtown-analytics/dbt/issues/1645
 
-        dbt.clients.system.make_directory(self.cookie_dir)
+        user = {"id": str(uuid.uuid4())}
 
-        with open(self.cookie_path, "w") as fh:
-            yaml.dump(user, fh)
+        cookie_path = os.path.abspath(self.cookie_dir)
+        profiles_file = os.path.join(cookie_path, 'profiles.yml')
+        if os.path.exists(cookie_path) and os.path.exists(profiles_file):
+            with open(self.cookie_path, "w") as fh:
+                yaml.dump(user, fh)
 
         return user
 


Test patch: