Skip to content
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
3 changes: 2 additions & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ if [ -n "$PR_HEAD_SHA" ]; then
fi

if [ -n "$DOCS_SUBFOLDER" ]; then
export DOCS_SUBFOLDER="$DOCS_SUBFOLDER"
DOCS_SUBFOLDER="${DOCS_SUBFOLDER%/}"
export DOCS_SUBFOLDER
fi

if [ -n "$COMMENT_BODY" ]; then
Expand Down
3 changes: 2 additions & 1 deletion src/doc_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ def _get_effective_subfolder():
Uses ``git rev-parse --show-prefix`` to determine CWD's position
within the repo, avoiding filesystem heuristics.
"""
docs_subfolder = os.environ.get("DOCS_SUBFOLDER", "")
raw = os.environ.get("DOCS_SUBFOLDER", "")
docs_subfolder = os.path.normpath(raw).strip("/") if raw.strip() else ""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] edge-case

When DOCS_SUBFOLDER is set to "." or "./", os.path.normpath(raw).strip("/") produces ".", which is truthy and passes the emptiness guard. The function compares "." against git rev-parse --show-prefix output (empty at repo root), returning "." as effective subfolder. Downstream pathspecs like "./commands" work in git but behavior is inconsistent with intent.

Suggested fix: Add a guard after normpath: if docs_subfolder == ".": docs_subfolder = ""

if not docs_subfolder:
return ""
result = run_command_safe(["git", "rev-parse", "--show-prefix"], check=False)
Expand Down
65 changes: 65 additions & 0 deletions tests/test_doc_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
INDEX_DIR,
SUMMARIES_DIR,
_get_docs_content_from_ref,
_get_effective_subfolder,
_handle_empty_folder_on_ref,
checkout_docs_from_base_branch,
folder_needs_reindex,
Expand Down Expand Up @@ -291,6 +292,70 @@ def test_falls_back_to_disk_when_ref_unavailable(self, doc_tree):
assert folder_needs_reindex("guides", manifest, docs_root=doc_tree) is False


class TestGetEffectiveSubfolder:
@pytest.fixture(autouse=True)
def _reset_log_state(self):
yield
if hasattr(_get_effective_subfolder, "_last_msg"):
delattr(_get_effective_subfolder, "_last_msg")

def test_trailing_slash_normalized(self, monkeypatch):
"""DOCS_SUBFOLDER with trailing slash should still match CWD prefix."""
monkeypatch.setenv("DOCS_SUBFOLDER", "docs/")
mock_result = MagicMock(returncode=0, stdout="docs/\n")
with patch("doc_index.run_command_safe", return_value=mock_result):
assert _get_effective_subfolder() == ""

def test_dot_slash_prefix_normalized(self, monkeypatch):
"""DOCS_SUBFOLDER with ./ prefix should still match CWD prefix."""
monkeypatch.setenv("DOCS_SUBFOLDER", "./docs")
mock_result = MagicMock(returncode=0, stdout="docs/\n")
with patch("doc_index.run_command_safe", return_value=mock_result):
assert _get_effective_subfolder() == ""

def test_no_trailing_slash(self, monkeypatch):
"""DOCS_SUBFOLDER without trailing slash matches normally."""
monkeypatch.setenv("DOCS_SUBFOLDER", "docs")
mock_result = MagicMock(returncode=0, stdout="docs/\n")
with patch("doc_index.run_command_safe", return_value=mock_result):
assert _get_effective_subfolder() == ""

def test_cwd_not_in_subfolder(self, monkeypatch):
"""When CWD is not inside DOCS_SUBFOLDER, return the subfolder."""
monkeypatch.setenv("DOCS_SUBFOLDER", "docs")
mock_result = MagicMock(returncode=0, stdout="\n")
with patch("doc_index.run_command_safe", return_value=mock_result):
assert _get_effective_subfolder() == "docs"

def test_empty_subfolder(self, monkeypatch):
monkeypatch.setenv("DOCS_SUBFOLDER", "")
assert _get_effective_subfolder() == ""

def test_trailing_slash_pathspec_not_doubled(self, monkeypatch):
"""The actual regression: trailing slash must not cause doubled pathspecs."""
monkeypatch.setenv("DOCS_SUBFOLDER", "docs/")
monkeypatch.setenv("DOCS_BASE_BRANCH", "main")

calls = []

def capture_run(cmd, **kwargs):
calls.append(cmd)
if "rev-parse" in cmd and "--show-prefix" in cmd:
return MagicMock(returncode=0, stdout="docs/\n")
if "rev-parse" in cmd and "--verify" in cmd:
return MagicMock(returncode=0)
if "ls-tree" in cmd:
return MagicMock(returncode=0, stdout="")
return MagicMock(returncode=0, stdout="")

with patch("doc_index.run_command_safe", side_effect=capture_run):
get_folder_doc_hashes_from_ref("commands")

ls_tree_calls = [c for c in calls if "ls-tree" in c]
assert len(ls_tree_calls) == 1
assert ls_tree_calls[0][-1] == "commands"


class TestGetFolderDocHashesFromRef:
def test_returns_hashes_from_git_ref(self, monkeypatch):
monkeypatch.delenv("DOCS_SUBFOLDER", raising=False)
Expand Down
Loading