From d3c6ed9226704ae031d45b59a0f261f5790a40b5 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 12:47:58 +0200 Subject: [PATCH 1/9] Fix when 2 function have the same name, run in parallel --- apps/unused_code/unused_code.py | 91 +++++++++++++++++++++++---------- poetry.lock | 2 +- pyproject.toml | 3 +- 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index e9d8e6d..97c6af1 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -3,12 +3,13 @@ import os import subprocess import sys +from concurrent.futures import Future, ThreadPoolExecutor, as_completed +from typing import Any, Iterable, List import click from simple_logger.logger import get_logger -from apps.utils import all_python_files, ListParamType, get_util_config -from typing import Any, Iterable, List +from apps.utils import ListParamType, all_python_files, get_util_config LOGGER = get_logger(name=__name__) @@ -50,6 +51,45 @@ def is_ignore_function_list(ignore_prefix_list: List[str], function: ast.Functio return False +def proccess_file(py_file: str, func_ignore_prefix: List[str], file_ignore_list: List[str]) -> str: + if os.path.basename(py_file) in file_ignore_list: + LOGGER.debug(f"Skipping file: {py_file}") + return "" + + with open(py_file) as fd: + tree = ast.parse(source=fd.read()) + + for func in _iter_functions(tree=tree): + if func_ignore_prefix and is_ignore_function_list(ignore_prefix_list=func_ignore_prefix, function=func): + LOGGER.debug(f"Skipping function: {func.name}") + continue + + if is_fixture_autouse(func=func): + LOGGER.debug(f"Skipping fixture function: {func.name}") + continue + + used = False + _func_grep_found = subprocess.check_output(f"git grep -w '{func.name}'", shell=True) + + for entry in _func_grep_found.decode().splitlines(): + _, _line = entry.split(":", 1) + + if f"def {func.name}" in _line: + continue + + if _line.strip().startswith("#"): + continue + + if func.name in _line: + used = True + break + + if not used: + return f"{os.path.relpath(py_file)}:{func.name}:{func.lineno}:{func.col_offset} Is not used anywhere in the code." + + return "" + + @click.command() @click.option( "--config-file-path", @@ -67,10 +107,10 @@ def is_ignore_function_list(ignore_prefix_list: List[str], function: ast.Functio help="Provide a comma-separated string or list of function prefixes to exclude", type=ListParamType(), ) -@click.option("--verbose", default=False, is_flag=True) +@click.option("--verbose", "-v", default=False, is_flag=True) def get_unused_functions( - config_file_path: Any, exclude_files: Any, exclude_function_prefixes: Any, verbose: bool -) -> Any: + config_file_path: str, exclude_files: list[str], exclude_function_prefixes: list[str], verbose: bool +) -> None: LOGGER.setLevel(logging.DEBUG if verbose else logging.INFO) _unused_functions = [] @@ -78,33 +118,28 @@ def get_unused_functions( func_ignore_prefix = exclude_function_prefixes or unused_code_config.get("exclude_function_prefix", []) file_ignore_list = exclude_files or unused_code_config.get("exclude_files", []) - for py_file in all_python_files(): - if os.path.basename(py_file) in file_ignore_list: - continue - with open(py_file) as fd: - tree = ast.parse(source=fd.read()) + jobs: list[Future] = [] - for func in _iter_functions(tree=tree): - if func_ignore_prefix and is_ignore_function_list(ignore_prefix_list=func_ignore_prefix, function=func): - continue + with ThreadPoolExecutor() as executor: + for py_file in all_python_files(): + jobs.append( + executor.submit( + proccess_file, + py_file=py_file, + func_ignore_prefix=func_ignore_prefix, + file_ignore_list=file_ignore_list, + ) + ) - if is_fixture_autouse(func=func): - continue + for result in as_completed(jobs): + _unused_functions.append(result.result()) - _used = subprocess.check_output( - f"git grep -w '{func.name}' | wc -l", - shell=True, - ) - used = int(_used.strip()) - if used < 2: - _unused_functions.append( - f"{os.path.relpath(py_file)}:{func.name}:{func.lineno}:{func.col_offset} Is" - " not used anywhere in the code.", - ) - if _unused_functions: - click.echo("\n".join(_unused_functions)) - sys.exit(1) + if unused_functions := [_unused_func for _unused_func in _unused_functions if _unused_func]: + click.echo("\n".join(unused_functions)) + sys.exit(1) if __name__ == "__main__": get_unused_functions() + + # get_unused_functions() diff --git a/poetry.lock b/poetry.lock index eaa64a3..fb34bbf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "asttokens" diff --git a/pyproject.toml b/pyproject.toml index f42f48d..d36bb75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ show_contexts = true show_error_codes = true warn_unused_ignores = true check_untyped_defs = true -disallow_any_generics = true +disallow_any_generics = false disallow_incomplete_defs = true disallow_untyped_defs = true no_implicit_optional = true @@ -23,6 +23,7 @@ preview = true line-length = 120 fix = true output-format = "grouped" +extend-select = ["I"] [tool.ruff.format] exclude = [".git", ".venv", ".mypy_cache", ".tox", "__pycache__"] From 85b7706724677488c06cac01875e0aeff982781d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 10:49:54 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- apps/jira_utils/jira_information.py | 15 ++++++--------- apps/polarion/polarion_set_automated.py | 9 +++++---- apps/polarion/polarion_utils.py | 12 +++++++----- apps/polarion/polarion_verify_tc_requirements.py | 7 ++++--- apps/utils.py | 7 ++++--- tests/jira_utils/test_jira_utils.py | 14 ++++++++------ tests/polarion/test_polarion_automated.py | 1 + .../polarion/test_verify_polarion_requirements.py | 1 + tests/unused_code/test_unused_code.py | 1 + 9 files changed, 37 insertions(+), 30 deletions(-) diff --git a/apps/jira_utils/jira_information.py b/apps/jira_utils/jira_information.py index 5f13280..8919c9f 100644 --- a/apps/jira_utils/jira_information.py +++ b/apps/jira_utils/jira_information.py @@ -1,20 +1,17 @@ +import concurrent.futures import logging +import os import re import sys -import os -import concurrent.futures from functools import lru_cache +from typing import Any, Dict, List, Set, Tuple import click -from jira import JIRA, JIRAError, Issue - +from jira import JIRA, Issue, JIRAError from simple_logger.logger import get_logger - -from apps.utils import ListParamType -from typing import Dict, List, Set, Tuple, Any - from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed -from apps.utils import all_python_files, get_util_config + +from apps.utils import ListParamType, all_python_files, get_util_config LOGGER = get_logger(name=__name__) diff --git a/apps/polarion/polarion_set_automated.py b/apps/polarion/polarion_set_automated.py index 2f89a33..920eddf 100644 --- a/apps/polarion/polarion_set_automated.py +++ b/apps/polarion/polarion_set_automated.py @@ -1,13 +1,14 @@ from __future__ import annotations + import logging import os -from simple_logger.logger import get_logger import sys -import click +from typing import Dict, List, Optional -from apps.polarion.polarion_utils import get_polarion_project_id, find_polarion_ids, update_polarion_ids -from typing import List, Dict, Optional +import click +from simple_logger.logger import get_logger +from apps.polarion.polarion_utils import find_polarion_ids, get_polarion_project_id, update_polarion_ids LOGGER = get_logger(name=__name__) diff --git a/apps/polarion/polarion_utils.py b/apps/polarion/polarion_utils.py index fd5434a..e29801f 100644 --- a/apps/polarion/polarion_utils.py +++ b/apps/polarion/polarion_utils.py @@ -1,12 +1,14 @@ from __future__ import annotations + import re -import sys -from simple_logger.logger import get_logger import shlex import subprocess +import sys +from typing import Dict, List + +from simple_logger.logger import get_logger from apps.utils import get_util_config -from typing import Dict, List LOGGER = get_logger(name=__name__) AUTOMATED = "automated" @@ -36,8 +38,8 @@ def validate_polarion_requirements( ) -> List[str]: tests_with_missing_requirements: List[str] = [] if polarion_test_ids: - from pylero.work_item import TestCase, Requirement from pylero.exceptions import PyleroLibException + from pylero.work_item import Requirement, TestCase for _id in polarion_test_ids: has_req = False @@ -80,8 +82,8 @@ def update_polarion_ids( if polarion_ids: automation_status = AUTOMATED if is_automated else NOT_AUTOMATED - from pylero.work_item import TestCase from pylero.exceptions import PyleroLibException + from pylero.work_item import TestCase for id in polarion_ids: try: diff --git a/apps/polarion/polarion_verify_tc_requirements.py b/apps/polarion/polarion_verify_tc_requirements.py index beb4435..6f559b7 100644 --- a/apps/polarion/polarion_verify_tc_requirements.py +++ b/apps/polarion/polarion_verify_tc_requirements.py @@ -1,10 +1,11 @@ import logging -from simple_logger.logger import get_logger import os -import click import sys -from apps.polarion.polarion_utils import validate_polarion_requirements, find_polarion_ids, get_polarion_project_id +import click +from simple_logger.logger import get_logger + +from apps.polarion.polarion_utils import find_polarion_ids, get_polarion_project_id, validate_polarion_requirements LOGGER = get_logger(name="polarion-verify-tc-requirements") diff --git a/apps/utils.py b/apps/utils.py index 7a4f925..e9ecbff 100644 --- a/apps/utils.py +++ b/apps/utils.py @@ -1,11 +1,12 @@ from __future__ import annotations + +import json import os +from typing import Any, Dict, Iterable, Optional +import click import yaml from simple_logger.logger import get_logger -import json -import click -from typing import Any, Dict, Iterable, Optional LOGGER = get_logger(name=__name__) diff --git a/tests/jira_utils/test_jira_utils.py b/tests/jira_utils/test_jira_utils.py index 1c05eda..8f888c5 100644 --- a/tests/jira_utils/test_jira_utils.py +++ b/tests/jira_utils/test_jira_utils.py @@ -1,14 +1,16 @@ +import os +import shlex +import subprocess + import pytest +from pyhelper_utils.shell import run_command +from simple_logger.logger import get_logger + from apps.jira_utils.jira_information import ( + get_jira_ids_from_file_content, get_jira_information, process_jira_command_line_config_file, - get_jira_ids_from_file_content, ) -from simple_logger.logger import get_logger -from pyhelper_utils.shell import run_command -import shlex -import subprocess -import os LOGGER = get_logger(name=__name__) BASE_COMMAND = "poetry run python apps/jira_utils/jira_information.py --verbose " diff --git a/tests/polarion/test_polarion_automated.py b/tests/polarion/test_polarion_automated.py index a1c4a64..b3866fb 100644 --- a/tests/polarion/test_polarion_automated.py +++ b/tests/polarion/test_polarion_automated.py @@ -1,5 +1,6 @@ import shlex import subprocess + from pyhelper_utils.shell import run_command BASE_COMMAND = "poetry run python apps/polarion/polarion_set_automated.py --verbose" diff --git a/tests/polarion/test_verify_polarion_requirements.py b/tests/polarion/test_verify_polarion_requirements.py index 7cf557d..71c724a 100644 --- a/tests/polarion/test_verify_polarion_requirements.py +++ b/tests/polarion/test_verify_polarion_requirements.py @@ -1,5 +1,6 @@ import shlex import subprocess + from pyhelper_utils.shell import run_command BASE_COMMAND = "poetry run python apps/polarion/polarion_verify_tc_requirements.py" diff --git a/tests/unused_code/test_unused_code.py b/tests/unused_code/test_unused_code.py index b8d29b5..48dc8fa 100644 --- a/tests/unused_code/test_unused_code.py +++ b/tests/unused_code/test_unused_code.py @@ -1,4 +1,5 @@ from simple_logger.logger import get_logger + from apps.unused_code.unused_code import get_unused_functions from tests.utils import get_cli_runner From 4f3c9820dbb42c3b9c45273317ba849e71f455b7 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 13:42:08 +0200 Subject: [PATCH 3/9] Fix typo, do not use shell=True to run grep command --- apps/unused_code/unused_code.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index 97c6af1..b6aecd9 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -51,7 +51,7 @@ def is_ignore_function_list(ignore_prefix_list: List[str], function: ast.Functio return False -def proccess_file(py_file: str, func_ignore_prefix: List[str], file_ignore_list: List[str]) -> str: +def process_file(py_file: str, func_ignore_prefix: List[str], file_ignore_list: List[str]) -> str: if os.path.basename(py_file) in file_ignore_list: LOGGER.debug(f"Skipping file: {py_file}") return "" @@ -69,7 +69,7 @@ def proccess_file(py_file: str, func_ignore_prefix: List[str], file_ignore_list: continue used = False - _func_grep_found = subprocess.check_output(f"git grep -w '{func.name}'", shell=True) + _func_grep_found = subprocess.check_output(["git", "grep", "-w", func.name], shell=False) for entry in _func_grep_found.decode().splitlines(): _, _line = entry.split(":", 1) @@ -124,7 +124,7 @@ def get_unused_functions( for py_file in all_python_files(): jobs.append( executor.submit( - proccess_file, + process_file, py_file=py_file, func_ignore_prefix=func_ignore_prefix, file_ignore_list=file_ignore_list, From cc939478d721c44b2de9968603808c4392d2dafb Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 13:54:26 +0200 Subject: [PATCH 4/9] use built-in types --- apps/jira_utils/jira_information.py | 34 +++++++++++++------------ apps/polarion/polarion_set_automated.py | 7 +++-- apps/polarion/polarion_utils.py | 19 +++++++------- apps/unused_code/unused_code.py | 10 +++++--- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/apps/jira_utils/jira_information.py b/apps/jira_utils/jira_information.py index 8919c9f..af4d736 100644 --- a/apps/jira_utils/jira_information.py +++ b/apps/jira_utils/jira_information.py @@ -1,10 +1,12 @@ +from __future__ import annotations + import concurrent.futures import logging import os import re import sys from functools import lru_cache -from typing import Any, Dict, List, Set, Tuple +from typing import Any import click from jira import JIRA, Issue, JIRAError @@ -26,7 +28,7 @@ def get_issue( return jira.issue(id=jira_id, fields="status, issuetype, fixVersions") -def get_jira_ids_from_file_content(file_content: str, issue_pattern: str, jira_url: str) -> Set[str]: +def get_jira_ids_from_file_content(file_content: str, issue_pattern: str, jira_url: str) -> set[str]: """ Try to find all Jira tickets in a given file content. @@ -52,7 +54,7 @@ def get_jira_ids_from_file_content(file_content: str, issue_pattern: str, jira_u return set(_pytest_jira_marker_bugs + _jira_id_arguments + _jira_url_jiras) -def get_jiras_from_python_files(issue_pattern: str, jira_url: str) -> Dict[str, Set[str]]: +def get_jiras_from_python_files(issue_pattern: str, jira_url: str) -> dict[str, set[str]]: """ Get all python files from the current directory and get list of jira ids from each of them @@ -65,7 +67,7 @@ def get_jiras_from_python_files(issue_pattern: str, jira_url: str) -> Dict[str, Note: any line containing would be not be checked for presence of a jira id """ - jira_found: Dict[str, Set[str]] = {} + jira_found: dict[str, set[str]] = {} for filename in all_python_files(): file_content = [] with open(filename) as fd: @@ -88,12 +90,12 @@ def get_jiras_from_python_files(issue_pattern: str, jira_url: str) -> Dict[str, def get_jira_information( jira_object: JIRA, jira_id: str, - skip_project_ids: List[str], - resolved_status: List[str], - jira_target_versions: List[str], + skip_project_ids: list[str], + resolved_status: list[str], + jira_target_versions: list[str], target_version_str: str, file_name: str, -) -> Tuple[str, str]: +) -> tuple[str, str]: jira_error_string = "" try: # check resolved status: @@ -130,11 +132,11 @@ def process_jira_command_line_config_file( url: str, token: str, issue_pattern: str, - resolved_statuses: List[str], + resolved_statuses: list[str], version_string_not_targeted_jiras: str, - target_versions: List[str], - skip_projects: List[str], -) -> Dict[str, Any]: + target_versions: list[str], + skip_projects: list[str], +) -> dict[str, Any]: # Process all the arguments passed from command line or config file or environment variable config_dict = get_util_config(util_name="pyutils-jira", config_file_path=config_file_path) url = url or config_dict.get("url", "") @@ -198,11 +200,11 @@ def process_jira_command_line_config_file( @click.option("--verbose", default=False, is_flag=True) def get_jira_mismatch( config_file_path: str, - target_versions: List[str], + target_versions: list[str], url: str, token: str, - skip_projects: List[str], - resolved_statuses: List[str], + skip_projects: list[str], + resolved_statuses: list[str], issue_pattern: str, version_string_not_targeted_jiras: str, verbose: bool, @@ -225,7 +227,7 @@ def get_jira_mismatch( ) jira_obj = JIRA(token_auth=jira_config_dict["token"], options={"server": jira_config_dict["url"]}) - jira_error: Dict[str, str] = {} + jira_error: dict[str, str] = {} if jira_id_dict := get_jiras_from_python_files( issue_pattern=jira_config_dict["issue_pattern"], jira_url=jira_config_dict["url"] diff --git a/apps/polarion/polarion_set_automated.py b/apps/polarion/polarion_set_automated.py index 920eddf..3003335 100644 --- a/apps/polarion/polarion_set_automated.py +++ b/apps/polarion/polarion_set_automated.py @@ -3,7 +3,6 @@ import logging import os import sys -from typing import Dict, List, Optional import click from simple_logger.logger import get_logger @@ -13,7 +12,7 @@ LOGGER = get_logger(name=__name__) -def approve_tests(polarion_project_id: str, added_ids: List[str]) -> Dict[str, List[str]]: +def approve_tests(polarion_project_id: str, added_ids: list[str]) -> dict[str, list[str]]: LOGGER.debug(f"Following polarion ids were added: {added_ids}") return update_polarion_ids( polarion_ids=list(added_ids), project_id=polarion_project_id, is_automated=True, is_approved=True @@ -21,8 +20,8 @@ def approve_tests(polarion_project_id: str, added_ids: List[str]) -> Dict[str, L def remove_approved_tests( - polarion_project_id: str, branch: str, added_ids: Optional[List[str]] = None -) -> Dict[str, List[str]]: + polarion_project_id: str, branch: str, added_ids: list[str] | None = None +) -> dict[str, list[str]]: removed_polarions = {} added_ids = added_ids or [] if removed_ids := set( diff --git a/apps/polarion/polarion_utils.py b/apps/polarion/polarion_utils.py index e29801f..af80745 100644 --- a/apps/polarion/polarion_utils.py +++ b/apps/polarion/polarion_utils.py @@ -4,7 +4,6 @@ import shlex import subprocess import sys -from typing import Dict, List from simple_logger.logger import get_logger @@ -21,8 +20,8 @@ def git_diff(branch: str) -> str: return data.decode() -def git_diff_lines(branch: str) -> Dict[str, List[str]]: - diff: Dict[str, List[str]] = {} +def git_diff_lines(branch: str) -> dict[str, list[str]]: + diff: dict[str, list[str]] = {} for line in git_diff(branch=branch).splitlines(): LOGGER.debug(line) if line.startswith("+"): @@ -33,10 +32,10 @@ def git_diff_lines(branch: str) -> Dict[str, List[str]]: def validate_polarion_requirements( - polarion_test_ids: List[str], + polarion_test_ids: list[str], polarion_project_id: str, -) -> List[str]: - tests_with_missing_requirements: List[str] = [] +) -> list[str]: + tests_with_missing_requirements: list[str] = [] if polarion_test_ids: from pylero.exceptions import PyleroLibException from pylero.work_item import Requirement, TestCase @@ -59,7 +58,7 @@ def validate_polarion_requirements( return tests_with_missing_requirements -def find_polarion_ids(polarion_project_id: str, string_to_match: str, branch: str) -> List[str]: +def find_polarion_ids(polarion_project_id: str, string_to_match: str, branch: str) -> list[str]: return re.findall( rf"pytest.mark.polarion.*({polarion_project_id}-[0-9]+)", "\n".join(git_diff_lines(branch=branch).get(string_to_match, [])), @@ -76,9 +75,9 @@ def get_polarion_project_id(util_name: str, config_file_path: str) -> str: def update_polarion_ids( - project_id: str, is_automated: bool, polarion_ids: List[str], is_approved: bool = False -) -> Dict[str, List[str]]: - updated_ids: Dict[str, List[str]] = {} + project_id: str, is_automated: bool, polarion_ids: list[str], is_approved: bool = False +) -> dict[str, list[str]]: + updated_ids: dict[str, list[str]] = {} if polarion_ids: automation_status = AUTOMATED if is_automated else NOT_AUTOMATED diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index b6aecd9..a778f54 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -1,10 +1,12 @@ +from __future__ import annotations + import ast import logging import os import subprocess import sys from concurrent.futures import Future, ThreadPoolExecutor, as_completed -from typing import Any, Iterable, List +from typing import Any, Iterable import click from simple_logger.logger import get_logger @@ -15,7 +17,7 @@ def is_fixture_autouse(func: ast.FunctionDef) -> bool: - deco_list: List[Any] = func.decorator_list + deco_list: list[Any] = func.decorator_list for deco in deco_list or []: if not hasattr(deco, "func"): continue @@ -40,7 +42,7 @@ def _iter_functions(tree: ast.Module) -> Iterable[ast.FunctionDef]: yield elm -def is_ignore_function_list(ignore_prefix_list: List[str], function: ast.FunctionDef) -> bool: +def is_ignore_function_list(ignore_prefix_list: list[str], function: ast.FunctionDef) -> bool: ignore_function_lists = [ function.name for ignore_prefix in ignore_prefix_list if function.name.startswith(ignore_prefix) ] @@ -51,7 +53,7 @@ def is_ignore_function_list(ignore_prefix_list: List[str], function: ast.Functio return False -def process_file(py_file: str, func_ignore_prefix: List[str], file_ignore_list: List[str]) -> str: +def process_file(py_file: str, func_ignore_prefix: list[str], file_ignore_list: list[str]) -> str: if os.path.basename(py_file) in file_ignore_list: LOGGER.debug(f"Skipping file: {py_file}") return "" From 2d38b6b62b6ccd57710a0a5f0e6ac6bbfdbf08cf Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 13:55:01 +0200 Subject: [PATCH 5/9] use built-in types --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d36bb75..6a6b93a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ preview = true line-length = 120 fix = true output-format = "grouped" -extend-select = ["I"] +lint.extend-select = ["I"] [tool.ruff.format] exclude = [".git", ".venv", ".mypy_cache", ".tox", "__pycache__"] From 86d91d09feffad7c6c5d91fe7d8c7ada250a1dd9 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 14:11:11 +0200 Subject: [PATCH 6/9] check that we run from git repositoyrt --- apps/unused_code/unused_code.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index a778f54..0178863 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -115,12 +115,15 @@ def get_unused_functions( ) -> None: LOGGER.setLevel(logging.DEBUG if verbose else logging.INFO) - _unused_functions = [] + unused_functions: list[str] = [] unused_code_config = get_util_config(util_name="pyutils-unusedcode", config_file_path=config_file_path) func_ignore_prefix = exclude_function_prefixes or unused_code_config.get("exclude_function_prefix", []) file_ignore_list = exclude_files or unused_code_config.get("exclude_files", []) jobs: list[Future] = [] + if not os.path.exists(".git"): + LOGGER.error("Must be run from a git repository") + sys.exit(1) with ThreadPoolExecutor() as executor: for py_file in all_python_files(): @@ -134,11 +137,12 @@ def get_unused_functions( ) for result in as_completed(jobs): - _unused_functions.append(result.result()) + if unused_func := result.result(): + unused_functions.append(unused_func) - if unused_functions := [_unused_func for _unused_func in _unused_functions if _unused_func]: - click.echo("\n".join(unused_functions)) - sys.exit(1) + if unused_functions: + click.echo("\n".join(unused_functions)) + sys.exit(1) if __name__ == "__main__": From 4901605e6085f346555e0681ae58286a56a03e2b Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 18:38:01 +0200 Subject: [PATCH 7/9] Remove commented line --- apps/unused_code/unused_code.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index 0178863..35623c5 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -147,5 +147,3 @@ def get_unused_functions( if __name__ == "__main__": get_unused_functions() - - # get_unused_functions() From c12ca32231ba0e418e899a6cc6747ffaa47f6845 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 19:02:10 +0200 Subject: [PATCH 8/9] remove deplicate debug log --- apps/unused_code/unused_code.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index 35623c5..d94f739 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -47,7 +47,6 @@ def is_ignore_function_list(ignore_prefix_list: list[str], function: ast.Functio function.name for ignore_prefix in ignore_prefix_list if function.name.startswith(ignore_prefix) ] if ignore_function_lists: - LOGGER.debug(f"Following functions are getting skipped: {ignore_function_lists}") return True return False From 02c8fc4754b6eb5690ca5e6e1a8e13a58d9e6f22 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Sun, 29 Dec 2024 19:34:30 +0200 Subject: [PATCH 9/9] State skip for `autouse` fixture in the log --- apps/unused_code/unused_code.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index d94f739..64a46a5 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -66,7 +66,7 @@ def process_file(py_file: str, func_ignore_prefix: list[str], file_ignore_list: continue if is_fixture_autouse(func=func): - LOGGER.debug(f"Skipping fixture function: {func.name}") + LOGGER.debug(f"Skipping `autouse` fixture function: {func.name}") continue used = False