Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🩹 Point read_chonkignore() toward target path instead of project root #30

Merged
merged 2 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,8 @@ $ pip install chonk
> Any files, folders, or file extensions specified in `.chonkignore` will be excluded from the output file.
> Refer to the `.chonkignore.example` for suggestions regarding what to include in `.chonkignore`.

To use CHONK outside of Python environments, install the package globally and ensure that the Python
executable is added to your system's `PATH`. On Windows, navigate to your environment variables and edit the `PATH`
user variable to include `C:\Users\<user>\AppData\Roaming\Python\Python312\Scripts`. After restarting your PC, run
`$ chonk --version` to verify that the package has been installed correctly.

Execute the script simply by running
To use this package outside of Python environments, install the package globally and ensure that the Python
executable is added to your system's `PATH`. Execute the script simply by running

```sh
$ chonk
Expand All @@ -39,7 +35,7 @@ and follow the prompts by providing an input directory, an output file destinati
Alternatively, the script can be executed using a single command with the appropriate flags:

```sh
$ chonk -i <input_path> -o <output_path> -f <(optional) filters>
$ chonk -i <input_path> -o <output_path> -f <optional filters>
```

For further information, run `$ chonk --help`.
30 changes: 26 additions & 4 deletions chonk/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@
from typing import Any, Callable, List, Optional


def get_project_root(start_path: str) -> str:
"""
Find the project root directory based on common project files.
"""
current_dir = os.path.abspath(start_path)
root_indicators = [
".git",
"package.json",
"pdm.lock",
"pyproject.toml",
"setup.py",
"tox.ini",
]

while current_dir != os.path.dirname(current_dir):
if any(os.path.exists(os.path.join(current_dir, indicator)) for indicator in root_indicators):
return current_dir
current_dir = os.path.dirname(current_dir)

return start_path


def skip_ignore_list_comments(file_path: str) -> List[str]:
ignore_list: List[str] = []
with open(file_path, "r", encoding="utf-8") as f:
Expand All @@ -12,17 +34,17 @@ def skip_ignore_list_comments(file_path: str) -> List[str]:
return ignore_list


def read_chonkignore(project_root: str, extension_filter: Optional[List[str]]) -> Callable[[str], bool]:
def read_chonkignore(input_path: str, extension_filter: Optional[List[str]]) -> Callable[[str], bool]:
"""
Excludes all files, extensions and directories specified in .chonkignore, located inside the root directory.
Excludes all files, extensions and directories specified in .chonkignore, located inside the input directory.
"""
project_root = get_project_root(input_path)
chonkignore = os.path.join(project_root, ".chonkignore")
default_ignore_list = DEFAULT_IGNORE_LIST.copy()

ignore_list: List[str] = []
if os.path.exists(chonkignore):
with open(chonkignore, "r", encoding="utf-8") as f:
ignore_list = [line.strip() for line in f if line.strip() and not line.startswith("#")]
ignore_list = skip_ignore_list_comments(chonkignore)

default_ignore_list.extend(ignore_list)

Expand Down
31 changes: 4 additions & 27 deletions chonk/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from prompt_toolkit.completion import Completer, Completion
from prompt_toolkit.document import Document

from .filter import parse_extensions
from .filter import get_project_root, parse_extensions
from .utilities import NoMatchingExtensionError, consolidate

GLOBAL_LOG_LEVEL = logging.INFO
Expand All @@ -21,30 +21,6 @@
MAX_FILE_SIZE: int = 1024 * 1024 * 10 # 10 MB


def get_project_root() -> str:
"""
Required for input/output path prompts to display the project root as default path.
"""

current_dir: str = os.path.abspath(os.getcwd())

root_indicators: List[str] = [
".git",
"package.json",
"pdm.lock",
"pyproject.toml",
"setup.py",
"tox.ini",
]

while current_dir != os.path.dirname(current_dir):
if any(os.path.exists(os.path.join(current_dir, indicator)) for indicator in root_indicators):
return current_dir
current_dir = os.path.dirname(current_dir)

return os.getcwd()


@dataclass
class CaseInsensitivePathCompleter(Completer):
only_directories: bool = False
Expand Down Expand Up @@ -82,7 +58,7 @@ def path_prompt(message: str, default: str, exists: bool = False) -> str:

while True:
path: str = prompt(f"{message} ", default=default, completer=path_completer)
path = path.strip() # # remove leading and trailing whitespace
path = path.strip() # remove leading and trailing whitespace
full_path: str = os.path.abspath(os.path.expanduser(path))
if not exists or os.path.exists(full_path):
return full_path
Expand Down Expand Up @@ -113,7 +89,8 @@ def generate_markdown(
input_path: Optional[str], output_path: Optional[str], extension_filter: Optional[List[str]]
) -> None:
no_flags_provided: bool = input_path is None and output_path is None and not extension_filter
project_root: str = get_project_root()
current_dir = os.getcwd()
project_root: str = get_project_root(current_dir)

input_path = input_path or path_prompt(
"📁 INPUT PATH OF YOUR TARGET DIRECTORY -", default=project_root, exists=True
Expand Down
3 changes: 1 addition & 2 deletions chonk/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ def consolidate(
Gathers and formats the content and metadata of all files inside a provided input directory,
while taking into account optional extension filters as well as .chonkignore specific exceptions.
"""
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
exclude_files = read_chonkignore(project_root, extensions)
exclude_files = read_chonkignore(path, extensions)
chonk = ""
file_count = 0
token_count = 0
Expand Down