Repository: IAMconsortium/nomenclature

Issue:
Double stacking external repos does not work as expected
I just ran into this potential issue when trying to create a DataStructure definition based of off legacy definitions.
What I did is:
1. Create a new (local) repository with an empty definitions folder and a `nomenclature.yaml` file with the following entry:
```yaml
repositories:
  legacy-definitions:
    url: https://github.com/IAMconsortium/legacy-definitions.git/
definitions:
  variable:
    repository: legacy-definitions
```
2. Since common definitions, as of right now (https://github.com/IAMconsortium/legacy-definitions/blob/main/nomenclature.yaml) contains a `nomenclature.yaml` file itself I thought that the above configuration should import common-definitions as well. However common-definitions was not fetched and instead just the yaml files from legacy-definitions were read.

I would see two ways to fix this, one easy one slightly more involved (because recursion).

### Option 1 (the quick fix)

Disallow any external repo to have a `nomenclature.yaml` on its own. This is easy enough to check and we would simply throw an error if this occurs.

### Option 2 (recursion)

We allow, potentially arbitrary many times, stacking of external repos. 


My preferred option would be 1. No only because it is faster to implement but also because the use case 2 currently does not exist and I'm not sure we even want to allow it for the sake of keeping things flat and easy ( "*Flat is better than nested.*" from https://peps.python.org/pep-0020/). 

What are your thoughts on the matter @danielhuppmann?

Discussion:

Patch:
diff --git a/nomenclature/config.py b/nomenclature/config.py
index 0bfb112..c037274 100644
--- a/nomenclature/config.py
+++ b/nomenclature/config.py
@@ -82,6 +82,20 @@ class Repository(BaseModel):
         repo.git.clean("-xdf")
         if self.revision == "main":
             repo.remotes.origin.pull()
+        self.check_external_repo_double_stacking()
+
+    def check_external_repo_double_stacking(self):
+        nomenclature_config = self.local_path / "nomenclature.yaml"
+        if nomenclature_config.is_file():
+            with open(nomenclature_config, "r") as f:
+                config = yaml.safe_load(f)
+            if config.get("repositories"):
+                raise ValueError(
+                    (
+                        "External repos cannot again refer to external repos, "
+                        f"found in nomenclature.yaml in '{self.url}'"
+                    )
+                )
 
 
 class DataStructureConfig(BaseModel):


Test patch:
diff --git a/tests/data/double_stacked_external_repo/nomenclature.yaml b/tests/data/double_stacked_external_repo/nomenclature.yaml
new file mode 100644
index 0000000..437e7ed
--- /dev/null
+++ b/tests/data/double_stacked_external_repo/nomenclature.yaml
@@ -0,0 +1,6 @@
+repositories:
+  common-definitions:
+    url: https://github.com/IAMconsortium/common-definitions.git/
+definitions:
+  region:
+    repository: common-definitions
diff --git a/tests/test_config.py b/tests/test_config.py
index b03fd3e..9674f08 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -55,3 +55,15 @@ def test_multiple_mapping_repos():
         assert nomenclature_config.repositories.keys() == exp_repos
     finally:
         clean_up_external_repos(nomenclature_config.repositories)
+
+
+def test_double_stacked_external_repo_raises(monkeypatch):
+    repo = Repository(url="lorem ipsum")
+    monkeypatch.setitem(
+        repo.__dict__,
+        "local_path",
+        TEST_DATA_DIR / "double_stacked_external_repo",
+    )
+    match = "External repos cannot again refer to external repos"
+    with raises(ValueError, match=match):
+        repo.check_external_repo_double_stacking()