diff --git a/nomenclature/cli.py b/nomenclature/cli.py index 33cdafc1..18ef895d 100644 --- a/nomenclature/cli.py +++ b/nomenclature/cli.py @@ -277,3 +277,29 @@ def cli_run_workflow( df = getattr(workflow, workflow_function)(IamDataFrame(input_file)) if output_file is not None: df.to_excel(output_file) + + +@cli.command("validate-scenarios") +@click.argument("input_file", type=click.Path(exists=True, path_type=Path)) +@click.option( + "--definitions", + help="Optional name for definitions folder", + type=click.Path(exists=True, path_type=Path), + default="definitions", +) +def cli_validate_scenarios(input_file: Path, definitions: Path): + """Validate a scenario file against the codelists of a project + + Parameters + ---------- + input_file : Path + Input data file, must be IAMC format, .xlsx or .csv + definitions : Path + Definitions folder with codelists, by default "definitions" + + Raises + ------ + ValueError + If input_file validation fails against specified codelist(s). + """ + DataStructureDefinition(definitions).validate(IamDataFrame(input_file)) diff --git a/tests/test_cli.py b/tests/test_cli.py index dd1b3422..9eaee1ff 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -420,3 +420,32 @@ def test_cli_run_workflow(tmp_path, simple_df): ) assert_iamframe_equal(simple_df, IamDataFrame(tmp_path / "output.xlsx")) + + +@pytest.mark.parametrize( + "status, unit, exit_code", [("valid", "EJ/yr", 0), ("invalid", "EJ", 1)] +) +def test_cli_valid_scenarios(status, unit, exit_code, tmp_path): + """Check that CLI validates an IAMC dataset according to defined codelist.""" + IamDataFrame( + pd.DataFrame( + [ + ["m_a", "s_a", "World", "Primary Energy", unit, 1, 2], + ], + columns=IAMC_IDX + [2005, 2010], + ) + ).to_excel(tmp_path / f"{status}_data.xlsx") + result_valid = runner.invoke( + cli, + [ + "validate-scenarios", + str(tmp_path / f"{status}_data.xlsx"), + "--definitions", + str( + MODULE_TEST_DATA_DIR + / "structure_validation_no_mappings" + / "definitions" + ), + ], + ) + assert result_valid.exit_code == exit_code