Repository: dbt-labs/dbt-core

Issue:
[Bug] Duplicated source when seed and model paths overlap
### Is this a new bug in dbt-core?

- [X] I believe this is a new bug in dbt-core
- [X] I have searched the existing issues, and I could not find an existing issue for this bug

### Current Behavior

If I have the following structure:
```
proj_name/
- data_provider
  - seeds
  - models
    - sources.yml
- < consider the previous structure repeated for N providers >
```

And the following configuration:
```yml
model-paths: 
  - proj_name/data_provider/
seed-paths: 
  - proj_name/data_provider
```

I will get an error like:
```
10:32:20  Running with dbt=1.3.0
10:32:21  Encountered an error:
Compilation Error
  dbt found two sources with the name "some_source".
  
  Since these resources have the same name, dbt will be unable to find the correct resource
  when looking for source("data_provider", "some_source").
  
  To fix this, change the name of one of these resources:
  - source.proj_name.data_provider.some_source (proj_name/data_provider/models/sources.yml)
  - source.proj_name.data_provider.some_source (proj_name/data_provider/models/sources.yml)
```

I am aware that I can do:
```yml
model-paths: 
  - proj_name/data_provider/models
seed-paths: 
  - proj_name/data_provider/seeds
```
But this is not practical for several data providers, furthermore, as the data in question is usually not mixed with other providers, we would like to keep the structure as close as it is.

### Expected Behavior

No name clash.

My intuition says that sources shouldn't be analysed when searching for seeds, but there may be a reason behind this.

### Steps To Reproduce

Described in current behavior.

### Relevant log output

```shell
Described in current behavior.
```


### Environment

```markdown
- OS: MacOS
- Python: 3.8.10
- dbt: 1.3.0
```


### Which database adapter are you using with dbt?

snowflake

### Additional Context

_No response_


Discussion:
Hey @jmg-duarte - I agree this is a bug! This sounds the same as one previously reported: https://github.com/dbt-labs/dbt-core/issues/5120. We included a fix for that (https://github.com/dbt-labs/dbt-core/pull/5176) in dbt-core v1.2.0 and v1.1.1.

As such, I wasn't able to reproduce this while running locally, using the latest version of `dbt-core`.

Is it possible that this regressed in v1.3? I would expect that this functional test should have started failing: https://github.com/dbt-labs/dbt-core/blob/main/tests/functional/configs/test_dupe_paths.py
Hey @jtcohen6, thanks for the quick response! I think this still happens if the paths resolve to the same one but the name is different. 

Such as:
```
path/to/folder
path/to/folder/
```

I haven't had the chance to look too deep into this, but I've been seeing this since 1.2.2. 
I'll try to create a repo with a minimal reproducible example so we can address this with confidence.
I have a minimal reproducible example, steps to reproduce:
1. `dbt init`
2. Modify the `dbt_project.yml` making the seeds and models point to the same folder
  - The folder must differ by having a trailing `/`, example:
  ```yml
  seeds: ["path/to/folder"]
  models: ["path/to/folder/"]
  ```
3. `dbt compile`

From an outside perspective, it seems as though the paths are not resolved before being used, so my suggestion would be to resolve them.

I've also updated the original issue to reflect this finding.
Ah, good to know that `/` makes the difference! That would explain why the fix from https://github.com/dbt-labs/dbt-core/issues/5120 isn't working here
Turning this
https://github.com/dbt-labs/dbt-core/blob/8145eed603266951ce35858f7eef3836012090bd/core/dbt/config/project.py#L128-L139

Into
```py
def _all_source_paths(
    model_paths: List[str],
    seed_paths: List[str],
    snapshot_paths: List[str],
    analysis_paths: List[str],
    macro_paths: List[str],
) -> List[str]:
    # We need to turn a list of lists into just a list, then convert to a set to
    # get only unique elements, then back to a list
    paths = chain(model_paths, seed_paths, snapshot_paths, analysis_paths, macro_paths)
    paths = map(lambda s: str(pathlib.Path(s).resolve()), paths)
    return list(set(paths))
```

Should work, I can try and submit a PR if this looks ok to you
@jmg-duarte That makes sense to me! If you're up to contribute the fix, plus another test like [this one](https://github.com/dbt-labs/dbt-core/blob/main/tests/functional/configs/test_dupe_paths.py), that would be very much appreciated :)

Resolving patch:
diff --git a/core/dbt/config/project.py b/core/dbt/config/project.py
--- a/core/dbt/config/project.py
+++ b/core/dbt/config/project.py
@@ -137,11 +137,10 @@ def _all_source_paths(
     analysis_paths: List[str],
     macro_paths: List[str],
 ) -> List[str]:
-    # We need to turn a list of lists into just a list, then convert to a set to
-    # get only unique elements, then back to a list
-    return list(
-        set(list(chain(model_paths, seed_paths, snapshot_paths, analysis_paths, macro_paths)))
-    )
+    paths = chain(model_paths, seed_paths, snapshot_paths, analysis_paths, macro_paths)
+    # Strip trailing slashes since the path is the same even though the name is not
+    stripped_paths = map(lambda s: s.rstrip("/"), paths)
+    return list(set(stripped_paths))
 
 
 T = TypeVar("T")


Test patch:
diff --git a/tests/functional/configs/test_dupe_paths.py b/tests/functional/configs/test_dupe_paths.py
--- a/tests/functional/configs/test_dupe_paths.py
+++ b/tests/functional/configs/test_dupe_paths.py
@@ -49,3 +49,27 @@ def test_config_with_dupe_paths(self, project, dbt_project_yml):
         assert len(results) == 1
         results = run_dbt(["run"])
         assert len(results) == 1
+
+
+class TestDupeStrippedProjectPaths:
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {
+            "my_model.sql": my_model_sql,
+            "seed.csv": seed_csv,
+            "somedoc.md": somedoc_md,
+            "schema.yml": schema_yml,
+        }
+
+    @pytest.fixture(scope="class")
+    def project_config_update(self):
+        return {
+            "model-paths": ["models/"],
+            "seed-paths": ["models"],
+        }
+
+    def test_config_with_dupe_paths(self, project, dbt_project_yml):
+        results = run_dbt(["seed"])
+        assert len(results) == 1
+        results = run_dbt(["run"])
+        assert len(results) == 1