diff --git a/apps/jira_utils/README.md b/apps/jira_utils/README.md index b1c4b10..aa69ea1 100644 --- a/apps/jira_utils/README.md +++ b/apps/jira_utils/README.md @@ -15,7 +15,8 @@ pyutils-jira --help ``` ## Config file -A config file with the jira connection parameters like url, token, resolved_statuses, skip_project_ids, target_versions should be passed to command line option `--cfg-file` +A config file with the jira connection parameters like url, token, resolved_statuses, skip_project_ids, +target_versions should be passed to command line option `--cfg-file` ### Example: @@ -33,6 +34,7 @@ pyutils-jira: target_versions: - 1.0.0 - 2.0.1 + - 3.0.z issue_pattern: "([A-Z]+-[0-9]+)" version_string_not_targeted_jiras: "vfuture" ``` diff --git a/apps/jira_utils/jira_information.py b/apps/jira_utils/jira_information.py index af4d736..90848ff 100644 --- a/apps/jira_utils/jira_information.py +++ b/apps/jira_utils/jira_information.py @@ -18,7 +18,11 @@ LOGGER = get_logger(name=__name__) -@retry(retry=retry_if_exception_type(JIRAError), stop=stop_after_attempt(3), wait=wait_fixed(2)) +@retry( + retry=retry_if_exception_type(JIRAError), + stop=stop_after_attempt(3), + wait=wait_fixed(2), +) @lru_cache def get_issue( jira: JIRA, @@ -97,6 +101,8 @@ def get_jira_information( file_name: str, ) -> tuple[str, str]: jira_error_string = "" + re_compile = r"(?=9.0.0,<10", "python-simple-logger>=2.0.0,<3", "pyhelper-utils>=1.0.1,<2", - "ast-comments>=1.2.2" + "ast-comments>=1.2.2", + "click (>=8.1.7)", ] [[project.authors]] @@ -39,7 +40,7 @@ dependencies = [ omit = [ "tests/*" ] [tool.coverage.report] -fail_under = 65 +fail_under = 68 skip_empty = true [tool.coverage.html] @@ -55,6 +56,7 @@ include = [ "apps" ] [tool.hatch.build.targets.wheel] include = [ "apps" ] + [tool.mypy] show_error_codes = true warn_unused_ignores = true @@ -78,7 +80,12 @@ output-format = "grouped" [dependency-groups] dev = [ "ipdb>=0.13.13,<0.14", "ipython" ] -test = [ "pytest>=8.0.0,<9", "pytest-cov>=6.0.0,<7" ] +test = [ + "ipdb>=0.13.13", + "ipython>=8.18.1", + "pytest>=8.0.0,<9", + "pytest-cov>=6.0.0,<7", +] [build-system] requires = [ "hatchling" ] diff --git a/renovate.json b/renovate.json index eab0baf..119babc 100644 --- a/renovate.json +++ b/renovate.json @@ -1,19 +1,18 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + ":dependencyDashboard", + ":maintainLockFilesWeekly", + ":prHourlyLimitNone" + ], + "prConcurrentLimit": 0, + "lockFileMaintenance": { + "enabled": true + }, "packageRules": [ { - "matchPackagePatterns": [ - "python-simple-logger", - "pylero", - "pyhelper-utils", - "pytest-mock", - "pyyaml", - "ipdb", - "ipython", - "pytest", - "pytest-cov" - ], - "groupName": "poetry-deps" + "matchPackagePatterns": ["*"], + "groupName": "python-deps" } ] } diff --git a/tests/jira_utils/test_jira_utils.py b/tests/jira_utils/test_jira_utils.py index 8f888c5..a8575d3 100644 --- a/tests/jira_utils/test_jira_utils.py +++ b/tests/jira_utils/test_jira_utils.py @@ -13,7 +13,7 @@ ) LOGGER = get_logger(name=__name__) -BASE_COMMAND = "poetry run python apps/jira_utils/jira_information.py --verbose " +BASE_COMMAND = "uv run apps/jira_utils/jira_information.py --verbose " def test_process_jira_command_line_config_file_empty_config_token() -> None: @@ -80,7 +80,16 @@ def test_process_jira_command_line_config_file_valid_config(mocker): # Test case 1: Issue with no jira target versions and not resolved status ("issue1", ["resolved"], [], "1.0", "file1.txt", [], "", "1.0"), # Test case 2: Issue with no jira target versions, but resolved status - ("issue2", ["open"], [], "1.0", "file2.txt", [], "issue2 current status: open is resolved.", "1.0"), + ( + "issue2", + ["open"], + [], + "1.0", + "file2.txt", + [], + "issue2 current status: open is resolved.", + "1.0", + ), # Test case 3: Issue with no jira target versions, default resolved status ("issue3", [], [], "", "file3.txt", [], "", "1.1"), # Test case 4: Issue with not resolved state, but matching jira target version @@ -99,7 +108,29 @@ def test_process_jira_command_line_config_file_valid_config(mocker): # Test case 6: Issue that would be skipped for version check because of skip ("issue6", ["resolved"], ["1.0"], "1.0", "file6.txt", ["issue"], "", "1.1"), # Test case 7: Issue that would be skipped for version check but fail resolved check - ("issue7", ["open"], ["1.0"], "1.0", "file6.txt", ["issue"], "issue7 current status: open is resolved.", "1.1"), + ( + "issue7", + ["open"], + ["1.0"], + "1.0", + "file6.txt", + ["issue"], + "issue7 current status: open is resolved.", + "1.1", + ), + # Test case 8: Issue with unresolved state, and matching jira z target version + ("issue8", [], ["1.2.z"], "1.2,z", "file4.txt", [], "", "1.2.z"), + # Test case 9: Issue with unresolved state, and jira z target version not matching expected versions + ( + "issue8", + [], + ["1.2.3"], + "", + "file4.txt", + [], + "issue8 target version: 1.2.z, does not match expected version ['1.2.3'].", + "1.2.z", + ), ], ids=[ "test_no_jira_versions_no_resolved_status", @@ -109,6 +140,8 @@ def test_process_jira_command_line_config_file_valid_config(mocker): "test_no_target_versions_not_resolved_state", "test_skip_version_check", "test_skip_version_check_fail_status_check", + "test_matching_target_z_version", + "test_non_matching_target_z_version", ], ) def test_get_jira_information( @@ -131,8 +164,8 @@ def test_get_jira_information( if jira_target_versions: mocker.patch( - "apps.jira_utils.jira_information.re.search", - return_value=mocker.MagicMock(group=lambda x: test_jira_version), + "apps.jira_utils.jira_information.re.findall", + return_value=[test_jira_version], ) result = get_jira_information( jira_object=mock_jira, @@ -160,10 +193,20 @@ def test_get_jira_information( @pytest.mark.parametrize( "content_and_expected", [ - pytest.param({"content": "pytest.mark.jira(ABC-1111)", "expected": {"ABC-1111"}}, id="pytest_mark_jira"), - pytest.param({"content": "JIRA ID is jira_id=ABC-1111", "expected": {"ABC-1111"}}, id="jira_id="), pytest.param( - {"content": "JIRA URL is https://example.com/browse/ABC-1111", "expected": {"ABC-1111"}}, id="jira_url=" + {"content": "pytest.mark.jira(ABC-1111)", "expected": {"ABC-1111"}}, + id="pytest_mark_jira", + ), + pytest.param( + {"content": "JIRA ID is jira_id=ABC-1111", "expected": {"ABC-1111"}}, + id="jira_id=", + ), + pytest.param( + { + "content": "JIRA URL is https://example.com/browse/ABC-1111", + "expected": {"ABC-1111"}, + }, + id="jira_url=", ), pytest.param( { @@ -184,6 +227,8 @@ def test_get_jira_information( ) def test_get_jira_ids_from_file_content(content_and_expected): jira_ids = get_jira_ids_from_file_content( - file_content=content_and_expected["content"], issue_pattern=r"([A-Z]+-[0-9]+)", jira_url="https://example.com" + file_content=content_and_expected["content"], + issue_pattern=r"([A-Z]+-[0-9]+)", + jira_url="https://example.com", ) assert jira_ids == content_and_expected["expected"] diff --git a/tests/polarion/test_polarion_automated.py b/tests/polarion/test_polarion_automated.py index 1ff9a01..4b4176f 100644 --- a/tests/polarion/test_polarion_automated.py +++ b/tests/polarion/test_polarion_automated.py @@ -3,7 +3,7 @@ from pyhelper_utils.shell import run_command -BASE_COMMAND = "poetry run python apps/polarion/polarion_set_automated.py --verbose" +BASE_COMMAND = "uv run apps/polarion/polarion_set_automated.py --verbose" def test_missing_required_params_set_automated(): diff --git a/tests/polarion/test_verify_polarion_requirements.py b/tests/polarion/test_verify_polarion_requirements.py index 71c724a..bff3a68 100644 --- a/tests/polarion/test_verify_polarion_requirements.py +++ b/tests/polarion/test_verify_polarion_requirements.py @@ -3,7 +3,7 @@ from pyhelper_utils.shell import run_command -BASE_COMMAND = "poetry run python apps/polarion/polarion_verify_tc_requirements.py" +BASE_COMMAND = "uv run apps/polarion/polarion_verify_tc_requirements.py" def test_missing_project_id(): diff --git a/tox.ini b/tox.ini index 22ecc85..18b55d8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,13 @@ [tox] -envlist = {python3.9,python3.10,python3.11,python3.12}-{unittest}, +envlist = 3.9, 3.1{0,1,2,3} skipsdist = True - [testenv] setenv = PYTHONPATH = {toxinidir} deps = uv commands = - uv run pytest tests + uv python pin python{envname} + uv sync --locked --all-extras --dev --group test + uv run pytest tests diff --git a/uv.lock b/uv.lock index f420b9d..6757f71 100644 --- a/uv.lock +++ b/uv.lock @@ -842,6 +842,7 @@ version = "1.0.20" source = { editable = "." } dependencies = [ { name = "ast-comments" }, + { name = "click" }, { name = "jira" }, { name = "pyhelper-utils" }, { name = "pylero" }, @@ -857,6 +858,8 @@ dev = [ { name = "ipython" }, ] test = [ + { name = "ipdb" }, + { name = "ipython" }, { name = "pytest" }, { name = "pytest-cov" }, ] @@ -864,6 +867,7 @@ test = [ [package.metadata] requires-dist = [ { name = "ast-comments", specifier = ">=1.2.2" }, + { name = "click", specifier = ">=8.1.7" }, { name = "jira", specifier = ">=3.6.0,<4" }, { name = "pyhelper-utils", specifier = ">=1.0.1,<2" }, { name = "pylero", specifier = ">=0.1.0,<0.2" }, @@ -879,6 +883,8 @@ dev = [ { name = "ipython" }, ] test = [ + { name = "ipdb", specifier = ">=0.13.13" }, + { name = "ipython", specifier = ">=8.18.1" }, { name = "pytest", specifier = ">=8.0.0,<9" }, { name = "pytest-cov", specifier = ">=6.0.0,<7" }, ]