Release/v0.8.17#56
Conversation
gather_files() followed symlinks without boundary checking. A symlink like packaging/dmg/stage/Applications -> /Applications caused the walker to recurse into the entire macOS Applications directory, spawning thousands of git check-ignore subprocesses. Fix: compute scan_root (canonical) once at entry, pass through recursion via gather_files_inner(). Skip any symlink whose canonical target falls outside scan_root. Intra-repo symlinks still work. Fixes #55 Co-Authored-By: Klaudiusz <the1st@whoai.am>
Commands like `loct health` and `loct dead` that trigger auto-rescan constructed ParsedArgs with Default::default(), which has empty ignore_patterns. The explicit `loct scan` path loads .loctignore via detect.rs but auto-rescan did not. Also canonicalizes root path in load_or_create_snapshot to prevent relative/absolute mismatch. Part of #55 Co-Authored-By: Klaudiusz <the1st@whoai.am>
normalize_root_dir('.') returned PathBuf('.') without resolving to
absolute path. This caused snapshot root mismatches when comparing
requested roots (relative) against cached roots (absolute).
Part of #55
Co-Authored-By: Klaudiusz <the1st@whoai.am>
loct cache --help returned 'Unknown command' because the help dispatcher had no entry for 'cache'. Add CACHE_HELP text and register it in both help lookup and command listing. Co-Authored-By: Klaudiusz <the1st@whoai.am>
Remove stale snapshot refresh workaround from analyzes_impact test (no longer needed after auto-rescan fix). Update audit_stdout_flag test comments to reflect current --json contract. Co-Authored-By: Klaudiusz <the1st@whoai.am>
Restructure installation and CI checks, and update docs. Makefile: break the monolithic install into install-cli and install-mcp (and call git-hooks from the new install), remove install-all, add clearer install output, and rename/simplify check targets (precheck -> fast cargo check, check -> full quality gate). The full quality gate now runs fmt, clippy, cargo check and an optional semgrep security scan. .gitignore: ignore /reports directory. README: simplify install instructions (one-liner, combined cargo installs, npm option), add a "Why loctree" comparison table and list the new tool `follow`, and clarify tool usage.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the loctree project by refining its build processes, improving CLI usability, and strengthening file scanning robustness. Users will benefit from more flexible installation options, better control over cached data, and safer, more accurate file scanning. Additionally, developers gain from an improved quality gate that now includes security scanning, ensuring a more robust and secure codebase. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new loct cache command for managing snapshot caches, complete with list and clean subcommands and detailed help. The Makefile has been refactored to modularize installation targets (install-cli, install-mcp) and enhance the check target with a Semgrep security scan. Additionally, the README.md has been updated with streamlined installation instructions and a new feature comparison table. Code changes also include canonicalizing root paths for snapshot loading and refactoring gather_files to prevent symlinks from escaping the scan root, though an efficiency improvement was noted for redundant canonicalize() calls within the recursive gather_files_inner function. A further improvement opportunity was identified in the Makefile to prevent semgrep execution if the tool is not installed.
| @if command -v semgrep >/dev/null 2>&1 || command -v pipx >/dev/null 2>&1; then \ | ||
| SEMGREP=$$(command -v semgrep || echo "pipx run semgrep"); \ | ||
| $$SEMGREP scan --config auto --error --quiet . 2>/dev/null || \ | ||
| echo "[!] Semgrep found issues (see above)"; \ | ||
| else \ | ||
| echo "[!] Semgrep not available, skipping (install: pipx install semgrep)"; \ | ||
| fi |
There was a problem hiding this comment.
The semgrep command is executed even if it's not installed, leading to an error message in the output. It would be better to skip the execution entirely if semgrep is not available.
if command -v semgrep >/dev/null 2>&1 || command -v pipx >/dev/null 2>&1; then \
SEMGREP=$$(command -v semgrep || echo "pipx run semgrep"); \
$$SEMGREP scan --config auto --error --quiet . 2>/dev/null || \
echo "[!] Semgrep found issues (see above)"; \
else \
echo "[!] Semgrep not available, skipping (install: pipx install semgrep)"; \
fi
| // Don't follow symlinks that escape the scan root (e.g. DMG staging | ||
| // dirs with /Applications symlink). Compares against the top-level | ||
| // scan root, not the current recursion dir, so intra-repo symlinks | ||
| // like src/data -> ../shared/data still work. | ||
| if !target.starts_with(scan_root) { | ||
| continue; | ||
| } | ||
| let meta = match fs::metadata(&path) { | ||
| Ok(m) => m, | ||
| Err(_) => continue, | ||
| }; | ||
| if meta.is_dir() && options.max_depth.is_none_or(|max| depth < max) { | ||
| gather_files(&target, options, depth + 1, git_checker, visited, files)?; | ||
| gather_files_inner( | ||
| &target, | ||
| scan_root, | ||
| options, | ||
| depth + 1, | ||
| git_checker, | ||
| visited, | ||
| files, | ||
| )?; |
There was a problem hiding this comment.
The gather_files_inner function is recursively called within the symlink handling logic. It would be more efficient to pass the scan_root to the gather_files_inner function directly instead of calling dir.canonicalize() again, as it's already canonicalized in the gather_files function.
gather_files_inner(
&target,
scan_root,
options,
depth + 1,
git_checker,
visited,
files,
)?;Add .github/FUNDING.yml to configure project funding links. This file registers the GitHub Sponsors account 'Loctree' and a Polar funding handle 'loctree' so the repository displays sponsor/donation options.
Rework release and Homebrew distribution workflows to separate distribution from the monorepo. - Publish pipeline now builds per-platform CLI (loct) and MCP (loctree-mcp) artifacts, uploads them as artifacts, and publishes thin releases into Loctree/loct and Loctree/loctree-mcp. A monorepo release is created after thin releases and npm publish. - homebrew-release workflow now downloads the published tarballs, computes SHA256 checksums, renders formulas via scripts/render-homebrew-formula.sh, and commits updates directly into two tap repos: Loctree/homebrew-cli and Loctree/homebrew-mcp (requires HOMEBREW_GITHUB_API_TOKEN). - Removed legacy Homebrew formula files and helper scripts for homebrew-core, deleted placeholder npm bin shims, and updated docs/README/.github guidance to reflect new tap names and the new bootstrap/runtime contract. This change centralizes binary distribution in narrow "thin" repos and automates tapping/updating of Homebrew formulae in the two custom taps.
loctree=0.8.17 report-leptos=0.8.17 loctree-mcp=0.8.17 VibeCrafted with AI Agents (c)2024-2026 VetCoders
Refactor the `loct cache list` handler to aggregate cache buckets by repo and project path and surface richer scan metadata. Introduces CacheBucketRow, CacheBucketStats and CacheSnapshotRecord along with helpers to read snapshot.json, compute bucket sizes, select project roots, resolve owner/repo labels, and format schema/branch/scan info; output now shows MB sizes and a summary meta column. Adds parsing of git owner/repo (parse_owner_repo and parse_repo_name), a new git_owner_repo field in SnapshotMetadata and GitContext, and updates get_git_info/git_context_for to populate it. Updates CLI help text, adds end-to-end and unit tests for the new behavior, and minor test adjustments. Also adds .vibecrafted to .gitignore.
Add a macOS smoke-releaseability script to verify release binaries do not link against non-system dylibs and to run a quick --version check. Integrate the smoke check into GitHub Actions and Makefile (new smoke-release-macos-arm64 target), include packaged release assets in the monorepo GH release, and update release messaging/docs. Make installer changes: tools/install.sh now supports INSTALL_MCP (install MCP server optionally) and uses cargo install --locked; README, distribution docs, npm docs, and dev install docs updated to reflect CLI-only npm channel and reproducible installs. Vendor libgit2 in loctree_rs Cargo.toml to keep macOS release binaries portable. Also add a small clippy allow and other minor packaging/CI tweaks.
Strip every #[allow(clippy::..., dead_code, unused_imports, ...)] attribute from the codebase and fix the underlying issues so clippy passes clean without any suppression: - Delete 7 dead functions/structs in dist.rs (source-map pipeline, -255 LOC) - Bundle too_many_arguments into context structs across 6 functions: tree.rs WalkContext, scan.rs AnalyzeContext, output.rs GlobalContext, findings.rs SummaryInput, py/mod.rs FromImportContext, refactor_plan/mod.rs TarjanState - Add ComponentResult type alias in graph.rs for type_complexity - Remove unused_imports in analyzer/mod.rs - Remove stale non_snake_case/dead_code/unused_unsafe suppressions in regexes.rs, snapshot.rs, cache.rs Also add 3 cache clean e2e tests covering the previously untested destructive cache clean command (--force, --older-than, confirmation UX). Co-Authored-By: Klaudiusz <the1st@whoai.am>
Standardize copyright/branding across the repo: replace (c) markers with ⓒ and extend year ranges to 2025-2026, unify the "VibeCrafted" styling (𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍.). Changes touch many docs, CI/workflow files, ai-hooks, scripts, examples, and source headers. Also adjust a Cargo.toml comment (rmcp-memex → rust-memex).
Replace numerous manual descending sort closures with sort_by_key(...Reverse(...)) across the codebase for clarity and consistency (loctree-mcp, analyzer modules, CLI handlers, snapshot, tree). Also simplify a match arm in the Python usage parser to use a guarded pattern, and add two docs: BUG_symlink_escape_traversal.md (symlink traversal bug report/fix notes) and ROADMAP_0.8.16_to_0.10.1.md (product roadmap/research notes). These are refactors and documentation additions only.
This pull request introduces several improvements and refactors to the
Makefile, CLI help system, file scanning logic, and documentation for the loctree project. The most notable changes are the restructuring of installation targets, enhancements to cache management commands, improved symlink handling during file scans, and updates to documentation and tests.Build and Installation Improvements
Makefileinstallation targets are now split intoinstall,install-cli, andinstall-mcp, allowing for more granular installation of CLI tools and MCP server. The maininstalltarget now also installs git hooks. [1] [2] [3]checktarget is renamed toprecheck.CLI Help and Cache Management
cachemanagement command to the CLI, including detailed help text and subcommands for listing and cleaning cached project snapshots. [1] [2] [3]File Scanning and Symlink Handling
Documentation Updates
README.mdis updated to clarify installation options, highlight loctree's advantages over other tools, and expand the list of available tools. [1] [2] [3]Test Adjustments
audit --stdoutflag, now recommending the--jsonflag for stdout output and verifying its contract.