diff --git a/esmvalcore/_main.py b/esmvalcore/_main.py index cff2c3c993..4a832a740f 100644 --- a/esmvalcore/_main.py +++ b/esmvalcore/_main.py @@ -178,6 +178,7 @@ def __init__(self) -> None: def show( self, filter: tuple[str] | None = ("extra_facets",), # noqa: A002 + project: str | None = None, ) -> None: """Show the current configuration. @@ -185,7 +186,12 @@ def show( ---------- filter: Filter this list of keys. By default, the `extra_facets` - key is filtered out, as it can be very large. + key is filtered out, as it can be very large. For example, to show + the full configuration, use `--filter=` and to filter out both + the `data` and `extra_facets` keys use `--filter=data,extra_facets`. + project: + Only show configuration for this project. For example, to only show + the configuration for the CMIP7 project, use `--project=CMIP7`. """ import yaml @@ -195,15 +201,19 @@ def show( from esmvalcore.config import CFG cfg = dict(CFG) + msg = "# Current configuration" + if project and "projects" in cfg and project in cfg["projects"]: + cfg = {"projects": {project: cfg["projects"][project]}} + msg += f" for project '{project}'" if filter: + if isinstance(filter, str): + filter = (filter,) # noqa: A001 for key in filter: cfg = nested_delete(cfg, key) - exclude_msg = ( - ", excluding the keys " + ", ".join(f"'{f}'" for f in filter) - if filter - else "" - ) - self.console.print(f"# Current configuration{exclude_msg}:") + msg += ", excluding the keys " + ", ".join( + f"'{key}'" for key in filter + ) + self.console.print(f"{msg}:") self.console.print( Syntax( yaml.safe_dump(cfg), diff --git a/tests/integration/test_main.py b/tests/integration/test_main.py index 90a86da39a..2eb7cc7c77 100644 --- a/tests/integration/test_main.py +++ b/tests/integration/test_main.py @@ -205,7 +205,7 @@ def test_config_show( cfg_default: Config, ) -> None: """Test esmvaltool config show command.""" - with arguments("esmvaltool", "config", "show", "--filter=None"): + with arguments("esmvaltool", "config", "show", "--filter="): run() stdout = capsys.readouterr().out expected_header = "# Current configuration:\n" @@ -216,6 +216,41 @@ def test_config_show( assert cfg == reference +def test_config_show_single_project( + capsys: pytest.CaptureFixture, + cfg_default: Config, +) -> None: + """Test esmvaltool config show command for a single project.""" + with arguments("esmvaltool", "config", "show", "--project=CMIP7"): + run() + stdout = capsys.readouterr().out + expected_header = "# Current configuration for project 'CMIP7', excluding the keys 'extra_facets':\n" + assert expected_header in stdout + cfg_txt = stdout.split(expected_header)[1] + cfg = yaml.safe_load(cfg_txt) + assert "projects" in cfg + assert "CMIP7" in cfg["projects"] + assert "CMIP6" not in cfg["projects"] + + +def test_config_show_filter( + capsys: pytest.CaptureFixture, + cfg_default: Config, +) -> None: + """Test esmvaltool config show command for a single project.""" + with arguments("esmvaltool", "config", "show", "--filter=projects"): + run() + stdout = capsys.readouterr().out + expected_header = ( + "# Current configuration, excluding the keys 'projects':\n" + ) + assert expected_header in stdout + cfg_txt = stdout.split(expected_header)[1] + cfg = yaml.safe_load(cfg_txt) + assert cfg + assert "projects" not in cfg + + def test_config_show_brief_by_default(capsys: pytest.CaptureFixture) -> None: """Test that the `esmvaltool config show` command produces readable results.""" with arguments("esmvaltool", "config", "show"):