Skip to content
Open
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
16 changes: 12 additions & 4 deletions insight/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
".ipynb"
)

SUPPORTED_FILENAMES = {"dockerfile", "makefile", "containerfile", "jenkinsfile"}

# Default directories to ignore
DEFAULT_IGNORED_DIRS = {"venv", "node_modules", "__pycache__", ".git", "dist", "build"}

Expand Down Expand Up @@ -37,16 +39,22 @@ def list_source_files(path):
# Determine the base path to look for the ignore file
base_path = path if os.path.isdir(path) else os.path.dirname(path)
IGNORED_DIRS = get_ignored_dirs(base_path)


if os.path.basename(os.path.normpath(path)) in IGNORED_DIRS:
return

if os.path.isfile(path):
yield path
if os.path.basename(path) not in IGNORED_DIRS:
yield path
return

for root, dirs, files in os.walk(path):
# This line is key: it modifies the list of directories `os.walk` will visit
dirs[:] = [d for d in dirs if d not in IGNORED_DIRS]

for file in files:
if file in IGNORED_DIRS:
continue
# Check for both extension and exact filename match (for Dockerfile, etc.)
if file.lower().endswith(SUPPORTED_EXTS) or file in IGNORED_DIRS:
yield os.path.join(root, file)
if file.lower().endswith(SUPPORTED_EXTS) or file.lower() in SUPPORTED_FILENAMES:
yield os.path.join(root, file)
45 changes: 45 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from pathlib import Path

from insight.utils import list_source_files


def _relative_sources(root: Path) -> set[str]:
return {
Path(path).relative_to(root).as_posix() for path in list_source_files(str(root))
}


def test_list_source_files_respects_ignored_files_and_supports_extensionless_names(
tmp_path: Path,
) -> None:
(tmp_path / ".insightignore").write_text(".env\nignored.log\n", encoding="utf-8")
(tmp_path / ".env").write_text("API_SECRET=do-not-send\n", encoding="utf-8")
(tmp_path / "ignored.log").write_text("not source\n", encoding="utf-8")
(tmp_path / "main.py").write_text("print('safe')\n", encoding="utf-8")
for filename in ("Dockerfile", "Makefile", "Containerfile", "Jenkinsfile"):
(tmp_path / filename).write_text("source\n", encoding="utf-8")

ignored_directory = tmp_path / "venv"
ignored_directory.mkdir()
(ignored_directory / "secret.py").write_text("secret = True\n", encoding="utf-8")

sources = _relative_sources(tmp_path)

assert ".env" not in sources
assert "ignored.log" not in sources
assert "venv/secret.py" not in sources
assert {
"main.py",
"Dockerfile",
"Makefile",
"Containerfile",
"Jenkinsfile",
} <= sources


def test_explicitly_ignored_file_is_not_returned(tmp_path: Path) -> None:
(tmp_path / ".insightignore").write_text(".env\n", encoding="utf-8")
ignored_file = tmp_path / ".env"
ignored_file.write_text("API_SECRET=do-not-send\n", encoding="utf-8")

assert list(list_source_files(str(ignored_file))) == []