Repository: halluxdev/hallux (language: python)

Issue:
Create pip module
https://packaging.python.org/en/latest/tutorials/packaging-projects/
Create pip module
https://packaging.python.org/en/latest/tutorials/packaging-projects/
Create pip module
https://packaging.python.org/en/latest/tutorials/packaging-projects/
Create pip module
https://packaging.python.org/en/latest/tutorials/packaging-projects/


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/hallux.yml b/.github/workflows/hallux.yml
index 939e4f8..a2af71c 100644
--- a/.github/workflows/hallux.yml
+++ b/.github/workflows/hallux.yml
@@ -24,16 +24,16 @@ jobs:
     - name: Unit-Tests
       run: |
         export PATH=$(pwd)/bin:$PATH
-        export PYTHONPATH=$(pwd)/src:${PYTHONPATH}
+        export PYTHONPATH=$(pwd)/hallux:${PYTHONPATH}
         python -m pytest \
           --cov-branch \
           --cov-report=term \
-          --cov=src \
+          --cov=hallux \
           --cov-report=xml \
           --cov-fail-under=65 \
           --junitxml xunit-reports/xunit-result-unit.xml \
           tests/unit \
-          tests/integration/hallux_fix_test.py         
+          tests/integration/hallux_fix_test.py
 
     - uses: sonarsource/sonarqube-scan-action@master
       env:
diff --git a/.gitignore b/.gitignore
index 50e3139..0e23ff9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,7 @@ Testing/
 venv/
 *.reconstructed
 __pycache__
-*/.pytest_cache/
+**/.pytest_cache/
 repos/
 data/
 .ruff_cache
@@ -22,3 +22,5 @@ htmlcov/
 dummy.json
 # this file is auto-generated
 src/__version__.py
+dist
+**/hallux.egg-info
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 0840efd..6921aa7 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -30,7 +30,10 @@
       "type": "python",
       "request": "launch",
       "program": "${file}",
-      "console": "integratedTerminal"
+      "console": "integratedTerminal",
+      "env": {
+        "PYTHONPATH": "/usr/local/lib/python3.11/site-packages/:$PYTHONPATH",
+      }
     }
   ]
 }
diff --git a/README.md b/README.md
index fbbbf0d..aeda93e 100644
--- a/README.md
+++ b/README.md
@@ -18,17 +18,25 @@ If you want `hallux` to propose you fixes and corrections directly into your Pul
 In order for `hallux` to understand your repo you need to provide `.hallux` configuration file, in the repo root folder.  
 For more command-line commands and just type `$ hallux` 
 
-## Folder structure
-* **bin** main hallux executable
-* **src** main source codes for hallux
-* **scripts** complimentary scripts for managing the repo
-* **tests** unit- and integration- tests for hallux 
 
 ## Installation
 
+```bash
+pip install hallux
+
+hallux
+```
+
+
+## Local development
+
 In order to setup Python virtual environment run `./scripts/setup-venv.sh`
 
 For activating environment run `cd /path/to/hallux && source activate.sh` 
 
-You might need to add `export PATH="/Path/to/hallux/bin:$PATH"` into your `~/.bashrc` or `~/.zshrc` file.
 
+## Folder structure
+* **bin** main hallux executable
+* **src** main source codes for hallux
+* **scripts** complimentary scripts for managing the repo
+* **tests** unit- and integration- tests for hallux 
diff --git a/activate.sh b/activate.sh
index 694313a..202d96a 100644
--- a/activate.sh
+++ b/activate.sh
@@ -8,6 +8,6 @@ export HALLUX_ROOT="${HALLUX_ROOT:-${PROJECT_DIR}}"
 
 source ${HALLUX_ROOT}/venv/bin/activate
 
-export PYTHONPATH="${HALLUX_ROOT}/src:${HALLUX_ROOT}/tests:${PYTHONPATH}"
+export PYTHONPATH="${HALLUX_ROOT}:${HALLUX_ROOT}/tests:${PYTHONPATH}"
 
 export PATH="${HALLUX_ROOT}/bin:${PATH}"
\ No newline at end of file
diff --git a/bin/hallux b/bin/hallux.sh
similarity index 83%
rename from bin/hallux
rename to bin/hallux.sh
index 40a276a..0f1f751 100755
--- a/bin/hallux
+++ b/bin/hallux.sh
@@ -1,5 +1,6 @@
 #!/usr/bin/env bash
 # Copyright: Hallux team, 2023
+# Developer version for local run
 
 SCRIPT_DIR=$(dirname "$0")
 HALLUX_ROOT="${SCRIPT_DIR}/.."
@@ -15,4 +16,4 @@ fi
 
 source ${HALLUX_ROOT}/activate.sh
 
-python3 ${HALLUX_ROOT}/src/hallux.py "$@"
+python3 ${HALLUX_ROOT}/hallux/main.py "$@"
diff --git a/hallux/VERSION b/hallux/VERSION
new file mode 100644
index 0000000..f5ca63c
--- /dev/null
+++ b/hallux/VERSION
@@ -0,0 +1,1 @@
+0.2.200
\ No newline at end of file
diff --git a/src/__init__.py b/hallux/__init__.py
similarity index 100%
rename from src/__init__.py
rename to hallux/__init__.py
diff --git a/src/auxilary.py b/hallux/auxilary.py
similarity index 100%
rename from src/auxilary.py
rename to hallux/auxilary.py
diff --git a/src/backends/dummy_backend.py b/hallux/backends/dummy_backend.py
similarity index 93%
rename from src/backends/dummy_backend.py
rename to hallux/backends/dummy_backend.py
index e0b1485..c2c9739 100644
--- a/src/backends/dummy_backend.py
+++ b/hallux/backends/dummy_backend.py
@@ -6,9 +6,9 @@
 import json
 from pathlib import Path
 
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
-from proposals.diff_proposal import DiffProposal
+from ..backends.query_backend import QueryBackend
+from ..issues.issue import IssueDescriptor
+from ..proposals.diff_proposal import DiffProposal
 
 
 class DummyBackend(QueryBackend):
diff --git a/src/backends/factory.py b/hallux/backends/factory.py
similarity index 92%
rename from src/backends/factory.py
rename to hallux/backends/factory.py
index 5400997..cec3687 100644
--- a/src/backends/factory.py
+++ b/hallux/backends/factory.py
@@ -4,10 +4,10 @@
 
 from pathlib import Path
 
-from auxilary import find_arg
-from backends.dummy_backend import DummyBackend
-from backends.openai_backend import OpenAiChatGPT, QueryBackend
-from backends.rest_backend import RestBackend
+from ..auxilary import find_arg
+from ..backends.dummy_backend import DummyBackend
+from ..backends.openai_backend import OpenAiChatGPT, QueryBackend
+from ..backends.rest_backend import RestBackend
 
 
 class BackendFactory:
diff --git a/src/backends/openai_backend.py b/hallux/backends/openai_backend.py
similarity index 94%
rename from src/backends/openai_backend.py
rename to hallux/backends/openai_backend.py
index 88f3993..f2bc63d 100644
--- a/src/backends/openai_backend.py
+++ b/hallux/backends/openai_backend.py
@@ -10,8 +10,8 @@
 import openai
 from openai.api_resources import ChatCompletion
 
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
+from ..backends.query_backend import QueryBackend
+from ..issues.issue import IssueDescriptor
 
 
 class OpenAiChatGPT(QueryBackend):
diff --git a/src/backends/query_backend.py b/hallux/backends/query_backend.py
similarity index 94%
rename from src/backends/query_backend.py
rename to hallux/backends/query_backend.py
index c28f3da..128aca2 100644
--- a/src/backends/query_backend.py
+++ b/hallux/backends/query_backend.py
@@ -6,7 +6,7 @@
 from pathlib import Path
 from typing import Final
 
