diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index f59f9e77199..53e98fb6758 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -22,7 +22,7 @@ ignorable_errors = [ [use_git] select = [ - "BA100", "BA101", "BA105", "BA106", "BA110", "BA111", "BA114", "BA116", "BA118", "BA119", "BA124", "BA126", + "BA100", "BA101", "BA105", "BA106", "BA108", "BA110", "BA111", "BA114", "BA116", "BA118", "BA119", "BA124", "BA126", "PA100", "PA101", "PA102", "PA103", "PA104", "PA105", "PA107", "PA108", "PA109", "PA111", "PA113", "PA115", "PA117", "PA118", "PA119", "PA120", "PA121", "PA123", "PA125", "PA127", "PA128", "PA130", "BC100", "BC101", "BC102", "BC105", "BC108", @@ -48,7 +48,7 @@ select = [ "IN131", "IN134", "IN135", "IN139", "IN141", "IN142", "IN144", "IN145", "IN146", "IN149", "IN150", "IN151", "IN152", "IN153", "IN154", "IN156", "IN158", "IN159", "IN160", "IN161", "IN162", "PB100","PB104", - "BA100", "BA101", "BA105", "BA106", "BA110", "BA111", "BA113", "BA116", "BA118", "BA119", "BA126", + "BA100", "BA101", "BA105", "BA106", "BA108", "BA110", "BA111", "BA113", "BA116", "BA118", "BA119", "BA126", "PA100", "PA101", "PA102", "PA103", "PA104", "PA105", "PA107", "PA108", "PA109", "PA111", "PA113", "PA115", "PA117", "PA118", "PA119", "PA120", "PA121", "PA123", "PA125", "PA127", "PA130", "DO100", "DO101", "DO102", "DO103", "DO104", diff --git a/demisto_sdk/commands/validate/tests/BA_validators_test.py b/demisto_sdk/commands/validate/tests/BA_validators_test.py index 5824f21e636..51578597d15 100644 --- a/demisto_sdk/commands/validate/tests/BA_validators_test.py +++ b/demisto_sdk/commands/validate/tests/BA_validators_test.py @@ -57,6 +57,9 @@ from demisto_sdk.commands.validate.validators.BA_validators.BA106_is_from_version_sufficient_integration import ( IsFromVersionSufficientIntegrationValidator, ) +from demisto_sdk.commands.validate.validators.BA_validators.BA108_is_folder_name_has_separators import ( + IsFolderNameHasSeparatorsValidator, +) from demisto_sdk.commands.validate.validators.BA_validators.BA110_is_entity_type_in_entity_name import ( IsEntityTypeInEntityNameValidator, ) @@ -1867,3 +1870,47 @@ def test_IsContentItemNameContainTrailingSpacesValidator_fix( results.message == f"Removed trailing spaces from the {', '.join(fields_with_trailing_spaces)} fields of following content items: {VALUE_WITH_TRAILING_SPACE.rstrip()}" ) + + +@pytest.mark.parametrize( + "content_items, expected_msg", + [ + pytest.param( + [ + create_integration_object( + name="invalid_integration_name" + ), + ], + "The folder name 'invalid_integration_name' should be without any separator.", + id="an invalid integration name", + ), + pytest.param( + [ + create_integration_object( + name="invalidIntegrationName" + ), + ], + "", + id="a valid integration name.", + ), + pytest.param( + [ + create_script_object(name="invalid-script-name"), + ], + "The folder name 'invalid-script-name' should be without any separator.", + id="an invalid script name", + ), + pytest.param( + [ + create_script_object(name="invalidScriptName"), + ], + "", + id="a valid script name", + ), + ], +) +def test_IsFolderNameHasSeparatorsValidator_is_valid(content_items, expected_msg): + result = IsFolderNameHasSeparatorsValidator().is_valid(content_items) + + if result: + assert result[0].message == expected_msg diff --git a/demisto_sdk/commands/validate/tests/test_tools.py b/demisto_sdk/commands/validate/tests/test_tools.py index e015e34af0e..b20b7046ebe 100644 --- a/demisto_sdk/commands/validate/tests/test_tools.py +++ b/demisto_sdk/commands/validate/tests/test_tools.py @@ -32,6 +32,7 @@ def create_integration_object( values: Optional[List[Any]] = None, pack_info: Optional[Dict[str, Any]] = None, readme_content: Optional[str] = None, + name: Optional[str] = None, code: Optional[str] = None, ) -> Integration: """Creating an integration object with altered fields from a default integration yml structure. @@ -54,6 +55,9 @@ def create_integration_object( if readme_content is not None: additional_params["readme"] = readme_content + if name is not None: + additional_params["name"] = name + integration = pack.create_integration(yml=yml_content, **additional_params) code = code or "from MicrosoftApiModule import *" integration.code.write(code) @@ -182,6 +186,7 @@ def create_script_object( paths: Optional[List[str]] = None, values: Optional[List[Any]] = None, pack_info: Optional[Dict[str, Any]] = None, + name: Optional[str] = None, code: Optional[str] = None, test_code: Optional[str] = None, ): @@ -195,12 +200,16 @@ def create_script_object( Returns: The script object. """ + additional_params = {} + if name is not None: + additional_params["name"] = name + yml_content = load_yaml("script.yml") update_keys(yml_content, paths, values) pack = REPO.create_pack() if pack_info: pack.set_data(**pack_info) - script = pack.create_script(yml=yml_content) + script = pack.create_script(yml=yml_content, **additional_params) code = code or "from MicrosoftApiModule import *" script.code.write(code) if test_code: diff --git a/demisto_sdk/commands/validate/validators/BA_validators/BA108_is_folder_name_has_separators.py b/demisto_sdk/commands/validate/validators/BA_validators/BA108_is_folder_name_has_separators.py new file mode 100644 index 00000000000..94c1aa2aead --- /dev/null +++ b/demisto_sdk/commands/validate/validators/BA_validators/BA108_is_folder_name_has_separators.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.common.constants import GitStatuses +from demisto_sdk.commands.content_graph.objects.integration import Integration +from demisto_sdk.commands.content_graph.objects.script import Script +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[Integration, Script] + + +class IsFolderNameHasSeparatorsValidator(BaseValidator[ContentTypes]): + error_code = "BA108" + description = "Check if there are separators in the folder name." + error_message = "The folder name '{0}' should be without any separator." + related_field = "" + rationale = "To ensure consistent, readable folder structures by avoiding separators like spaces, underscores, or hyphens." + is_auto_fixable = False + expected_git_statuses = [GitStatuses.RENAMED, GitStatuses.ADDED] + + def is_valid(self, content_items: Iterable[ContentTypes]) -> List[ValidationResult]: + separators = ["_", "-"] + return [ + ValidationResult( + validator=self, + message=self.error_message.format(content_item.path.parent.name), + content_object=content_item, + ) + for content_item in content_items + if (any(char in separators for char in content_item.path.parent.name)) + ]