Skip to content

fix: add file-based fallback to check_comfy_repo for non-git installs#401

Open
bigcat88 wants to merge 2 commits intomainfrom
fix/check-comfy-repo-fallback-markers
Open

fix: add file-based fallback to check_comfy_repo for non-git installs#401
bigcat88 wants to merge 2 commits intomainfrom
fix/check-comfy-repo-fallback-markers

Conversation

@bigcat88
Copy link
Copy Markdown
Contributor

Fixes #205

check_comfy_repo() only validated ComfyUI installations by matching git remote URLs against a hardcoded allowlist. This caused set-default and workspace detection to reject perfectly valid ComfyUI installations that were set up via zip download, the Windows portable build, or cloned from a fork/mirror with a non-listed remote URL.

This adds a file-based fallback that checks for ComfyUI marker files (main.py, comfy/, nodes.py, comfy_extras/ — at least 3 of 4 must be present) when the git-based check fails. The git check still runs first, so existing behavior is preserved for standard clones.

The return type of check_comfy_repo() changes from tuple[bool, git.Repo | None] to tuple[bool, str | None], returning the resolved path string directly instead of a repo object. All callers only used repo.working_dir anyway, so this is a straightforward simplification.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

The pull request refactors ComfyUI repository detection to return resolved filesystem paths instead of git repository objects, and introduces a fallback mechanism for non-git installations by detecting ComfyUI marker files. This enables the tool to validate and work with both git-based and portable ComfyUI installations.

Changes

Cohort / File(s) Summary
Repository Detection API
comfy_cli/workspace_manager.py
Changed check_comfy_repo() return type from tuple[bool, git.Repo | None] to tuple[bool, str | None]. Added _has_comfyui_markers() helper to detect non-git ComfyUI installations via marker files/directories. Implemented fallback logic that checks for 3+ marker files when git initialization fails, returning success with absolute path for valid non-git installations. Updated callers to use string paths and _paths_match() for workspace comparison instead of .working_dir attribute access.
Command Layer Integration
comfy_cli/cmdline.py
Updated install and set_default commands to use the resolved_path return value from check_comfy_repo() rather than accessing repo_dir.working_dir. Reassigns comfy_path when resolved_path is provided, properly handling both git and non-git ComfyUI installations.
Test Alignment
tests/comfy_cli/test_workspace_manager.py
Updated mocked check_comfy_repo() calls to return (True, <path_string>) instead of (True, <MagicMock_object>), and adjusted side_effect lambdas to return string paths. Ensures test assertions match the new API contract where workspace detection returns filesystem paths for validation.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed PR successfully implements file-based fallback for ComfyUI validation, allowing non-git installations (zip, portable builds, forks) to be recognized, directly addressing issue #205's requirement to accept diverse installation methods.
Out of Scope Changes check ✅ Passed All changes are scope-appropriate: workspace_manager refactors check_comfy_repo signature and fallback logic, cmdline updates callers, and tests align mocks with new return type—no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/check-comfy-repo-fallback-markers
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/check-comfy-repo-fallback-markers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 72.72727% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
comfy_cli/cmdline.py 40.00% 3 Missing ⚠️
comfy_cli/workspace_manager.py 82.35% 3 Missing ⚠️
@@           Coverage Diff           @@
##             main     #401   +/-   ##
=======================================
  Coverage   75.00%   75.00%           
=======================================
  Files          34       34           
  Lines        4028     4033    +5     