-from issues.issue import IssueDescriptor
+from ..issues.issue import IssueDescriptor
 
 
 class QueryBackend(ABC):
diff --git a/src/backends/rest_backend.py b/hallux/backends/rest_backend.py
similarity index 95%
rename from src/backends/rest_backend.py
rename to hallux/backends/rest_backend.py
index e36021c..b49983c 100644
--- a/src/backends/rest_backend.py
+++ b/hallux/backends/rest_backend.py
@@ -9,8 +9,8 @@
 
 import requests
 
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
+from ..backends.query_backend import QueryBackend
+from ..issues.issue import IssueDescriptor
 
 
 class RestBackend(QueryBackend):
@@ -113,8 +113,7 @@ def query(self, request: str, issue: IssueDescriptor | None = None, issue_lines:
             self.headers.update({"Content-Type": "application/json"})
 
         elif self._is_string(self.request_body):
-            parsed_request = self.request_body.replace(
-                self.PROMPT_STRING, request)
+            parsed_request = self.request_body.replace(self.PROMPT_STRING, request)
             self.headers.update({"Content-Type": "text/plain"})
 
         else:
diff --git a/src/issues/issue.py b/hallux/issues/issue.py
similarity index 96%
rename from src/issues/issue.py
rename to hallux/issues/issue.py
index 35cb926..3d6d5be 100644
--- a/src/issues/issue.py
+++ b/hallux/issues/issue.py
@@ -5,7 +5,7 @@
 from abc import ABC, abstractmethod
 from typing import Final
 
-from proposals.proposal_engine import ProposalEngine
+from ..proposals.proposal_engine import ProposalEngine
 
 
 class IssueDescriptor(ABC):
diff --git a/src/hallux.py b/hallux/main.py
similarity index 91%
rename from src/hallux.py
rename to hallux/main.py
index 463e23d..6e0b5cc 100644
--- a/src/hallux.py
+++ b/hallux/main.py
@@ -10,26 +10,21 @@
 
 from __future__ import annotations
 
-import logging
 import sys
+import yaml
+import logging
+
 from pathlib import Path
 from typing import Any, Final
 
-import yaml
+from hallux.auxilary import find_arg
+from hallux.backends.factory import BackendFactory, QueryBackend
+from hallux.targets.diff import DiffTarget
+from hallux.targets.filesystem import FilesystemTarget
+from hallux.targets.git_commit import GitCommitTarget
+from hallux.targets.github_proposal import GithubProposalTraget
+from hallux.tools.factory import IssueSolver, ProcessorFactory
 
-from auxilary import find_arg
-from backends.factory import BackendFactory, QueryBackend
-from targets.diff_target import DiffTarget
-from targets.filesystem_target import FilesystemTarget
-from targets.git_commit_target import GitCommitTarget
-from targets.github_proposal_traget import GithubProposalTraget
-from tools.factory import IssueSolver, ProcessorFactory
-
-try:
-    from __version__ import version
-except ImportError:
-    with open(Path(__file__).resolve().parent.parent.joinpath("version.txt"), "rt") as f:
-        version = f.read().split("\n")[0] + ".DEVELOP"
 
 DEBUG: Final[bool] = False
 CONFIG_FILE: Final[str] = ".hallux"
@@ -76,7 +71,7 @@ def find_config(run_path: Path) -> tuple[dict, Path]:
 
     @staticmethod
     def print_usage():
-        print(f"Hallux v{version} - Convenient Coding Assistant")
+        print(f"Hallux v{get_version()} - Convenient Coding Assistant")
         print("USAGE: ")
         print("hallux [TARGET] [BACKEND] [PLUGINS] [OTHER] DIR")
         print()
@@ -138,12 +133,20 @@ def init_target(argv: list[str], config: dict | str, verbose: bool = False) -> D
         return FilesystemTarget()
 
 
-def main(argv: list[str], run_path: Path | None = None) -> int:
+def get_version():
+    with open(Path(__file__).parent / "VERSION") as version_file:
+        return version_file.read().strip()
+
+
+def main(argv: list[str] | None = None, run_path: Path | None = None) -> int:
     """
     :param argv: list of command-line arguments
     :param run_path: Path, from where main executable is running
     :return: error code or 0, if successful
     """
+    if argv is None:
+        argv = sys.argv
+
     verbose: bool = find_arg(argv, "--verbose") > 0 or find_arg(argv, "-v") > 0
     if verbose:
         logging.basicConfig(level=logging.DEBUG)
diff --git a/src/proposals/diff_proposal.py b/hallux/proposals/diff_proposal.py
similarity index 100%
rename from src/proposals/diff_proposal.py
rename to hallux/proposals/diff_proposal.py
diff --git a/src/proposals/proposal_engine.py b/hallux/proposals/proposal_engine.py
similarity index 97%
rename from src/proposals/proposal_engine.py
rename to hallux/proposals/proposal_engine.py
index fe333d7..dd41c82 100644
--- a/src/proposals/proposal_engine.py
+++ b/hallux/proposals/proposal_engine.py
@@ -4,7 +4,7 @@
 from abc import ABC, abstractmethod
 from typing import Final
 
-from proposals.diff_proposal import DiffProposal
+from .diff_proposal import DiffProposal
 
 
 class ProposalEngine(ABC):
diff --git a/src/proposals/python_proposal.py b/hallux/proposals/python_proposal.py
similarity index 91%
rename from src/proposals/python_proposal.py
rename to hallux/proposals/python_proposal.py
index 05a5e1d..51c2499 100644
--- a/src/proposals/python_proposal.py
+++ b/hallux/proposals/python_proposal.py
@@ -5,15 +5,16 @@
 import ast
 import copy
 
-from issues.issue import IssueDescriptor
-from proposals.simple_proposal import SimpleProposal
+from ..issues.issue import IssueDescriptor
+from .simple_proposal import SimpleProposal
 
 
 class PythonProposal(SimpleProposal):
     def __init__(
         self,
         issue: IssueDescriptor,
-        radius_or_range: int | tuple[int, int] = 4,  # radius or tuple with [start_line, end_line]
+        # radius or tuple with [start_line, end_line]
+        radius_or_range: int | tuple[int, int] = 4,
         issue_line_comment: str | None = None,
         extract_function: bool = False,
     ):
diff --git a/src/proposals/simple_proposal.py b/hallux/proposals/simple_proposal.py
similarity index 95%
rename from src/proposals/simple_proposal.py
rename to hallux/proposals/simple_proposal.py
index 6fb5e52..c337ecb 100644
--- a/src/proposals/simple_proposal.py
+++ b/hallux/proposals/simple_proposal.py
@@ -6,10 +6,10 @@
 import difflib
 from typing import Final
 
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
-from proposals.diff_proposal import DiffProposal
-from targets.diff_target import DiffTarget
+from ..backends.query_backend import QueryBackend
+from ..issues.issue import IssueDescriptor
+from .diff_proposal import DiffProposal
+from ..targets.diff import DiffTarget
 
 
 # Struct to keep all relevant info about found code fix in one place
@@ -17,7 +17,8 @@ class SimpleProposal(DiffProposal):
     def __init__(
         self,
         issue: IssueDescriptor,
-        radius_or_range: int | tuple[int, int] | None = None,  # radius or tuple with [start_line, end_line]
+        # radius or tuple with [start_line, end_line]
+        radius_or_range: int | tuple[int, int] | None = None,
         issue_line_comment: str | None = None,
     ):
         """
@@ -92,7 +93,8 @@ def _merge_lines(self, proposed_lines: list[str]) -> bool:
             proposed_lines = proposed_lines[1:-1]  # remove first and last line
             if proposed_lines[-1].startswith("```"):
                 # if new last line is still ``` (this happens if there was "\n" after ```)
-                proposed_lines = proposed_lines[:-1]  # remove last line once again
+                # remove last line once again
+                proposed_lines = proposed_lines[:-1]
 
             # remove issue_line_comment if it was added
         issue_line_found: int | None = None
diff --git a/src/targets/diff_target.py b/hallux/targets/diff.py
similarity index 96%
rename from src/targets/diff_target.py
rename to hallux/targets/diff.py
index 9cd5b00..4665151 100644
--- a/src/targets/diff_target.py
+++ b/hallux/targets/diff.py
@@ -11,7 +11,7 @@
 
 from abc import ABC, abstractmethod
 
-from proposals.diff_proposal import DiffProposal
+from ..proposals.diff_proposal import DiffProposal
 
 
 # Interface for DiffTarget implementations
diff --git a/src/targets/filesystem_target.py b/hallux/targets/filesystem.py
similarity index 94%
rename from src/targets/filesystem_target.py
rename to hallux/targets/filesystem.py
index b0a25da..e4a601f 100644
--- a/src/targets/filesystem_target.py
+++ b/hallux/targets/filesystem.py
@@ -4,9 +4,9 @@
 
 from pathlib import Path
 
-from auxilary import set_directory
-from proposals.diff_proposal import DiffProposal
-from targets.diff_target import DiffTarget
+from ..auxilary import set_directory
+from ..proposals.diff_proposal import DiffProposal
+from .diff import DiffTarget
 
 
 # Saves diff-proposals directly into local filesystem
diff --git a/src/targets/git_commit_target.py b/hallux/targets/git_commit.py
similarity index 95%
rename from src/targets/git_commit_target.py
rename to hallux/targets/git_commit.py
index e3e6255..45f416d 100644
--- a/src/targets/git_commit_target.py
+++ b/hallux/targets/git_commit.py
@@ -7,8 +7,8 @@
 import subprocess
 from pathlib import Path
 
-from proposals.diff_proposal import DiffProposal
-from targets.filesystem_target import FilesystemTarget
+from ..proposals.diff_proposal import DiffProposal
+from .filesystem import FilesystemTarget
 
 
 class GitCommitTarget(FilesystemTarget):
diff --git a/src/targets/github_proposal_traget.py b/hallux/targets/github_proposal.py
similarity index 97%
rename from src/targets/github_proposal_traget.py
rename to hallux/targets/github_proposal.py
index 944a796..298c091 100644
--- a/src/targets/github_proposal_traget.py
+++ b/hallux/targets/github_proposal.py
@@ -7,8 +7,8 @@
 
 from github import Github, GithubException, PullRequest, Repository
 
-from proposals.diff_proposal import DiffProposal
-from targets.filesystem_target import FilesystemTarget
+from ..proposals.diff_proposal import DiffProposal
+from .filesystem import FilesystemTarget
 
 
 # Saves Issue Fixes as Github proposals
diff --git a/src/tools/cpp/cpp.py b/hallux/tools/cpp/cpp.py
similarity index 94%
rename from src/tools/cpp/cpp.py
rename to hallux/tools/cpp/cpp.py
index 4db995e..8865050 100644
--- a/src/tools/cpp/cpp.py
+++ b/hallux/tools/cpp/cpp.py
@@ -10,11 +10,11 @@
 from pathlib import Path
 from typing import Final
 
-from auxilary import set_directory
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
-from targets.diff_target import DiffTarget
-from tools.cpp.make_target_solver import IssueSolver, MakeTargetSolver
+from ...auxilary import set_directory
+from ...backends.query_backend import QueryBackend
+from ...issues.issue import IssueDescriptor
+from ...targets.diff import DiffTarget
+from .make_target_solver import IssueSolver, MakeTargetSolver
 
 
 @dataclass
diff --git a/src/tools/cpp/issue.py b/hallux/tools/cpp/issue.py
similarity index 93%
rename from src/tools/cpp/issue.py
rename to hallux/tools/cpp/issue.py
index b5df856..cea5c1c 100644
--- a/src/tools/cpp/issue.py
+++ b/hallux/tools/cpp/issue.py
@@ -4,9 +4,9 @@
 
 from pathlib import Path
 
-from issues.issue import IssueDescriptor
-from proposals.proposal_engine import ProposalEngine, ProposalList
-from proposals.simple_proposal import SimpleProposal
+from ...issues.issue import IssueDescriptor
+from ...proposals.proposal_engine import ProposalEngine, ProposalList
+from ...proposals.simple_proposal import SimpleProposal
 
 
 class CppIssue(IssueDescriptor):
diff --git a/src/tools/cpp/make_target_solver.py b/hallux/tools/cpp/make_target_solver.py
similarity index 82%
rename from src/tools/cpp/make_target_solver.py
rename to hallux/tools/cpp/make_target_solver.py
index dfac80c..ed58be5 100644
--- a/src/tools/cpp/make_target_solver.py
+++ b/hallux/tools/cpp/make_target_solver.py
@@ -7,12 +7,12 @@
 from pathlib import Path
 from typing import Final
 
-from auxilary import set_directory
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
-from targets.diff_target import DiffTarget
-from tools.cpp.issue import CppIssue
-from tools.issue_solver import IssueSolver
+from ...auxilary import set_directory
+from ...backends.query_backend import QueryBackend
+from ...issues.issue import IssueDescriptor
+from ...targets.diff import DiffTarget
+from ...tools.cpp.issue import CppIssue
+from ...tools.issue_solver import IssueSolver
 
 
 class MakeTargetSolver(IssueSolver):
diff --git a/src/tools/factory.py b/hallux/tools/factory.py
similarity index 86%
rename from src/tools/factory.py
rename to hallux/tools/factory.py
index 288332f..cbe19ce 100644
--- a/src/tools/factory.py
+++ b/hallux/tools/factory.py
@@ -4,12 +4,12 @@
 
 from pathlib import Path
 
-from auxilary import find_arg
-from tools.cpp.cpp import Cpp_IssueSolver
-from tools.issue_solver import IssueSolver
-from tools.mypy.solver import Mypy_IssueSolver
-from tools.ruff.solver import Ruff_IssueSolver
-from tools.sonarqube.solver import Sonar_IssueSolver
+from ..auxilary import find_arg
+from ..tools.cpp.cpp import Cpp_IssueSolver
+from ..tools.issue_solver import IssueSolver
+from ..tools.mypy.solver import Mypy_IssueSolver
+from ..tools.ruff.solver import Ruff_IssueSolver
+from ..tools.sonarqube.solver import Sonar_IssueSolver
 
 
 class ProcessorFactory:
diff --git a/src/tools/issue_solver.py b/hallux/tools/issue_solver.py
similarity index 95%
rename from src/tools/issue_solver.py
rename to hallux/tools/issue_solver.py
index 8aabc19..ddea4ad 100644
--- a/src/tools/issue_solver.py
+++ b/hallux/tools/issue_solver.py
@@ -8,11 +8,11 @@
 from pathlib import Path
 from typing import Final
 
-from auxilary import set_directory
-from backends.query_backend import QueryBackend
-from issues.issue import IssueDescriptor
-from proposals.diff_proposal import DiffProposal
-from targets.diff_target import DiffTarget
+from ..auxilary import set_directory
+from ..backends.query_backend import QueryBackend
+from ..issues.issue import IssueDescriptor
+from ..proposals.diff_proposal import DiffProposal
+from ..targets.diff import DiffTarget
 
 
 class IssueSolver(ABC):
diff --git a/src/tools/mypy/solver.py b/hallux/tools/mypy/solver.py
similarity index 86%
rename from src/tools/mypy/solver.py
rename to hallux/tools/mypy/solver.py
index a605e84..f6e35f6 100644
--- a/src/tools/mypy/solver.py
+++ b/hallux/tools/mypy/solver.py
@@ -5,10 +5,10 @@
 import subprocess
 from pathlib import Path
 
-from auxilary import set_directory
-from issues.issue import IssueDescriptor
-from tools.issue_solver import IssueSolver
-from tools.python.python_issue import PythonIssue
+from ...auxilary import set_directory
+from ...issues.issue import IssueDescriptor
+from ...tools.issue_solver import IssueSolver
+from ...tools.python.python_issue import PythonIssue
 
 
 class Mypy_IssueSolver(IssueSolver):
diff --git a/src/tools/python/python_issue.py b/hallux/tools/python/python_issue.py
similarity index 91%
rename from src/tools/python/python_issue.py
rename to hallux/tools/python/python_issue.py
index d5d417c..b84dfcf 100644
--- a/src/tools/python/python_issue.py
+++ b/hallux/tools/python/python_issue.py
@@ -2,9 +2,9 @@
 
 from __future__ import annotations
 
-from issues.issue import IssueDescriptor
-from proposals.proposal_engine import ProposalEngine, ProposalList
-from proposals.python_proposal import PythonProposal
+from ...issues.issue import IssueDescriptor
+from ...proposals.proposal_engine import ProposalEngine, ProposalList
+from ...proposals.python_proposal import PythonProposal
 
 
 class PythonIssue(IssueDescriptor):
diff --git a/src/tools/ruff/solver.py b/hallux/tools/ruff/solver.py
similarity index 86%
rename from src/tools/ruff/solver.py
rename to hallux/tools/ruff/solver.py
index 514cf24..dd42b92 100644
--- a/src/tools/ruff/solver.py
+++ b/hallux/tools/ruff/solver.py
@@ -5,10 +5,10 @@
 import subprocess
 from pathlib import Path
 
-from auxilary import set_directory
-from issues.issue import IssueDescriptor
-from tools.issue_solver import IssueSolver
-from tools.python.python_issue import PythonIssue
+from ...auxilary import set_directory
+from ...issues.issue import IssueDescriptor
+from ..issue_solver import IssueSolver
+from ..python.python_issue import PythonIssue
 
 
 class Ruff_IssueSolver(IssueSolver):
diff --git a/src/tools/sonarqube/issue.py b/hallux/tools/sonarqube/issue.py
similarity index 92%
rename from src/tools/sonarqube/issue.py
rename to hallux/tools/sonarqube/issue.py
index 322044c..13b1af5 100644
--- a/src/tools/sonarqube/issue.py
+++ b/hallux/tools/sonarqube/issue.py
@@ -4,10 +4,10 @@
 
 import json
 
-from issues.issue import IssueDescriptor
-from proposals.proposal_engine import ProposalEngine, ProposalList
-from proposals.python_proposal import PythonProposal
-from proposals.simple_proposal import SimpleProposal
+from ...issues.issue import IssueDescriptor
+from ...proposals.proposal_engine import ProposalEngine, ProposalList
+from ...proposals.python_proposal import PythonProposal
+from ...proposals.simple_proposal import SimpleProposal
 
 
 class SonarIssue(IssueDescriptor):
diff --git a/src/tools/sonarqube/solver.py b/hallux/tools/sonarqube/solver.py
similarity index 93%
rename from src/tools/sonarqube/solver.py
rename to hallux/tools/sonarqube/solver.py
index 06beaf6..c348472 100644
--- a/src/tools/sonarqube/solver.py
+++ b/hallux/tools/sonarqube/solver.py
@@ -8,10 +8,10 @@
 
 import requests
 
-from backends.query_backend import QueryBackend
-from targets.diff_target import DiffTarget
-from tools.issue_solver import IssueSolver
-from tools.sonarqube.issue import IssueDescriptor, SonarIssue
+from ...backends.query_backend import QueryBackend
+from ...targets.diff import DiffTarget
+from ..issue_solver import IssueSolver
+from .issue import IssueDescriptor, SonarIssue
 
 
 class OverrideQueryBackend(QueryBackend):
diff --git a/pyproject.toml b/pyproject.toml
index 7638074..ff4b876 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,10 +1,117 @@
-[tool.black]
-line_length = 120
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "hallux"
+dynamic = ["version"]
+authors = [
+  { name="Hallux Team", email="team@hallux.dev" },
+]
+description = "Fixing project issues automagically with AI."
+readme = "README.md"
+license = {file = "LICENSE.txt"}
+requires-python = ">=3.8, <4.0"
+
+classifiers = [
+  "Development Status :: 4 - Beta",
+  "Programming Language :: Python :: 3.8",
+  "Programming Language :: Python :: 3.9",
+  "Programming Language :: Python :: 3.10",
+  "Programming Language :: Python :: 3.11",
+  "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
+  "Topic :: Scientific/Engineering :: Artificial Intelligence",
+]
+
+dependencies = [
+  'openai==0.27.8',
+  'pyyaml==6.0',
+  'types-PyYAML==6.0.12.11',
+  'PyGithub==1.59',
+]
+
+[project.optional-dependencies]
+test = [
+  'mypy==1.4.1',
+  'black==23.3.0',
+  'ruff==0.0.272',
+  'pytest >= 7.3.1',
+  'pytest-cov==4.1.0',
+  'isort==5.12.0',
+  'wheel==0.40.0',
+  'pyinstaller==5.13.0',
+]
+
+[tool.setuptools.dynamic]
+version = {file = "hallux/VERSION"}
+
+[project.scripts]
+hallux = 'hallux.main:main'
+
+[project.urls]
+"Homepage" = "https://github.com/halluxdev/hallux"
+"Bug Tracker" = "https://github.com/halluxdev/hallux/issues"
+
 
 [tool.ruff]
-# Same as Black.
+select = ["F", "E", "W", "I001"]
+line-length = 120
+show-fixes = false
+target-version = "py311"
+task-tags = ["TODO", "FIXME"]
+exclude = [
+    "tests/test-python-project",
+    ".git",
+    ".ruff_cache",
+    ".scannerwork",
+    ".vscode",
+    ".venv",
+    "__pypackages__",
+    "_build",
+    "buck-out",
+    "build",
+    "htmlcov",
+    "dist",
+    "node_modules",
+    "venv",
+    "scripts",
+]
+
+
+[tool.ruff.isort]
+known-first-party = []
+known-third-party = []
+section-order = [
+    "future",
+    "standard-library",
+    "third-party",
+    "first-party",
+    "local-folder",
+]
+combine-as-imports = true
+split-on-trailing-comma = false
+lines-between-types = 1
+
+[tool.black]
 line-length = 120
-exclude = ["tests/test-python-project"]
+target-version = ["py311"]
+include = '\.pyi?$'
+exclude = '''
+(
+  /(
+      \.direnv
+    | \.eggs
+    | \.git
+    | \.tox
+    | \.venv
+    | _build
+    | build
+    | dist
+    | venv
+  )/
+)
+'''
+
 
 [tool.isort]
 line_length = 120
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 8f917f5..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[metadata]
-license_files = LICENSE.txt
\ No newline at end of file
diff --git a/setup.py b/setup.py
deleted file mode 100644
index cac6a29..0000000
--- a/setup.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from __future__ import annotations
-
-import os
-import pathlib
-
-from setuptools import setup
-
-here = pathlib.Path(__file__).parent.resolve()
-
-
-def get_version() -> str:
-    # check auto-genertated file for latest version
-    version_py = here / "bin/__version__.py"
-    if version_py.exists():
-        with open(version_py) as fp:
-            for line in fp.read().splitlines():
-                if line.startswith("version"):
-                    delim = '"' if '"' in line else "'"
-                    return line.split(delim)[1]
-
-    # check env variable
-    version_env: str | None = os.environ.get("HALLUX_VERSION", None)
-    if version_env is not None:
-        return version_env
-
-    return "DEVELOP"
-
-
-# Get the long description from the README file
-long_description = (here / "README.md").read_text(encoding="utf-8")
-
-setup(
-    name="hallux",
-    version=get_version(),
-    description="Convenient Coding Assistant.",
-    long_description=long_description,
-    long_description_content_type="text/markdown",
-    url="https://github.com/halluxdev/hallux",
-    project_urls={
-        "Documentation": "https://hallux.dev/doc",
-    },
-    author="Hallux.Dev Team",
-    author_email="sergey@hallux.dev",
-    license="PRIVARE",
-    classifiers=[
-        "Development Status :: 3 - Alpha",
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: MIT License",
-        "Topic :: Software Development :: Build Tools",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-        "Programming Language :: Python :: 3.9",
-        "Programming Language :: Python :: 3.10",
-        "Programming Language :: Python :: 3.11",
-        "Programming Language :: Python :: 3.12",
-    ],
-    package_dir={"": "bin"},
-    install_requires=["ruff", "mypy", "openai", "pyyaml", "PyGithub"],
-    entry_points={
-        "console_scripts": [
-            "hallux=hallux:main",
-        ],
-    },
-    zip_safe=False,
-    python_requires=">=3.7",
-)
diff --git a/sonar-project.properties b/sonar-project.properties
index 4ebcc3f..c87c89d 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -2,5 +2,5 @@ sonar.projectKey=halluxdev_hallux_AYpIk3Z__hwOMJbIE7XQ
 sonar.python.version=3.9
 sonar.python.pylint.reportPaths=pylint.report
 sonar.python.coverage.reportPaths=coverage.xml
-sonar.sources=src
+sonar.sources=hallux
 sonar.tests=tests
diff --git a/version.txt b/version.txt
deleted file mode 100644
index 2f45361..0000000
--- a/version.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-0.2
\ No newline at end of file


Test patch:
diff --git a/real-openai-test.sh b/real-openai-test.sh
index 580b1e6..9e9128c 100755
--- a/real-openai-test.sh
+++ b/real-openai-test.sh
@@ -6,4 +6,4 @@ python -m pytest -v --real-openai-test  tests/integration/hallux_fix_test.py
 
 ./scripts/sonar-scanner.sh
 
-python src/hallux.py --openai --sonar --git bin
+python hallux/main.py --openai --sonar --git bin
diff --git a/tests/integration/hallux_fix_test.py b/tests/integration/hallux_fix_test.py
index e61bc2e..c52c14b 100644
--- a/tests/integration/hallux_fix_test.py
+++ b/tests/integration/hallux_fix_test.py
@@ -11,8 +11,8 @@
 import pytest
 from utils import hallux_tmp_dir
 
-from auxilary import set_directory
-from hallux import main
+from hallux.auxilary import set_directory
+from hallux.main import main
 
 
 def test_hallux_cpp(
@@ -32,7 +32,8 @@ def test_hallux_cpp(
     proj_dir = Path(__file__).resolve().parent.parent.joinpath(proj_name)
 
     # copy reference project into temp folder
-    shutil.copytree(str(proj_dir), tmp_proj_dir, ignore_dangling_symlinks=False, dirs_exist_ok=True)
+    shutil.copytree(str(proj_dir), tmp_proj_dir,
+                    ignore_dangling_symlinks=False, dirs_exist_ok=True)
 
     # another temporal dir for cmake init
     cmake_tmp_dir = hallux_tmp_dir()
@@ -46,7 +47,8 @@ def test_hallux_cpp(
 
         make_succesfull: bool = True
         try:
-            subprocess.check_output(["make", "cpp/test_cpp_project.o"], stderr=subprocess.DEVNULL)
+            subprocess.check_output(
+                ["make", "cpp/test_cpp_project.o"], stderr=subprocess.DEVNULL)
         except subprocess.CalledProcessError as e:
             make_succesfull = False
             returncode = e.returncode
@@ -74,7 +76,8 @@ def test_hallux_cpp(
     # ASSERT: must be no remaining c++ compilation issues
     with set_directory(cmake_tmp_dir):
         try:
-            subprocess.check_output(["make", "cpp/test_cpp_project.o"], stderr=subprocess.DEVNULL)
+            subprocess.check_output(
+                ["make", "cpp/test_cpp_project.o"], stderr=subprocess.DEVNULL)
         except subprocess.CalledProcessError as e:
             pytest.fail(e, pytrace=True)  # make must not find any issues
 
@@ -96,7 +99,8 @@ def test_hallux_python(
     proj_dir = Path(__file__).resolve().parent.parent.joinpath(proj_name)
 
     # copy reference project into temp folder
-    shutil.copytree(str(proj_dir), tmp_proj_dir, ignore_dangling_symlinks=False, dirs_exist_ok=True)
+    shutil.copytree(str(proj_dir), tmp_proj_dir,
+                    ignore_dangling_symlinks=False, dirs_exist_ok=True)
 
     # check that temporal project has ruff issues
     with set_directory(tmp_proj_dir):
diff --git a/tests/integration/hallux_github_test.py b/tests/integration/hallux_github_test.py
index 3e39569..0d8005c 100644
--- a/tests/integration/hallux_github_test.py
+++ b/tests/integration/hallux_github_test.py
@@ -14,9 +14,9 @@
 import pytest
 from github import Github, PullRequest, Repository
 
-from auxilary import set_directory
-from hallux import main
-from targets.github_proposal_traget import GithubProposalTraget
+from hallux.auxilary import set_directory
+from hallux.main import main
+from hallux.targets.github_proposal import GithubProposalTraget
 
 GITHUB_PULLREQUEST_URL = "https://github.com/halluxdev/hallux/pull/26"
 
@@ -37,7 +37,8 @@ def test_hallux_github(tmp_proj_dir: str | None = None):
     hallux_git_dir = Path(__file__).resolve().parent.parent.parent
     assert hallux_git_dir.joinpath(".git").exists()
 
-    base_url, repo_name, pr_id = GithubProposalTraget.parse_pr_url(GITHUB_PULLREQUEST_URL)
+    base_url, repo_name, pr_id = GithubProposalTraget.parse_pr_url(
+        GITHUB_PULLREQUEST_URL)
     assert base_url == "https://api.github.com"
     assert repo_name == "halluxdev/hallux"
     assert pr_id == 26
@@ -60,23 +61,28 @@ def test_hallux_github(tmp_proj_dir: str | None = None):
     # re-calculate comments_count
     initial_comments_count: Final[int] = pull_request.get_comments().totalCount
 
-    shutil.copytree(str(hallux_git_dir), tmp_proj_dir, ignore_dangling_symlinks=False, dirs_exist_ok=True)
+    shutil.copytree(str(hallux_git_dir), tmp_proj_dir,
+                    ignore_dangling_symlinks=False, dirs_exist_ok=True)
     with set_directory(Path(tmp_proj_dir)):
         try:
             subprocess.check_output(["git", "reset", "--hard"])
-            subprocess.check_output(["git", "fetch", "origin", CORRESPONDING_COMMIT_SHA])
-            subprocess.check_output(["git", "checkout", CORRESPONDING_COMMIT_SHA])
+            subprocess.check_output(
+                ["git", "fetch", "origin", CORRESPONDING_COMMIT_SHA])
+            subprocess.check_output(
+                ["git", "checkout", CORRESPONDING_COMMIT_SHA])
         except subprocess.CalledProcessError as e:
             pytest.fail(e, pytrace=True)  # Cannot checkout PR commit
 
         try:
-            main(["hallux", "--cache", "--python", "--github", GITHUB_PULLREQUEST_URL, "."])
+            main(["hallux", "--cache", "--python",
+                 "--github", GITHUB_PULLREQUEST_URL, "."])
         except Exception as e:
             pytest.fail(
                 e, pytrace=True
             )  # Fail during running `hallux --python --github https://github.com/halluxai/hallux/pull/26 .`
 
-    processed_comments_count: Final[int] = pull_request.get_comments().totalCount
+    processed_comments_count: Final[int] = pull_request.get_comments(
+    ).totalCount
 
     assert processed_comments_count > initial_comments_count
 
diff --git a/tests/unit/auxilary_test.py b/tests/unit/auxilary_test.py
index a9ae4fe..f9b6a6a 100644
--- a/tests/unit/auxilary_test.py
+++ b/tests/unit/auxilary_test.py
@@ -8,7 +8,7 @@
 
 import pytest
 
-from auxilary import Path, find_arg, set_directory
+from hallux.auxilary import Path, find_arg, set_directory
 
 
 @pytest.mark.parametrize(
diff --git a/tests/unit/backends/dummy_backend_test.py b/tests/unit/backends/dummy_backend_test.py
index 5f1108a..bcb9774 100644
--- a/tests/unit/backends/dummy_backend_test.py
+++ b/tests/unit/backends/dummy_backend_test.py
@@ -8,8 +8,8 @@
 import pytest
 from unit.common.testing_issue import TestingIssue
 
-from backends.dummy_backend import DummyBackend
-from proposals.diff_proposal import DiffProposal
+from hallux.backends.dummy_backend import DummyBackend
+from hallux.proposals.diff_proposal import DiffProposal
 
 
 class TestDummyBackend:
@@ -17,7 +17,8 @@ class TestDummyBackend:
     def setup_dummy_backend(self):
         filename = tempfile.mktemp(suffix=".json", prefix="/tmp/")
         self.base_path = Path(__file__).resolve().parent
-        self.test_filename = str(self.base_path.joinpath("dummy_backend_test.txt"))
+        self.test_filename = str(
+            self.base_path.joinpath("dummy_backend_test.txt"))
         with open(filename, "wt") as file:
             json.dump(
                 {
@@ -37,7 +38,8 @@ def test_init(self, setup_dummy_backend):
         }
 
     def test_query(self, setup_dummy_backend):
-        issue = TestingIssue(language="python", tool="tool1", filename=self.test_filename, description="issue1")
+        issue = TestingIssue(language="python", tool="tool1",
+                             filename=self.test_filename, description="issue1")
         result = setup_dummy_backend.query("request", issue, ["something"])
         assert result == []
 
@@ -46,17 +48,20 @@ def test_query_no_issue(self, setup_dummy_backend):
         assert result == []
 
     def test_query_no_match(self, setup_dummy_backend):
-        issue = TestingIssue(language="python", tool="tool1", filename=self.test_filename, description="issue3")
+        issue = TestingIssue(language="python", tool="tool1",
+                             filename=self.test_filename, description="issue3")
         result = setup_dummy_backend.query("request", issue)
         assert result == []
 
     def test_query_no_language(self, setup_dummy_backend):
-        issue = TestingIssue(language="", tool="tool1", filename=self.test_filename, description="issue1")
+        issue = TestingIssue(language="", tool="tool1",
+                             filename=self.test_filename, description="issue1")
         result = setup_dummy_backend.query("request", issue)
         assert result == []
 
     def test_query_no_tool(self, setup_dummy_backend):
-        issue = TestingIssue(language="cpp", tool="newTool", filename=self.test_filename, description="issue1")
+        issue = TestingIssue(language="cpp", tool="newTool",
+                             filename=self.test_filename, description="issue1")
         result = setup_dummy_backend.query("request", issue)
         assert result == []
 
@@ -71,7 +76,8 @@ def test_report_succesfull_fix():
     assert not root_path.joinpath(dummy_json).exists()
     dummy_backend = DummyBackend(dummy_json, base_path=root_path)
     base_path = Path(__file__).resolve().parent
-    issue = TestingIssue(language="cpp", tool="newTool", filename="file1.py", description="issue1", base_path=base_path)
+    issue = TestingIssue(language="cpp", tool="newTool",
+                         filename="file1.py", description="issue1", base_path=base_path)
     proposal = Mock(spec=DiffProposal)
     proposal.issue_lines = ["aaa"]
     proposal.proposed_lines = ["bbb"]
diff --git a/tests/unit/backends/open_ai_test.py b/tests/unit/backends/open_ai_test.py
index 06cb8c2..8fa8f90 100644
--- a/tests/unit/backends/open_ai_test.py
+++ b/tests/unit/backends/open_ai_test.py
@@ -3,8 +3,7 @@
 
 import pytest
 from unit.common.testing_issue import TestingIssue
-
-from backends.openai_backend import OpenAiChatGPT
+from hallux.backends.openai_backend import OpenAiChatGPT
 
 
 class TestOpenAiChatGPT:
@@ -24,6 +23,7 @@ def test_query(self, mock_create, setup_openai_chat_gpt):
             ]
         }
 
-        issue = TestingIssue(language="en", tool="tool1", filename="file1", description="issue1")
+        issue = TestingIssue(language="en", tool="tool1",
+                             filename="file1", description="issue1")
         result = setup_openai_chat_gpt.query("request", issue)
         assert result == ["answer1", "answer2"]
diff --git a/tests/unit/backends/rest_backend_test.py b/tests/unit/backends/rest_backend_test.py
index 8f08324..9914aa9 100644
--- a/tests/unit/backends/rest_backend_test.py
+++ b/tests/unit/backends/rest_backend_test.py
@@ -3,8 +3,7 @@
 
 import pytest
 from unit.common.testing_issue import TestingIssue
-
-from backends.rest_backend import RestBackend
+from hallux.backends.rest_backend import RestBackend
 
 
 class TestRestBackend:
diff --git a/tests/unit/common/testing_issue.py b/tests/unit/common/testing_issue.py
index c846677..0c77d23 100644
--- a/tests/unit/common/testing_issue.py
+++ b/tests/unit/common/testing_issue.py
@@ -6,7 +6,7 @@
 from pathlib import Path
 from typing import Final
 
-from issues.issue import IssueDescriptor
+from hallux.issues.issue import IssueDescriptor
 
 
 class TestingIssue(IssueDescriptor):
@@ -20,11 +20,13 @@ def __init__(
         language: str | None = None,
         base_path: Path | None = None,
     ):
-        self.base_path: Final[Path] = base_path if base_path is not None else Path(__file__).resolve().parent
+        self.base_path: Final[Path] = base_path if base_path is not None else Path(
+            __file__).resolve().parent
         test_file = self.base_path.joinpath(filename)
 
         # By-default contain absolute full-path, but can contain relative name too, if base_path provided
-        testing_filename: str = str(test_file) if base_path is None else filename
+        testing_filename: str = str(
+            test_file) if base_path is None else filename
 
         super().__init__(
             tool=tool,
diff --git a/tests/unit/hallux_test.py b/tests/unit/hallux_test.py
index 269dc5d..7eb14e9 100644
--- a/tests/unit/hallux_test.py
+++ b/tests/unit/hallux_test.py
@@ -9,12 +9,12 @@
 
 import yaml
 
-from auxilary import set_directory
-from hallux import CONFIG_FILE, Hallux, main
+from hallux.auxilary import set_directory
+from hallux.main import CONFIG_FILE, Hallux, main
 
 
 @patch("builtins.print")
-def test_Hallux_main(mock_print):
+def test_hallux_main(mock_print):
     # prints usage, and quits
     out_val: int = main([])
     assert out_val == 0
diff --git a/tests/unit/proposals/python_proposal_test.py b/tests/unit/proposals/python_proposal_test.py
index 1661302..2142303 100644
--- a/tests/unit/proposals/python_proposal_test.py
+++ b/tests/unit/proposals/python_proposal_test.py
@@ -8,7 +8,7 @@
 
 from unit.common.testing_issue import TestingIssue
 
-from proposals.python_proposal import PythonProposal
+from hallux.proposals.python_proposal import PythonProposal
 
 
 def test_python_proposal():
@@ -17,12 +17,15 @@ def test_python_proposal():
     print("B")  # This is THE line
     print("C")
 
-    issue = TestingIssue(filename=str(Path(__file__).resolve()), language="python", issue_line=line + 2)
+    issue = TestingIssue(filename=str(Path(__file__).resolve()),
+                         language="python", issue_line=line + 2)
     proposal = PythonProposal(issue, radius_or_range=1)
     assert proposal.code_offset == 4
-    assert proposal.issue_lines == ['print("A")', 'print("B")  # This is THE line', 'print("C")']
+    assert proposal.issue_lines == [
+        'print("A")', 'print("B")  # This is THE line', 'print("C")']
 
-    assert proposal._merge_lines(['print("A")', 'print("BBBBBB")', 'print("C")']) is True
+    assert proposal._merge_lines(
+        ['print("A")', 'print("BBBBBB")', 'print("C")']) is True
 
     proposal2 = PythonProposal(issue, extract_function=True)
     assert line > proposal2.start_line >= line - 2
@@ -33,9 +36,11 @@ def test_python_proposal():
 def test_python_proposal_code_offset():
     line = getframeinfo(currentframe()).lineno
     if line > 0:
-        issue = TestingIssue(filename=str(Path(__file__).resolve()), language="python", issue_line=line + 3)
-        proposal0 = PythonProposal(issue, radius_or_range=0)  # This line is used for testing
-        assert proposal0.code_offset == 8
+        issue = TestingIssue(filename=str(
+            Path(__file__).resolve()), language="python", issue_line=line + 3)
+        # This line is used for testing
+        proposal0 = PythonProposal(issue, radius_or_range=0)
+        assert proposal0.code_offset == 12
 
         proposal1 = PythonProposal(issue, radius_or_range=1)
         assert proposal1.code_offset == 8
diff --git a/tests/unit/proposals/simple_proposal_test.py b/tests/unit/proposals/simple_proposal_test.py
index c9e3b85..72fc552 100644
--- a/tests/unit/proposals/simple_proposal_test.py
+++ b/tests/unit/proposals/simple_proposal_test.py
@@ -8,19 +8,23 @@
 import pytest
 from unit.common.testing_issue import TestingIssue
 
-from proposals.simple_proposal import SimpleProposal
+from hallux.proposals.simple_proposal import SimpleProposal
 
 
 @pytest.mark.parametrize(
     "issue_line, radius, propose_lines, expected_lines",
     [
-        (4, 2, "2\n3\n4\n\n6", "2\n3\n4\n\n6"),  # normal situation line 5 is removed
-        (4, 2, "3\n4\n\n6", "2\n3\n4\n\n6"),  # proposed lines shorter than needed, but still OK
-        (4, 2, "3\n\n5", "2\n3\n\n5\n6"),  # proposed lines super short, but still enough to match
+        # normal situation line 5 is removed
+        (4, 2, "2\n3\n4\n\n6", "2\n3\n4\n\n6"),
+        # proposed lines shorter than needed, but still OK
+        (4, 2, "3\n4\n\n6", "2\n3\n4\n\n6"),
+        # proposed lines super short, but still enough to match
+        (4, 2, "3\n\n5", "2\n3\n\n5\n6"),
         (4, 2, "```\n3\n4\n\n6\n```", "2\n3\n4\n\n6"),  # extra ``` stuff
         (4, 2, "```\n3\n4\n\n6\n```\n", "2\n3\n4\n\n6"),  # extra ``` stuff + \n
         (5, 1, "HAL\n4\nB\n6\nHAL", "4\nB\n6"),  # hallucinations around
-        (5, 1, "HAL1\nHAL2\n4\nB\n6\nHAL1\nHAL2", "4\nB\n6"),  # more hallucinations around
+        (5, 1, "HAL1\nHAL2\n4\nB\n6\nHAL1\nHAL2",
+         "4\nB\n6"),  # more hallucinations around
         (5, 10, "3\nB\n4", "1\n2\n3\nB\n4\n5\n6\n7\n8\n9\n10"),
     ],
 )
@@ -66,7 +70,8 @@ def test_simple_proposal(test_filename="simple_proposal_test.txt"):
     assert fd1._merge_lines("3\nA\nB\nC".split("\n")) is False
     assert fd1._merge_lines("A\nB\nC\n5".split("\n")) is False
 
-    fd1_c = SimpleProposal(test_issue2, radius_or_range=1, issue_line_comment=" #")
+    fd1_c = SimpleProposal(test_issue2, radius_or_range=1,
+                           issue_line_comment=" #")
     assert fd1_c.issue_lines == ["3", "4 #", "5"]
     fd1_c._merge_lines(fd1_c.issue_lines)
     assert fd1_c.proposed_lines == ["3", "4", "5"]
@@ -75,7 +80,8 @@ def test_simple_proposal(test_filename="simple_proposal_test.txt"):
 def test_cpp_file_diff_with_real_openai_results(test_filename="../../test-cpp-project/cpp/test_cpp_project.cpp"):
     test_file = Path(__file__).resolve().parent.joinpath(test_filename)
     test_issue = TestingIssue(str(test_file), issue_line=21)
-    fd = SimpleProposal(test_issue, radius_or_range=4, issue_line_comment=" // line 21")
+    fd = SimpleProposal(test_issue, radius_or_range=4,
+                        issue_line_comment=" // line 21")
     real_output = (
         '```cpp\n#include <iostream>\n\nvoid missingFunction(int arg) {\n    std::cout << "Missing function called with'
         ' argument: " << arg << std::endl;\n}\n\nint main(int argc, char** argv) {\n    missingFunction(argc);\n\n   '
@@ -83,9 +89,11 @@ def test_cpp_file_diff_with_real_openai_results(test_filename="../../test-cpp-pr
     )
     result = fd._merge_lines(real_output.split("\n"))
     assert result
-    assert fd.proposed_lines == ["  }", "", "  missingFunction(argc);", "", "    return 0;", "}", ""]
+    assert fd.proposed_lines == [
+        "  }", "", "  missingFunction(argc);", "", "    return 0;", "}", ""]
 
-    fd2 = SimpleProposal(test_issue, radius_or_range=5, issue_line_comment=" // line 21")
+    fd2 = SimpleProposal(test_issue, radius_or_range=5,
+                         issue_line_comment=" // line 21")
     real_output2 = (
         '```cpp\n#include <iostream>\n\nvoid print_usage(char* argv[]) {\n  std::cout << "Usage: " << argv[0] << "'
         ' <filename>" << std::endl;\n}\n\nvoid missingFunction(int argc) {\n  std::cout << "Missing function called'
@@ -95,7 +103,8 @@ def test_cpp_file_diff_with_real_openai_results(test_filename="../../test-cpp-pr
     result = fd2._merge_lines(real_output2.split("\n"))
     assert result
     print(fd2.proposed_lines)
-    assert fd.proposed_lines == ["  }", "", "  missingFunction(argc);", "", "    return 0;", "}", ""]
+    assert fd.proposed_lines == [
+        "  }", "", "  missingFunction(argc);", "", "    return 0;", "}", ""]
 
 
 def test_python_file_diff_with_real_openai_results(
diff --git a/tests/unit/targets/filesystem_target_test.py b/tests/unit/targets/filesystem_target_test.py
index 7fb3a3c..612f9a9 100644
--- a/tests/unit/targets/filesystem_target_test.py
+++ b/tests/unit/targets/filesystem_target_test.py
@@ -9,8 +9,8 @@
 import pytest
 from unit.common.testing_issue import TestingIssue
 
-from proposals.simple_proposal import SimpleProposal
-from targets.filesystem_target import FilesystemTarget
+from hallux.proposals.simple_proposal import SimpleProposal
+from hallux.targets.filesystem import FilesystemTarget
 
 
 def test_filesystem_target():
diff --git a/tests/unit/targets/git_commit_target_test.py b/tests/unit/targets/git_commit_target_test.py
index 43bbb53..838b546 100644
--- a/tests/unit/targets/git_commit_target_test.py
+++ b/tests/unit/targets/git_commit_target_test.py
@@ -3,8 +3,8 @@
 
 import pytest
 
-from targets.filesystem_target import FilesystemTarget
-from targets.git_commit_target import GitCommitTarget
+from hallux.targets.filesystem import FilesystemTarget
+from hallux.targets.git_commit import GitCommitTarget
 
 TEST_PROJECT_PATH: Final[str] = "/current/dir"
 
@@ -77,7 +77,8 @@ def test_commit_diff(git_target_factory, diff_proposal):
 
         # Check that subprocess.check_output was called with the expected arguments
         mock_subprocess.assert_any_call(["git", "add", "file"])
-        mock_subprocess.assert_any_call(["git", "commit", "-m", f"HALLUX: {diff_proposal.description}"])
+        mock_subprocess.assert_any_call(
+            ["git", "commit", "-m", f"HALLUX: {diff_proposal.description}"])
 
         # Check that os.chdir was called to change into and back out of the git directory
         mock_chdir.assert_any_call("/path/to")
diff --git a/tests/unit/targets/github_proposal_target_test.py b/tests/unit/targets/github_proposal_target_test.py
index 59aa537..22a39a7 100644
--- a/tests/unit/targets/github_proposal_target_test.py
+++ b/tests/unit/targets/github_proposal_target_test.py
@@ -3,11 +3,12 @@
 
 from __future__ import annotations
 
-from targets.github_proposal_traget import GithubProposalTraget
+from hallux.targets.github_proposal import GithubProposalTraget
 
 
 def test_github_proposal_target():
-    (base_url, repo_name, PR_ID) = GithubProposalTraget.parse_pr_url("https://github.com/halluxai/hallux/pull/38")
+    (base_url, repo_name, PR_ID) = GithubProposalTraget.parse_pr_url(
+        "https://github.com/halluxai/hallux/pull/38")
     assert base_url == "https://api.github.com"
     assert repo_name == "halluxai/hallux"
     assert PR_ID == 38
diff --git a/tests/unit/tools/cpp_test.py b/tests/unit/tools/cpp_test.py
index 8cdc5b3..78a6d83 100644
--- a/tests/unit/tools/cpp_test.py
+++ b/tests/unit/tools/cpp_test.py
@@ -3,7 +3,7 @@
 from pathlib import Path
 from unittest.mock import Mock, patch
 
-from tools.cpp.cpp import Cpp_IssueSolver
+from hallux.tools.cpp.cpp import Cpp_IssueSolver
 
 
 class TestCpp_IssueSolver(unittest.TestCase):
@@ -40,4 +40,5 @@ def test_process_without_make_nor_cmake(self):
         processor = Cpp_IssueSolver(self.base_path, self.base_path)
         with patch("logging.error") as mock_print:
             processor.solve_issues(self.query_backend, self.diff_target)
-            mock_print.assert_called_with("Process C/C++: cannot find `Makefile` nor 'CMakeLists.txt'")
+            mock_print.assert_called_with(
+                "Process C/C++: cannot find `Makefile` nor 'CMakeLists.txt'")
diff --git a/tests/unit/tools/factory_test.py b/tests/unit/tools/factory_test.py
index fceaaf0..5e4ae0d 100644
--- a/tests/unit/tools/factory_test.py
+++ b/tests/unit/tools/factory_test.py
@@ -7,12 +7,12 @@
 
 import pytest
 
-from tools.cpp.cpp import Cpp_IssueSolver
-from tools.factory import ProcessorFactory
-from tools.issue_solver import IssueSolver
-from tools.mypy.solver import Mypy_IssueSolver
-from tools.ruff.solver import Ruff_IssueSolver
-from tools.sonarqube.solver import Sonar_IssueSolver
+from hallux.tools.cpp.cpp import Cpp_IssueSolver
+from hallux.tools.factory import ProcessorFactory
+from hallux.tools.issue_solver import IssueSolver
+from hallux.tools.mypy.solver import Mypy_IssueSolver
+from hallux.tools.ruff.solver import Ruff_IssueSolver
+from hallux.tools.sonarqube.solver import Sonar_IssueSolver
 
 ruff = Ruff_IssueSolver(Path(), Path())
 mypy = Mypy_IssueSolver(Path(), Path())
@@ -23,9 +23,12 @@
 @pytest.mark.parametrize(
     "argv, config, groups, expected_list",
     [
-        ([], None, None, [ruff, mypy, sonar, cpp]),  # no settings, no request -> select everything
-        ([], {}, None, [ruff, mypy, sonar, cpp]),  # settings empty, no request -> select everything
-        ([], {"whatever": {}}, {}, [ruff, mypy, sonar, cpp]),  # not valid request
+        # no settings, no request -> select everything
+        ([], None, None, [ruff, mypy, sonar, cpp]),
+        # settings empty, no request -> select everything
+        ([], {}, None, [ruff, mypy, sonar, cpp]),
+        # not valid request
+        ([], {"whatever": {}}, {}, [ruff, mypy, sonar, cpp]),
         (
             ["--whatever"],
             {"whatever": {}},
@@ -57,7 +60,8 @@
 )
 def test_init_solvers(argv: list[str], config: dict, groups: dict, expected_list: list):
     argv = ["hallux"] + argv
-    solvers_list = ProcessorFactory.init_solvers(argv, config, groups, Path(), Path())
+    solvers_list = ProcessorFactory.init_solvers(
+        argv, config, groups, Path(), Path())
     assert len(solvers_list) == len(expected_list)
     assert len(solvers_list) >= 1  # shall always return at least one processor
     for i in range(len(solvers_list)):
diff --git a/tests/unit/tools/issue_solver_test.py b/tests/unit/tools/issue_solver_test.py
index cf1989f..15fce2a 100644
--- a/tests/unit/tools/issue_solver_test.py
+++ b/tests/unit/tools/issue_solver_test.py
@@ -4,10 +4,10 @@
 import pytest
 from unit.common.testing_issue import TestingIssue
 
-from backends.query_backend import QueryBackend
-from proposals.diff_proposal import DiffProposal
-from targets.diff_target import DiffTarget
-from tools.issue_solver import IssueSolver
+from hallux.backends.query_backend import QueryBackend
+from hallux.proposals.diff_proposal import DiffProposal
+from hallux.targets.diff import DiffTarget
+from hallux.tools.issue_solver import IssueSolver
 
 
 # Create a concrete subclass of IssueSolver for testing
diff --git a/tests/unit/tools/sonar_test.py b/tests/unit/tools/sonar_test.py
index a86690b..7ef18cc 100644
--- a/tests/unit/tools/sonar_test.py
+++ b/tests/unit/tools/sonar_test.py
@@ -5,8 +5,8 @@
 
 import requests
 
-from issues.issue import IssueDescriptor
-from tools.sonarqube.solver import Sonar_IssueSolver, SonarIssue
+from hallux.issues.issue import IssueDescriptor
+from hallux.tools.sonarqube.solver import Sonar_IssueSolver, SonarIssue
 
 SONAR_SAMPLE_TOKEN: Final[str] = "sqt-deadbeefdeadbeefdeadbeefdeadbeef"
 SONAR_PROJECT: Final[str] = "test_project"
@@ -58,7 +58,8 @@ def test_try_fixing_no_results(filename=__file__):
 
     sonar_issue = SonarIssue(
         filename=str(test_file.absolute()),
-        text_range={"startLine": 2, "endLine": 2, "startOffset": 0, "endOffset": 0},
+        text_range={"startLine": 2, "endLine": 2,
+                    "startOffset": 0, "endOffset": 0},
         issue_line=2,
     )
     proposals = sonar_issue.list_proposals()