diff --git a/kibot/config_reader.py b/kibot/config_reader.py index ad81488d4..7ec5e7d60 100644 --- a/kibot/config_reader.py +++ b/kibot/config_reader.py @@ -49,6 +49,8 @@ AUTO_DOWN_URL = GITHUB_RAW+'auto_download-22x22.png' AUTO_DOWN = '![Auto-download]('+AUTO_DOWN_URL+')' VALID_SECTIONS = {'kiplot', 'kibot', 'import', 'global', 'filters', 'variants', 'preflight', 'outputs', 'groups'} +VALID_IMPORT = {'file', 'is_external', 'outputs', 'preflights', 'filters', 'variants', 'global', 'globals', 'groups', + 'definitions'} VALID_KIBOT_SEC = {'version', 'imported_global_has_less_priority'} RST_WARNING = ".. Automatically generated by KiBot, please don't edit this file\n" rst_mode = False @@ -317,9 +319,9 @@ def _parse_import_items(kind, fname, value): if isinstance(v, str): values.append(v) else: - CfgYamlReader._config_error_import(fname, '`{}` items must be strings ({})'.format(kind, str(v))) + CfgYamlReader._config_error_import(fname, f'`{kind}` items must be strings ({v})') return values - CfgYamlReader._config_error_import(fname, '`{}` must be a string or a list ({})'.format(kind, str(v))) + CfgYamlReader._config_error_import(fname, f'`{kind}` must be a string or a list ({value})') def _parse_import_outputs(self, outs, explicit_outs, fn_rel, data, imported): sel_outs = [] @@ -556,7 +558,11 @@ def _parse_import(self, imp, name, collected_definitions, apply=True, depth=0): CfgYamlReader._config_error_import(fn, 'definitions must be a dict') local_defs = v else: - self._config_error_import(fn, "Unknown import entry `{}`".format(str(v))) + msg = f"Unknown import entry `{k}`" + best_matches = difflib.get_close_matches(k, VALID_IMPORT) + if best_matches: + msg += " (did you mean {}?)".format(' or '.join(best_matches)) + self._config_error_import(fn, msg) if fn is None: raise KiPlotConfigurationError("`import` entry without `file` ({})".format(str(entry))) else: diff --git a/tests/test_plot/test_yaml_errors.py b/tests/test_plot/test_yaml_errors.py index 4f7cef723..84b9e75a3 100644 --- a/tests/test_plot/test_yaml_errors.py +++ b/tests/test_plot/test_yaml_errors.py @@ -808,3 +808,57 @@ def test_pre_list_instead_of_dict(test_dir): ctx.run(EXIT_BAD_CONFIG) assert ctx.search_err(r"Found .*list.* instead of dict") ctx.clean_up(keep_project=True) + + +@pytest.mark.indep +def test_import_not_list(test_dir): + """ Import preflights, but give a number """ + ctx = context.TestContext(test_dir, PRJ, 'error_import_not_list') + ctx.run(EXIT_BAD_CONFIG) + assert ctx.search_err(r"`preflights` must be a string or a list") + ctx.clean_up(keep_project=True) + + +@pytest.mark.indep +def test_import_item_not_str(test_dir): + """ Import preflights, but give a number in the list """ + ctx = context.TestContext(test_dir, PRJ, 'error_import_item_not_str') + ctx.run(EXIT_BAD_CONFIG) + assert ctx.search_err(r"`preflights` items must be strings") + ctx.clean_up(keep_project=True) + + +@pytest.mark.indep +def test_import_defs_not_dict(test_dir): + """ Import definitions, but not a dict """ + ctx = context.TestContext(test_dir, PRJ, 'error_import_defs_not_dict') + ctx.run(EXIT_BAD_CONFIG) + assert ctx.search_err(r"definitions must be a dict") + ctx.clean_up(keep_project=True) + + +@pytest.mark.indep +def test_import_unk_entry(test_dir): + """ Import unknown entry (pre-flight) """ + ctx = context.TestContext(test_dir, PRJ, 'error_import_unk_entry') + ctx.run(EXIT_BAD_CONFIG) + assert ctx.search_err(r"Unknown import entry `pre-flights` .* in .unnamed. import") + ctx.clean_up(keep_project=True) + + +@pytest.mark.indep +def test_import_no_file(test_dir): + """ Import no file name """ + ctx = context.TestContext(test_dir, PRJ, 'error_import_no_file') + ctx.run(EXIT_BAD_CONFIG) + assert ctx.search_err(r"`import` entry without `file`") + ctx.clean_up(keep_project=True) + + +@pytest.mark.indep +def test_import_no_str_or_dict(test_dir): + """ Import no file name """ + ctx = context.TestContext(test_dir, PRJ, 'error_import_no_str_or_dict') + ctx.run(EXIT_BAD_CONFIG) + assert ctx.search_err(r"`import` items must be strings or dicts") + ctx.clean_up(keep_project=True) diff --git a/tests/yaml_samples/error_import_defs_not_dict.kibot.yaml b/tests/yaml_samples/error_import_defs_not_dict.kibot.yaml new file mode 100644 index 000000000..a1611aef8 --- /dev/null +++ b/tests/yaml_samples/error_import_defs_not_dict.kibot.yaml @@ -0,0 +1,6 @@ +kibot: + version: 1 + +import: + - file: drc.kibot.yaml + definitions: 10 diff --git a/tests/yaml_samples/error_import_item_not_str.kibot.yaml b/tests/yaml_samples/error_import_item_not_str.kibot.yaml new file mode 100644 index 000000000..3caf767bd --- /dev/null +++ b/tests/yaml_samples/error_import_item_not_str.kibot.yaml @@ -0,0 +1,6 @@ +kibot: + version: 1 + +import: + - file: drc.kibot.yaml + preflights: ['a', 10] diff --git a/tests/yaml_samples/error_import_no_file.kibot.yaml b/tests/yaml_samples/error_import_no_file.kibot.yaml new file mode 100644 index 000000000..8dfd1bfbe --- /dev/null +++ b/tests/yaml_samples/error_import_no_file.kibot.yaml @@ -0,0 +1,5 @@ +kibot: + version: 1 + +import: + - preflights: run_drc diff --git a/tests/yaml_samples/error_import_no_str_or_dict.kibot.yaml b/tests/yaml_samples/error_import_no_str_or_dict.kibot.yaml new file mode 100644 index 000000000..9886a3175 --- /dev/null +++ b/tests/yaml_samples/error_import_no_str_or_dict.kibot.yaml @@ -0,0 +1,5 @@ +kibot: + version: 1 + +import: + - 10 diff --git a/tests/yaml_samples/error_import_not_list.kibot.yaml b/tests/yaml_samples/error_import_not_list.kibot.yaml new file mode 100644 index 000000000..8ec7ccc5e --- /dev/null +++ b/tests/yaml_samples/error_import_not_list.kibot.yaml @@ -0,0 +1,6 @@ +kibot: + version: 1 + +import: + - file: drc.kibot.yaml + preflights: 10 diff --git a/tests/yaml_samples/error_import_unk_entry.kibot.yaml b/tests/yaml_samples/error_import_unk_entry.kibot.yaml new file mode 100644 index 000000000..4346f3bf9 --- /dev/null +++ b/tests/yaml_samples/error_import_unk_entry.kibot.yaml @@ -0,0 +1,5 @@ +kibot: + version: 1 + +import: + - pre-flights: 10