=======================================
+ Hits         3021     3025    +4     
- Misses       1007     1008    +1     
Files with missing lines Coverage Δ
comfy_cli/cmdline.py 57.24% <40.00%> (ø)
comfy_cli/workspace_manager.py 73.44% <82.35%> (+0.19%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bigcat88 bigcat88 marked this pull request as ready for review March 30, 2026 19:01
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Mar 30, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
comfy_cli/workspace_manager.py (1)

79-86: ⚠️ Potential issue | 🟡 Minor

Harden custom_nodes parent derivation to avoid empty-path git resolution.

When parent becomes "", git.Repo(parent, ...) resolves from current working directory, which can produce false positives.

🔧 Proposed guard
         if not path_is_comfy_repo and "custom_nodes" in path:
             parts = path.split(os.sep)
             try:
                 index = parts.index("custom_nodes")
-                parent = os.sep.join(parts[:index])
+                parent = os.sep.join(parts[:index]) or os.sep
 
                 repo = git.Repo(parent, search_parent_directories=True)
                 path_is_comfy_repo = any(remote.url in constants.COMFY_ORIGIN_URL_CHOICES for remote in repo.remotes)
             except ValueError:
                 pass
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_cli/workspace_manager.py` around lines 79 - 86, The parent path derived
for "custom_nodes" can be empty which lets git.Repo("") resolve from CWD and
give false positives; before calling git.Repo(parent,
search_parent_directories=True) in workspace_manager (where path, parts, index,
parent, repo and path_is_comfy_repo are used), add a guard to skip git.Repo when
parent is empty or not an absolute/valid directory (e.g., check if parent and
os.path.isdir(parent) or normalize with os.path.abspath(parent) and only then
construct repo and evaluate remotes), otherwise leave path_is_comfy_repo False.
tests/comfy_cli/test_workspace_manager.py (1)

213-224: 🛠️ Refactor suggestion | 🟠 Major

Add regression tests for marker fallback paths (non-git root + non-git subdir).

This PR’s core behavior is marker fallback, but the suite still mostly mocks check_comfy_repo. Add direct tests that exercise real filesystem markers so future changes don’t quietly break this fix. A tiny test now avoids a big oops later.

🧪 Suggested test additions
+def test_check_comfy_repo_non_git_marker_root(tmp_path):
+    from comfy_cli.workspace_manager import check_comfy_repo
+    root = tmp_path / "ComfyUI"
+    root.mkdir()
+    (root / "main.py").write_text("#")
+    (root / "nodes.py").write_text("#")
+    (root / "comfy").mkdir()
+    ok, resolved = check_comfy_repo(str(root))
+    assert ok is True
+    assert resolved == str(root)
+
+def test_check_comfy_repo_non_git_marker_subdir(tmp_path):
+    from comfy_cli.workspace_manager import check_comfy_repo
+    root = tmp_path / "ComfyUI"
+    sub = root / "custom_nodes" / "x"
+    sub.mkdir(parents=True)
+    (root / "main.py").write_text("#")
+    (root / "nodes.py").write_text("#")
+    (root / "comfy_extras").mkdir()
+    ok, resolved = check_comfy_repo(str(sub))
+    assert ok is True
+    assert resolved == str(root)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/comfy_cli/test_workspace_manager.py` around lines 213 - 224, Add
regression tests that exercise real filesystem marker fallback instead of
mocking check_comfy_repo: create a temporary directory structure with a marker
file (e.g., a Comfy marker used by workspace_manager like ".comfy-repo" or the
repository marker your code checks), create a subdirectory (non-git subdir),
monkeypatch os.getcwd to the subdir, instantiate the manager with
_make_manager(use_here=None) and _mock_config as needed, call
mgr.get_workspace_path() without patching check_comfy_repo/_paths_match, and
assert the returned path matches the marker-rooted resolved path; reference
helpers _make_manager, get_workspace_path, and check_comfy_repo/_paths_match to
locate where to integrate the new tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@comfy_cli/workspace_manager.py`:
- Around line 97-103: The fallback detection only checks the provided absolute
path (abs_path) for ComfyUI markers via _has_comfyui_markers, so paths that are
inside a ComfyUI tree (e.g. custom_nodes/...) are missed; update the logic to
walk up parent directories from abs_path until filesystem root, calling
_has_comfyui_markers on each parent and returning (True, root_path) when found
(otherwise return (False, None)); reference the existing abs_path variable and
_has_comfyui_markers function to implement the upward traversal and return the
detected ComfyUI root.

---

Outside diff comments:
In `@comfy_cli/workspace_manager.py`:
- Around line 79-86: The parent path derived for "custom_nodes" can be empty
which lets git.Repo("") resolve from CWD and give false positives; before
calling git.Repo(parent, search_parent_directories=True) in workspace_manager
(where path, parts, index, parent, repo and path_is_comfy_repo are used), add a
guard to skip git.Repo when parent is empty or not an absolute/valid directory
(e.g., check if parent and os.path.isdir(parent) or normalize with
os.path.abspath(parent) and only then construct repo and evaluate remotes),
otherwise leave path_is_comfy_repo False.

In `@tests/comfy_cli/test_workspace_manager.py`:
- Around line 213-224: Add regression tests that exercise real filesystem marker
fallback instead of mocking check_comfy_repo: create a temporary directory
structure with a marker file (e.g., a Comfy marker used by workspace_manager
like ".comfy-repo" or the repository marker your code checks), create a
subdirectory (non-git subdir), monkeypatch os.getcwd to the subdir, instantiate
the manager with _make_manager(use_here=None) and _mock_config as needed, call
mgr.get_workspace_path() without patching check_comfy_repo/_paths_match, and
assert the returned path matches the marker-rooted resolved path; reference
helpers _make_manager, get_workspace_path, and check_comfy_repo/_paths_match to
locate where to integrate the new tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8d66d251-f2cc-4df5-9469-6de0e3d3b45b

📥 Commits

Reviewing files that changed from the base of the PR and between 1528c51 and 0f5a1be.

📒 Files selected for processing (3)
  • comfy_cli/cmdline.py
  • comfy_cli/workspace_manager.py
  • tests/comfy_cli/test_workspace_manager.py

Comment on lines +97 to +103
# Fallback: file-based detection for non-git installations (zip downloads,
# portable builds, forks with non-standard remotes, etc.)
abs_path = os.path.abspath(path)
if _has_comfyui_markers(abs_path):
return True, abs_path

return False, None
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fallback currently misses subdirectory paths in non-git installs.

Line 100 checks markers only on abs_path, so paths inside a portable/zip ComfyUI tree (for example custom_nodes/...) fail detection even though the function contract says “is (or is inside).” No root, no loot.

💡 Proposed fix (walk parents to resolve ComfyUI root)
+def _find_comfyui_root(path: str) -> str | None:
+    cur = os.path.abspath(path)
+    if not os.path.isdir(cur):
+        cur = os.path.dirname(cur)
+    while True:
+        if _has_comfyui_markers(cur):
+            return cur
+        parent = os.path.dirname(cur)
+        if parent == cur:
+            return None
+        cur = parent
+
 def check_comfy_repo(path) -> tuple[bool, str | None]:
@@
-    abs_path = os.path.abspath(path)
-    if _has_comfyui_markers(abs_path):
-        return True, abs_path
+    marker_root = _find_comfyui_root(path)
+    if marker_root is not None:
+        return True, marker_root
 
     return False, None
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Fallback: file-based detection for non-git installations (zip downloads,
# portable builds, forks with non-standard remotes, etc.)
abs_path = os.path.abspath(path)
if _has_comfyui_markers(abs_path):
return True, abs_path
return False, None
def _find_comfyui_root(path: str) -> str | None:
cur = os.path.abspath(path)
if not os.path.isdir(cur):
cur = os.path.dirname(cur)
while True:
if _has_comfyui_markers(cur):
return cur
parent = os.path.dirname(cur)
if parent == cur:
return None
cur = parent
def check_comfy_repo(path) -> tuple[bool, str | None]:
# ... existing code ...
# Fallback: file-based detection for non-git installations (zip downloads,
# portable builds, forks with non-standard remotes, etc.)
marker_root = _find_comfyui_root(path)
if marker_root is not None:
return True, marker_root
return False, None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_cli/workspace_manager.py` around lines 97 - 103, The fallback detection
only checks the provided absolute path (abs_path) for ComfyUI markers via
_has_comfyui_markers, so paths that are inside a ComfyUI tree (e.g.
custom_nodes/...) are missed; update the logic to walk up parent directories
from abs_path until filesystem root, calling _has_comfyui_markers on each parent
and returning (True, root_path) when found (otherwise return (False, None));
reference the existing abs_path variable and _has_comfyui_markers function to
implement the upward traversal and return the detected ComfyUI root.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Having problem with set-default and --workspace commands

1 participant