From 40c40cc40bb2a70bd7e88dc3b57cba8bc5e9af3c Mon Sep 17 00:00:00 2001 From: Gursimran Singh Date: Wed, 8 Jan 2020 16:48:42 -0500 Subject: [PATCH] HelpInputOutputValidator error messages and bug fix --- README.md | 2 + .../rules/help_input_output_validator.py | 89 +++++++++++-------- setup.py | 2 +- 3 files changed, 56 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 33626700..2eb06f96 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ to simulate the `--all` flag. ## Changelog +* 2.6.9 - Update HelpInputOutputValidator to fix error messaging | +Fix issue with HelpInputOutputValidator when help.md has action and trigger with same name * 2.6.8 - Docker Validator to run with -a command line argument | Helpful message on failure * 2.6.7 - Fix issue where OutputValidator was throwing error for plugins without any action * 2.6.6 - Fix issue where HelpInputOutputValidator was not extracting complete output section of an action or trigger diff --git a/icon_validator/rules/help_input_output_validator.py b/icon_validator/rules/help_input_output_validator.py index 45a342d9..06357b67 100644 --- a/icon_validator/rules/help_input_output_validator.py +++ b/icon_validator/rules/help_input_output_validator.py @@ -10,29 +10,45 @@ class HelpInputOutputValidator(KomandPluginValidator): action_missing = 0 @staticmethod - def validate_input(action_title: str, action_input: list): - regex = r"#### " + action_title + "\n.*?#+ Output" + def validate_input(action_title: str, action_input: list, process_type: str): + regex = r"### " + process_type.capitalize() + ".*?#### " + action_title + "\n.*?#+ Output" + if process_type == "actions": + regex = regex + ".*?### Triggers" + action_input_section = re.findall(regex, HelpInputOutputValidator.raw_help, re.DOTALL) if not action_input_section: - print(f"{YELLOW}Action/Trigger \"{action_title}\" could be missing or title is incorrect in help.md{RESET_ALL}") + print(f"{YELLOW}{process_type[:-1].capitalize()} \"{action_title}\" could be missing or title is incorrect in help.md{RESET_ALL}") HelpInputOutputValidator.violated = 1 HelpInputOutputValidator.action_missing = 1 return + regex = r"#### " + action_title + "\n.*?#+ Output" + action_input_section = re.findall(regex, action_input_section[0], re.DOTALL) + for input_fields in action_input: if input_fields not in action_input_section[0]: HelpInputOutputValidator.violations.append(input_fields) @staticmethod - def validate_output(action_title: str, action_output: list): + def validate_output(action_title: str, action_output: list, process_type: str): + regex = r"### " + process_type.capitalize() + ".*?#### " + action_title + "\n.*?#+ Output\n\n.*?\n\n" + if process_type == "actions": + regex = regex + ".*?### Trigger" + + action_help_section_temp = re.findall(regex, HelpInputOutputValidator.raw_help, re.DOTALL) regex = r"#### " + action_title + "\n.*?#+ Output\n\n.*?\n\n" - action_help_section = re.findall(regex, HelpInputOutputValidator.raw_help, re.DOTALL) + action_help_section = re.findall(regex, action_help_section_temp[0], re.DOTALL) + + if "This " + process_type[:-1] + " does not contain any outputs." not in action_help_section[0]: + regex = r"### " + process_type.capitalize() + ".*?#### " + action_title + "\n.*?#+ Output\n\n.*?" + re.escape("|Name|Type|Required|Description|") + ".*?\n\n" + if process_type == "actions": + regex = regex + ".*?### Triggers" - if "This action does not contain any outputs." not in action_help_section[0]: + action_help_section_temp = re.findall(regex, HelpInputOutputValidator.raw_help, re.DOTALL) regex = r"#### " + action_title + "\n.*?#+ Output\n\n.*?" + re.escape("|Name|Type|Required|Description|") + ".*?\n\n" - action_help_section = re.findall(regex, HelpInputOutputValidator.raw_help, re.DOTALL) - action_output_section = re.findall(r'#+ Output\n\n.*?' + re.escape("|Name|Type|Required|Description|") + ".*?\n\n", action_help_section[0], re.DOTALL) + action_output_section_temp = re.findall(regex, action_help_section_temp[0], re.DOTALL) + action_output_section = re.findall(r'#+ Output\n\n.*?' + re.escape("|Name|Type|Required|Description|") + ".*?\n\n", action_output_section_temp[0], re.DOTALL) else: action_output_section = re.findall(r"#+ Output\n\n.*?\n\n", action_help_section[0], re.DOTALL) @@ -68,34 +84,35 @@ def get_spec_output(output_content: dict) -> list: def validate(self, spec): HelpInputOutputValidator.raw_help = spec.raw_help() raw_spec_yaml = spec.spec_dictionary() - actions = raw_spec_yaml.get('actions', {}) - actions.update(raw_spec_yaml.get('triggers', {})) - - for key, value in actions.items(): - action_name = actions[key].get('title') - input_section = actions[key].get('input') - output_section = actions[key].get('output') - HelpInputOutputValidator.action_missing = 0 - - # Action with no input in spec file will skip input validation - if input_section: - action_input_fields = HelpInputOutputValidator.get_spec_input(input_section) - HelpInputOutputValidator.validate_input(action_name, action_input_fields) - - if HelpInputOutputValidator.violations: - print(f'{YELLOW}Input violations: Action/Trigger -> \"{action_name}\": Missing {HelpInputOutputValidator.violations} in help.md{RESET_ALL}') - HelpInputOutputValidator.violations = [] - HelpInputOutputValidator.violated = 1 - - # Actions with no output in spec file will skip output validation. Also, skip output validation for actions not found in help.md - if output_section and not HelpInputOutputValidator.action_missing: - action_output_fields = HelpInputOutputValidator.get_spec_output(output_section) - HelpInputOutputValidator.validate_output(action_name, action_output_fields) - - if HelpInputOutputValidator.violations: - print(f'{YELLOW}Output violations: Action/Trigger -> \"{action_name}\": Missing {HelpInputOutputValidator.violations} in help.md{RESET_ALL}') - HelpInputOutputValidator.violations = [] - HelpInputOutputValidator.violated = 1 + process_type = ["actions", "triggers"] + + for p_type in process_type: + actions = raw_spec_yaml.get(p_type, {}) + for key, value in actions.items(): + action_name = actions[key].get('title') + input_section = actions[key].get('input') + output_section = actions[key].get('output') + HelpInputOutputValidator.action_missing = 0 + + # Action with no input in spec file will skip input validation + if input_section: + action_input_fields = HelpInputOutputValidator.get_spec_input(input_section) + HelpInputOutputValidator.validate_input(action_name, action_input_fields, p_type) + + if HelpInputOutputValidator.violations: + print(f'{YELLOW}Input violations: {p_type[:-1].capitalize()} -> \"{action_name}\": Missing {HelpInputOutputValidator.violations} in help.md{RESET_ALL}') + HelpInputOutputValidator.violations = [] + HelpInputOutputValidator.violated = 1 + + # Actions with no output in spec file will skip output validation. Also, skip output validation for actions not found in help.md + if output_section and not HelpInputOutputValidator.action_missing: + action_output_fields = HelpInputOutputValidator.get_spec_output(output_section) + HelpInputOutputValidator.validate_output(action_name, action_output_fields, p_type) + + if HelpInputOutputValidator.violations: + print(f'{YELLOW}Output violations: {p_type[:-1].capitalize()}-> \"{action_name}\": Missing {HelpInputOutputValidator.violations} in help.md{RESET_ALL}') + HelpInputOutputValidator.violations = [] + HelpInputOutputValidator.violated = 1 if HelpInputOutputValidator.violated: raise Exception("Help.md is not in sync with plugin.spec.yaml. Please check and rectify above violations") diff --git a/setup.py b/setup.py index cdb5dd15..e2b32a4d 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ long_description = fh.read() setup(name='insightconnect_integrations_validators', - version='2.6.8', + version='2.6.9', description='Validator tooling for InsightConnect integrations', long_description=long_description, long_description_content_type="text/markdown",