Skip to content

Refactor plugin failures and file URI normalization; update tests#80

Merged
leynos merged 4 commits intomainfrom
refactor-rename-symbol-uri-and-docs-uqgz9w
Mar 11, 2026
Merged

Refactor plugin failures and file URI normalization; update tests#80
leynos merged 4 commits intomainfrom
refactor-rename-symbol-uri-and-docs-uqgz9w

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Mar 11, 2026

Summary

  • Introduces a structured plugin failure model (PluginFailure) and centralizes failure-to-response conversion via failure_response.
  • Normalizes and validates file:// URIs with normalize_request_uri; ensures URI payloads match payload paths and maps mismatches to a structured failure with ReasonCode::IncompletePayload.
  • Updates rust-analyzer plugin to use the new failure module and URI normalization; symbol lookup errors map to plain PluginFailure to preserve existing behavior.
  • Adds tests and fixtures updated to file:// URIs (rust-analyzer and weaverd), including RelativeUri scenarios and SymbolNotFound handling.
  • Adds a helper in weaverd to inject file:// URIs via to_file_uri.
  • Documentation and fixtures updated to reflect file:// URI usage and new failure codes.

Changes

  • New: crates/weaver-plugin-rust-analyzer/src/failure.rs
    • Adds PluginFailure with optional ReasonCode and conversion to PluginResponse via failure_response.
    • Implements Display for user-friendly messages.
    • Plain() and with_reason() constructors for different failure scenarios.
  • Updated: crates/weaver-plugin-rust-analyzer/src/lib.rs
    • Replaces in-file failure handling with the new failure module (PluginFailure, failure_response).
    • Adds normalize_request_uri(uri) -> Result<String, RustAnalyzerAdapterError> to validate and normalize file:// URIs.
    • In execute_rename, uses normalize_request_uri to compare the request URI against the file payload path and maps URI mismatches to a structured failure with ReasonCode::IncompletePayload.
    • On symbol lookup errors from the adapter, maps to a plain PluginFailure without a reason code to preserve existing behavior where appropriate.
  • Updated: tests for rust-analyzer and weaverd
    • rust-analyzer tests updated to use file:// URIs (e.g., file://src/main.rs) and include a new RelativeUri scenario.
    • NoChange failures now include a SymbolNotFound reason_code when appropriate; tests assert on the presence of ReasonCode::SymbolNotFound.
    • weaverd tests updated to inject and expect file:// URIs (e.g., file://notes.txt).
  • New: in crates/weaverd/src/dispatch/act/refactor/mod.rs
    • Adds to_file_uri(path) -> String and uses it to inject file:// URIs when constructing plugin_args.
  • Tests and fixtures adjustments
    • Updated test expectations in various modules to reflect file:// URIs and the new failure semantics.
  • Documentation and fixtures
    • Documentation and feature files updated to reflect file:// URI usage, and new failure code expectations.
    • Updated examples in user guide to mention URI handling and version/help behavior where relevant.

📎 Task: https://www.devboxer.com/task/99d3abee-f949-400f-bd69-cc2a3ee3cbcc

…odes

- Introduce `PluginFailure` struct encapsulating error message and optional `ReasonCode`.
- Provide constructors for plain and reason-coded failures.
- Add conversion helper `failure_response` to create protocol-compliant failure responses.
- Refactor rust-analyzer adapter to use `PluginFailure` for error handling and enrich diagnostic info.
- Normalize plugin request URIs to uniform 'file://' scheme and reject relative URIs.
- Update tests and features to handle new failure reason codes and URI format.

This change enables richer, stable failure reporting in the Rust analyzer plugin.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 11, 2026

Reviewer's Guide

Refactors the rust-analyzer plugin to route all failures through a new structured failure module, introduces URI normalization/validation for file:// requests, updates weaverd to always send file:// URIs, and aligns tests/docs with the new URI and failure semantics.

Sequence diagram for rename-symbol flow with file URI normalization and structured failures

sequenceDiagram
    actor User
    participant WeaverdRefactor as WeaverdRefactorDispatcher
    participant RustPlugin as RustAnalyzerPlugin
    participant Adapter as RustAnalyzerLspAdapter

    User->>WeaverdRefactor: act refactor rename-symbol(file)
    WeaverdRefactor->>WeaverdRefactor: to_file_uri(path)
    WeaverdRefactor->>RustPlugin: PluginRequest{ uri = file://path, file_payload }

    RustPlugin->>RustPlugin: execute_rename(request)
    RustPlugin->>RustPlugin: normalize_request_uri(arguments.uri)
    alt URI not file:// or invalid path
        RustPlugin->>RustPlugin: PluginFailure::with_reason(message, IncompletePayload)
        RustPlugin->>RustPlugin: failure_response(failure)
        RustPlugin-->>WeaverdRefactor: PluginResponse::failure(reason_code = IncompletePayload)
        WeaverdRefactor-->>User: Error response
    else URI valid and matches payload path
        RustPlugin->>Adapter: rename_symbol(path, ByteOffset, new_name)
        alt Adapter returns error (e.g. symbol not found)
            RustPlugin->>RustPlugin: PluginFailure::plain(error.to_string())
            RustPlugin->>RustPlugin: failure_response(failure)
            RustPlugin-->>WeaverdRefactor: PluginResponse::failure(no reason_code)
            WeaverdRefactor-->>User: Error response
        else Adapter returns modified content
            RustPlugin->>RustPlugin: build_search_replace_patch
            RustPlugin-->>WeaverdRefactor: PluginResponse::success(Diff)
            WeaverdRefactor-->>User: Refactor succeeded
        end
    end
Loading

Class diagram for PluginFailure, failure_response, and URI normalization

classDiagram
    class PluginFailure {
        -String message
        -Option_ReasonCode reason_code
        +plain(message: String) PluginFailure
        +with_reason(message: String, reason: ReasonCode) PluginFailure
        +message() String
        +reason_code() Option_ReasonCode
    }

    class ReasonCode {
    }

    class PluginResponse {
        +failure(diagnostics: Vec_PluginDiagnostic_) PluginResponse
    }

    class PluginDiagnostic {
        +new(severity: DiagnosticSeverity, message: String) PluginDiagnostic
        +with_reason_code(reason_code: ReasonCode) PluginDiagnostic
    }

    class DiagnosticSeverity {
    }

    class FailureModule {
        +failure_response(failure: PluginFailure) PluginResponse
    }

    class RustAnalyzerAdapterError {
        <<enum>>
        InvalidPath(message: String)
        OtherVariants
    }

    class UriNormalization {
        +normalize_request_uri(uri: String) Result_String_RustAnalyzerAdapterError_
    }

    class PathUtils {
        +path_to_slash(path: Path) String
        +validate_relative_path(path: Path) Result_Void_RustAnalyzerAdapterError_
    }

    class WeaverdRefactorDispatch {
        +to_file_uri(path: String) String
        +apply_rename_symbol_mapping(plugin_args: Map_String_Value_, file: String)
    }

    PluginFailure --> ReasonCode : uses
    FailureModule --> PluginFailure : parameter
    FailureModule --> PluginResponse : builds
    FailureModule --> PluginDiagnostic : builds
    PluginDiagnostic --> DiagnosticSeverity : uses
    PluginDiagnostic --> ReasonCode : optional

    UriNormalization --> RustAnalyzerAdapterError : error
    UriNormalization --> PathUtils : uses

    WeaverdRefactorDispatch --> UriNormalization : via plugin request
    WeaverdRefactorDispatch --> WeaverdRefactorDispatch : to_file_uri used when building uri

    UriNormalization ..> PluginFailure : mapped to IncompletePayload
    PathUtils ..> RustAnalyzerAdapterError : may return

    note for FailureModule "Represents contents of failure.rs: PluginFailure and failure_response"
Loading

File-Level Changes

Change Details Files
Centralize plugin failure modeling and response conversion for the rust-analyzer plugin.
  • Move PluginFailure type and its Display implementation into a new failure module with plain() and with_reason() constructors.
  • Expose a failure_response helper that converts PluginFailure into protocol PluginResponse values with optional ReasonCode.
  • Update rust-analyzer plugin code to depend on the new failure module instead of in-file failure handling.
crates/weaver-plugin-rust-analyzer/src/failure.rs
crates/weaver-plugin-rust-analyzer/src/lib.rs
Normalize and validate file:// URIs in the rename flow and adjust failure semantics.
  • Introduce normalize_request_uri(uri) that enforces file:// prefix, validates relative paths via validate_relative_path, and normalizes them with path_to_slash.
  • Use normalize_request_uri in execute_rename to compare the normalized URI path against the FilePayload path, mapping mismatches to PluginFailure with ReasonCode::IncompletePayload.
  • Change adapter rename errors to map to plain PluginFailure (no ReasonCode) while keeping NoChange failures tagged with ReasonCode::SymbolNotFound.
crates/weaver-plugin-rust-analyzer/src/lib.rs
Have weaverd construct and propagate file:// URIs to plugins.
  • Add a to_file_uri(path) helper that prefixes paths with file:// when building plugin_args for rename-symbol requests.
  • Ensure the refactor dispatcher overwrites any pre-existing uri argument with the file:// form derived from --file.
  • Update refactor dispatch tests to assert that file:// URIs (e.g., file://notes.txt) are sent to the plugin.
crates/weaverd/src/dispatch/act/refactor/mod.rs
crates/weaverd/src/dispatch/act/refactor/tests.rs
Align tests with file:// URI usage and new failure reason codes.
  • Update rust-analyzer unit tests to use file://src/main.rs URIs and add a RelativeUri scenario that accepts equivalent relative URIs (file://./src/main.rs).
  • Tighten failure assertions so that NoChange failures expect ReasonCode::SymbolNotFound, URI mismatches expect ReasonCode::IncompletePayload, and adapter errors have no reason code.
  • Adjust BDD tests and step definitions to recognize the new symbol_not_found reason code string.
crates/weaver-plugin-rust-analyzer/src/tests/mod.rs
crates/weaver-plugin-rust-analyzer/src/tests/behaviour.rs
crates/weaver-plugin-rust-analyzer/tests/features/rust_analyzer_plugin.feature
Update documentation and user guide examples to reflect current CLI and capability formatting.
  • Tidy execplan markdown wrapping and wording around help/version behaviour, decisions, and risks without changing behaviour.
  • Clarify the user guide’s Version section formatting and switch capability examples to array-style notation, e.g., capabilities = ["rename-symbol"].
  • Mark the rust plugin execplan as completed and adjust language to talk about the CLI and BDD tests explicitly.
docs/execplans/2-2-3-top-level-version-output.md
docs/users-guide.md
docs/execplans/5-2-3-update-rust-plugin-to-declare-rename-symbol.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 11, 2026

Summary by CodeRabbit

  • New Features

    • Rename requests now use file:// URIs throughout the flow.
  • Bug Fixes

    • Improved URI validation, error mapping and payload handling.
    • Failure diagnostics now include explicit reason codes.
  • Refactor

    • Centralised failure handling and unified URI normalisation.
  • Tests

    • Expanded unit, BDD and dispatch-layer tests covering URI variants, argument validation and failure reasons.
  • Documentation

    • Updated user guide, exec plans and roadmap for wording and examples.

Walkthrough

Refactor failure handling into a new crate-private failure module; centralise PluginFailure and failure_response; normalise plugin URIs to file:// form and validate/strip them; update weaverd to emit file URIs; update tests and docs to expect file URIs and include reason codes in diagnostics.

Changes

Cohort / File(s) Summary
Failure Handling
crates/weaver-plugin-rust-analyzer/src/failure.rs, crates/weaver-plugin-rust-analyzer/src/lib.rs
Add crate-private PluginFailure and failure_response in failure.rs; remove the in-file PluginFailure and local failure_response from lib.rs; replace local failure construction with PluginFailure::plain/with_reason and call failure_response.
URI Normalisation & Helpers
crates/weaver-plugin-rust-analyzer/src/lib.rs, crates/weaverd/src/dispatch/act/refactor/mod.rs
Introduce normalize_request_uri, invalid_file_uri_error, strip_file_uri_root in plugin; add to_file_uri(path) in weaverd; change rename payloads to use file:// URIs and propagate URI construction errors by updating function signatures to return Result.
Tests — behaviour & dispatch
crates/weaver-plugin-rust-analyzer/src/tests/behaviour.rs, crates/weaver-plugin-rust-analyzer/src/tests/dispatch_layer.rs, crates/weaver-plugin-rust-analyzer/src/tests/argument_validation.rs
Switch test URIs to file:// form; add argument-validation test matrix; assert failure reason codes (e.g. symbol_not_found, IncompletePayload, OperationNotSupported) in diagnostics.
Tests — support & refactor
crates/weaver-plugin-rust-analyzer/src/tests/support.rs, crates/weaver-plugin-rust-analyzer/src/tests/mod.rs, crates/weaverd/src/dispatch/act/refactor/tests.rs
Introduce test support utilities and MockAdapter; replace in-file test scaffolding with helpers; update weaverd tests to expect file URIs.
Docs & Execplans
docs/execplans/..., docs/users-guide.md, docs/roadmap.md
Adjust wording and status lines; represent actuator capabilities as arrays; add doc/lint/format checks to roadmap and execplans; minor reflowing and phrasing updates.
Features (BDD)
crates/weaver-plugin-rust-analyzer/tests/features/rust_analyzer_plugin.feature
Add assertion to check failure reason code symbol_not_found when adapter returns unchanged content.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Weaverd
    participant Plugin
    participant Adapter
    rect rgba(200,220,255,0.5)
    Client->>Weaverd: Request rename (path)
    Weaverd->>Weaverd: to_file_uri(path) -> "file://..."
    Weaverd->>Plugin: PluginRequest { uri: "file://..." }
    Plugin->>Plugin: normalize_request_uri(uri)
    alt invalid URI
        Plugin->>Plugin: PluginFailure::plain(...)
        Plugin->>Weaverd: failure_response(PluginFailure)
    else valid URI
        Plugin->>Adapter: rename(FilePayload{path}, offset, new_name)
        Adapter-->>Plugin: Result (changed / unchanged / error)
        Plugin->>Plugin: map result -> PluginResponse (attach ReasonCode if needed)
        Plugin-->>Weaverd: PluginResponse
    end
    Weaverd-->>Client: Final result / diagnostic
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🔧 Failures gathered in one place,
file:// paths now take their place,
Tests hum with mocks on cue,
Diagnostics show the reason true,
Quick tidy code — a tidy grace!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main changes: refactoring plugin failure handling, normalising file URIs, and updating tests accordingly.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the structured failure model, URI normalisation, test updates, and documentation changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-rename-symbol-uri-and-docs-uqgz9w

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

@leynos leynos marked this pull request as ready for review March 11, 2026 11:44
sourcery-ai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0d33b9f76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/weaver-plugin-rust-analyzer/src/lib.rs
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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/weaver-plugin-rust-analyzer/src/failure.rs`:
- Around line 9-13: Implement std::error::Error for PluginFailure by deriving or
implementing Error (prefer using thiserror::Error) on the PluginFailure struct
so it becomes a proper error type callers can use with `?` and error utilities;
update the struct definition for PluginFailure to derive Error (and
Debug/Display via thiserror) and remove the manual Display implementation if
present, and ensure the ReasonCode enum (if used for error details) implements
or derives Display/Debug as required for the derived Error implementation to
compile.

In `@crates/weaver-plugin-rust-analyzer/src/lib.rs`:
- Around line 344-353: normalize_request_uri currently strips "file://" naively;
instead parse the URI with the url crate: call Url::parse(uri), ensure scheme ==
"file" and convert to a filesystem path via Url::to_file_path() (or extract and
percent-decode the path component if needed), map parse/validation failures into
RustAnalyzerAdapterError::InvalidPath, then pass the resulting Path (or PathBuf)
to validate_relative_path and path_to_slash as before; reference
normalize_request_uri, RustAnalyzerAdapterError, validate_relative_path, and
path_to_slash when making the change.
🪄 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: da221aec-950a-433b-913e-7a77f9330389

📥 Commits

Reviewing files that changed from the base of the PR and between a72c086 and a0d33b9.

📒 Files selected for processing (10)
  • crates/weaver-plugin-rust-analyzer/src/failure.rs
  • crates/weaver-plugin-rust-analyzer/src/lib.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/behaviour.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/mod.rs
  • crates/weaver-plugin-rust-analyzer/tests/features/rust_analyzer_plugin.feature
  • crates/weaverd/src/dispatch/act/refactor/mod.rs
  • crates/weaverd/src/dispatch/act/refactor/tests.rs
  • docs/execplans/2-2-3-top-level-version-output.md
  • docs/execplans/5-2-3-update-rust-plugin-to-declare-rename-symbol.md
  • docs/users-guide.md

Comment thread crates/weaver-plugin-rust-analyzer/src/failure.rs Outdated
Comment thread crates/weaver-plugin-rust-analyzer/src/lib.rs
…sing

- Use `url::Url` to parse and validate file:// URIs instead of manual string stripping
- Reject URIs with authorities or invalid schemes explicitly
- Normalize and strip root directory from file paths safely
- Update related tests to use valid file:/// URIs
- Replace manual Display impl on PluginFailure with thiserror::Error derive
- Use Url for file URI creation in weaverd refactor module

These changes improve correctness and robustness around URI handling in the rust-analyzer plugin, ensuring only valid local file URIs without authority components are accepted and normalized consistently.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Refactor: structured plugin failures and file URI normalization Address review comments; finalize plugin failures and URI normalization Mar 11, 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: 4

Caution

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

⚠️ Outside diff range comments (1)
crates/weaver-plugin-rust-analyzer/src/tests/mod.rs (1)

1-420: 🧹 Nitpick | 🔵 Trivial

File length at guideline boundary.

At 420 lines, this file slightly exceeds the 400-line guideline. The current structure is acceptable, but decompose into separate test modules (e.g., argument_validation.rs, dispatch_layer.rs) if further tests are added.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/weaver-plugin-rust-analyzer/src/tests/mod.rs` around lines 1 - 420,
This file exceeds the 400-line guideline; split tests into focused modules to
keep each file small. Move the argument-validation related tests and helpers
(functions and fixtures like rename_arguments, request_with_args, all mutate
helpers, and the rename_argument_validation test) into a new module/file (e.g.,
argument_validation) and move the stdin/stdout dispatch layer tests and helpers
(valid_request_json, dispatch_stdin, run_with_adapter_dispatch_layer,
failure_responses_include_reason_codes, request_with_path, and related cases)
into a separate dispatch_layer module/file; retain shared mocks (mock! Adapter,
adapter_returning, adapter_unused, adapter_returning_with_path) either by
placing them in a common test utils module or re-exporting them so both new
files can use them, and update mod declarations (mod behaviour) and test imports
accordingly so tests like rename_non_mutating_or_error_returns_failure and
rename_rejects_empty_or_curdir_path remain in the most relevant module.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/weaverd/src/dispatch/act/refactor/mod.rs`:
- Around line 328-334: Change to_file_uri to return Result<String,
url::ParseError> instead of unwrapping: parse the base with
Url::parse("?file:///")? (or Url::parse("file:///")?) and use
url.path_segments_mut().expect("file URL cannot be a
base").extend(path.split('/')) so each component is percent-encoded safely, then
Ok(url.to_string()); remove all .expect()/.unwrap() uses. Update the call site
in apply_rename_symbol_mapping to propagate or map the url::ParseError into the
existing DispatchError (e.g., using ? or .map_err(|e| DispatchError::...)) so
errors are handled rather than panicking.

In `@docs/execplans/2-2-3-top-level-version-output.md`:
- Around line 184-186: The example text currently uses an absolute,
workstation-specific path (`/home/user/project/Cargo.toml`); change that to a
repo-relative reference such as "the workspace Cargo.toml (repository root)" or
"Cargo.toml in the workspace root" so the sentence reads like: The workspace
version is `0.1.0` (set in the workspace Cargo.toml) — keep the rest of the
sentence and ensure no machine-specific paths remain.
- Around line 503-514: Add a short caption line immediately before the markdown
table that begins with the header row "| File | Change | Lines before | Lines
after |" (e.g., "Table 1. File change summary.") so the table is explicitly
captioned per documentation guidelines; update the doc content near that table
(the markdown block in docs/execplans/2-2-3-top-level-version-output.md that
contains the listed file-change rows) to insert the caption as a plain paragraph
placed directly above the table header.
- Around line 409-415: The documentation stages are missing Markdown validation
and formatting steps; update the plan (Stage H / the
docs/execplans/2-2-3-top-level-version-output.md and docs/roadmap.md entries for
2.2.3) to run make markdownlint and make fmt as part of the verification/quality
gate steps so Markdown regressions are caught; add explicit steps that invoke
"make markdownlint" and "make fmt" (and ensure they run alongside the existing
Rust quality gates) and mark those checklist items as done for the 2.2.3 roadmap
entries.

---

Outside diff comments:
In `@crates/weaver-plugin-rust-analyzer/src/tests/mod.rs`:
- Around line 1-420: This file exceeds the 400-line guideline; split tests into
focused modules to keep each file small. Move the argument-validation related
tests and helpers (functions and fixtures like rename_arguments,
request_with_args, all mutate helpers, and the rename_argument_validation test)
into a new module/file (e.g., argument_validation) and move the stdin/stdout
dispatch layer tests and helpers (valid_request_json, dispatch_stdin,
run_with_adapter_dispatch_layer, failure_responses_include_reason_codes,
request_with_path, and related cases) into a separate dispatch_layer
module/file; retain shared mocks (mock! Adapter, adapter_returning,
adapter_unused, adapter_returning_with_path) either by placing them in a common
test utils module or re-exporting them so both new files can use them, and
update mod declarations (mod behaviour) and test imports accordingly so tests
like rename_non_mutating_or_error_returns_failure and
rename_rejects_empty_or_curdir_path remain in the most relevant module.
🪄 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: 76a0dd0d-6bc4-4d25-88ff-074f4733ef57

📥 Commits

Reviewing files that changed from the base of the PR and between a0d33b9 and be81c8f.

📒 Files selected for processing (7)
  • crates/weaver-plugin-rust-analyzer/src/failure.rs
  • crates/weaver-plugin-rust-analyzer/src/lib.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/behaviour.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/mod.rs
  • crates/weaverd/src/dispatch/act/refactor/mod.rs
  • crates/weaverd/src/dispatch/act/refactor/tests.rs
  • docs/execplans/2-2-3-top-level-version-output.md

Comment thread crates/weaverd/src/dispatch/act/refactor/mod.rs Outdated
Comment thread docs/execplans/2-2-3-top-level-version-output.md Outdated
Comment thread docs/execplans/2-2-3-top-level-version-output.md
Comment thread docs/execplans/2-2-3-top-level-version-output.md
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Mar 11, 2026

@coderabbitai Have the following now been resolved?

Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity.

Please address the comments from this code review:

## Overall Comments
- The new `normalize_request_uri` helper assumes `file://` URIs are plain paths and does not handle URL encoding (e.g. spaces, non-ASCII); if clients might send proper URIs, consider decoding percent-encoded segments or explicitly constraining/validating the accepted URI form.
- In `adapter_returning`, the assertions on `offset` and `new_name` make the helper tightly coupled to a specific call pattern; if you intend to reuse this helper across scenarios, consider moving those assertions into the specific test or adding parameters so different expectations can be expressed.

## Individual Comments

### Comment 1
<location path="crates/weaver-plugin-rust-analyzer/src/tests/mod.rs" line_range="194" />
<code_context>
     NoChange,
     AdapterError,
     UriMismatch,
+    RelativeUri,
 }

</code_context>
<issue_to_address>
**issue (testing):** Add an explicit failure scenario for invalid or non-file:// URIs to fully exercise the new URI normalization/validation path

The new `normalize_request_uri` logic maps invalid URIs (e.g. without `file://`) to `PluginFailure` with `ReasonCode::IncompletePayload`, but the tests only cover a valid relative URI and a mismatched-but-valid URI. Please add a `FailureScenario` (e.g. `InvalidUri`) where `uri` is something like `"src/main.rs"` or `"http://src/main.rs"`, and assert that:
- `execute_request` returns `Err`,
- the error message mentions the invalid URI requirement (e.g. `"uri argument must be a file:// URI"`), and
- `err.reason_code() == Some(ReasonCode::IncompletePayload)`.

This will exercise the malformed-URI path and protect against regressions in the new validation behaviour.
</issue_to_address>

### Comment 2
<location path="crates/weaver-plugin-rust-analyzer/src/tests/mod.rs" line_range="37-39" />
<code_context>
         .expect_rename()
         .once()
-        .return_once(move |_file, _offset, _new_name| result);
+        .return_once(move |_file, offset, new_name| {
+            assert_eq!(offset, ByteOffset::new(3));
+            assert_eq!(new_name, "new_name");
+            result
+        });
</code_context>
<issue_to_address>
**suggestion (testing):** Consider asserting on the normalized file path passed to the adapter in the RelativeUri success case

In the `RelativeUri` case, the key behavior is that `file://./src/main.rs` is normalized to match the payload path before reaching the adapter, but the test currently only asserts `offset` and `new_name`.

To better verify this end-to-end, have the adapter closure assert that `file` equals the normalized path (e.g. `"src/main.rs"`) and ensure the `RelativeUri` scenario uses this adapter. That way the test confirms both success and that the adapter receives the expected normalized path.

Suggested implementation:

```rust
    adapter
        .expect_rename()
        .once()
        .return_once(move |file, offset, new_name| {
            // Verify the adapter receives the normalized file path.
            assert_eq!(file, "src/main.rs");
            assert_eq!(offset, ByteOffset::new(3));
            assert_eq!(new_name, "new_name");
            result
        });
    adapter
}

```

```rust
    let mut arguments = HashMap::new();
    arguments.insert(
        String::from("uri"),
        // Use a relative URI to exercise the RelativeUri normalization path.
        serde_json::Value::String(String::from("file://./src/main.rs")),
    );
    arguments.insert(

```
</issue_to_address>

### Comment 3
<location path="docs/execplans/2-2-3-top-level-version-output.md" line_range="91" />
<code_context>
+  medium. Likelihood: low. Mitigation: The existing test (lines 28-54)
+  intentionally uses combined stdout+stderr output
+  (`format!("{stdout}{stderr}")`) and does not assert on exit code. Its comment
+  states, "We intentionally avoid asserting on the exit code so this test
+  remains valid if --help is later changed to exit 0." No change is needed.

</code_context>
<issue_to_address>
**issue (review_instructions):** This sentence includes the first-person pronoun "We" inside the quoted comment, which violates the no first/second person pronouns requirement.

To comply with the style guide, rephrase this quoted comment to avoid first-person pronouns. For example:

- Its comment states, "The test intentionally avoids asserting on the exit code so it remains valid if --help is later changed to exit 0."

This preserves the meaning while removing the first-person "We".

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Avoid 2nd person or 1st person pronouns ("I", "you", "we").

</details>
</issue_to_address>

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 11, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check Comment 1 & 2: FailureScenario enum and adapter_returning/adapter_returning_with_path in tests/mod.rs
grep -n "FailureScenario\|InvalidUri\|RelativeUri\|adapter_returning\|assert_eq!(file\|assert_eq!(offset\|assert_eq!(new_name\|normalize\|file://\." \
    crates/weaver-plugin-rust-analyzer/src/tests/mod.rs | head -80

echo "---"
# Check Comment 3: pronoun in docs file
grep -n "We intentionally\|intentionally avoid\|The test intentionally" \
    docs/execplans/2-2-3-top-level-version-output.md

Length of output: 1937


🏁 Script executed:

#!/bin/bash
# Check URL encoding handling in normalize_request_uri
grep -n "percent\|decode\|url::Url\|Url::parse\|path_segments\|to_file_path\|normalize_request_uri" \
    crates/weaver-plugin-rust-analyzer/src/lib.rs | head -40

echo "---"
# Show the full normalize_request_uri function
ast-grep --pattern 'fn normalize_request_uri($_) -> $_ {
  $$$
}'

Length of output: 1457


@leynos: Yes, all items are resolved. Here is the breakdown:

Overall comments

  • URL encoding: normalize_request_uri now uses url::Url::parse followed by .to_file_path(), which the url crate automatically percent-decodes. The concern is addressed.
  • Adapter coupling: The PR introduces adapter_returning_with_path(result, Option<…>) and makes adapter_returning delegate to it with None. This parametrises the path assertion without tightening the helper to a single call pattern and adds no unnecessary complexity. Resolved cleanly; no annulment required.

Individual comments

# File Status
1 tests/mod.rs InvalidUri variant added to FailureScenario (line 207), test case wired at line 215, and the invalid-URI branch exercised at lines 232, 244, and 287. ✅
2 tests/mod.rs adapter_returning_with_path (line 37) now asserts file.path(), offset, and new_name; the RelativeUri case uses it at line 245. ✅
3 docs/execplans/2-2-3-top-level-version-output.md Line 91 now reads "The test intentionally avoids asserting on the exit code so this…" — the first-person "We" has been removed. ✅

… dispatch layer tests

- Introduce extensive unit tests for argument validation in the rust-analyzer plugin
- Add stdin/stdout dispatch layer tests to ensure robustness of plugin request handling
- Refactor test modules to separate support, argument validation, and dispatch tests
- Enhance URI handling in rename-symbol mapping with error propagation
- Update documentation with markdownlint and formatting improvements

This change improves reliability by validating plugin request arguments and verifying dispatch behavior under various input scenarios.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/weaver-plugin-rust-analyzer/src/tests/argument_validation.rs`:
- Around line 65-97: Add a test case covering the omitted new_name field by
defining a remover function (e.g., remove_new_name(arguments: &mut
HashMap<String, serde_json::Value>) that calls arguments.remove("new_name")) and
adding the rstest entry #[case::missing_new_name(remove_new_name as fn(&mut _),
Some("new_name"))] into the rename_argument_validation cases table (alongside
other #[case::...] entries); this will exercise the branch that should return
ReasonCode::IncompletePayload when new_name is absent—add the remover function
near the other helper mutators and run the unit tests.

In `@crates/weaver-plugin-rust-analyzer/src/tests/support.rs`:
- Around line 84-93: The helper request_with_path currently only updates the
FilePayload path but leaves arguments["uri"] hard-coded to file:///src/main.rs;
update request_with_path (and the PluginRequest::with_arguments invocation) to
derive the "uri" argument from the given path (e.g. build a file:// URI from the
path string) so the payload PathBuf and arguments["uri"] are consistent for the
"rename-symbol" request and FilePayload; alternatively change the signature to
accept both path and uri and pass both through to FilePayload and arguments to
avoid mismatch.

In `@docs/execplans/2-2-3-top-level-version-output.md`:
- Around line 427-439: Update the Markdown fenced code blocks that are marked
with ```sh to ```bash for any blocks that use the Bash-specific `set -o
pipefail` construct; specifically change the three occurrences of the ```sh
fence surrounding the blocks that include `set -o pipefail` (the two "After
making edits"/"After making all edits" blocks and the third block at lines
476-477) so the fence identifier is `bash` instead of `sh`.

In `@docs/roadmap.md`:
- Around line 176-177: Remove the redundant sub-task "- [x] Validate the
documentation updates with `make markdownlint` and `make fmt` alongside the Rust
quality gates" from the roadmap so acceptance criteria remain the single source
of truth; update the checklist to omit that procedural validation item and keep
only the acceptance criteria that list the required make targets (`make
check-fmt`, `make markdownlint`, `make fmt`, `make lint`, `make test`) to
express the delivered capability.
🪄 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: 4154fef9-7f55-424a-94e0-8c72d8cc9216

📥 Commits

Reviewing files that changed from the base of the PR and between be81c8f and 84e298f.

📒 Files selected for processing (7)
  • crates/weaver-plugin-rust-analyzer/src/tests/argument_validation.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/dispatch_layer.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/mod.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/support.rs
  • crates/weaverd/src/dispatch/act/refactor/mod.rs
  • docs/execplans/2-2-3-top-level-version-output.md
  • docs/roadmap.md

Comment thread crates/weaver-plugin-rust-analyzer/src/tests/argument_validation.rs
Comment thread crates/weaver-plugin-rust-analyzer/src/tests/support.rs
Comment thread docs/execplans/2-2-3-top-level-version-output.md Outdated
Comment thread docs/roadmap.md Outdated
…st helpers

- Added remove_new_name helper and corresponding test case to argument_validation.rs
- Enhanced request_with_path to include URI argument formatted as file URI
- Added file_uri_for_path helper creating proper file URIs with url crate
- Minor fixes in test support code for clearer argument handling

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Address review comments; finalize plugin failures and URI normalization Refactor plugin failures and file URI normalization; update tests Mar 11, 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.

♻️ Duplicate comments (1)
docs/execplans/2-2-3-top-level-version-output.md (1)

423-439: ⚠️ Potential issue | 🟡 Minor

Replace the workstation-specific workspace path.

Remove /home/user/project. State that the commands run from the workspace
root, so the execplan remains portable across checkouts.

🛠️ Proposed fix
-All commands run from workspace root `/home/user/project`.
+All commands run from the workspace root.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/execplans/2-2-3-top-level-version-output.md` around lines 423 - 439,
Remove the hard-coded workstation path `/home/user/project` and replace it with
a generic reference to the workspace root in the two command blocks; update the
surrounding text to read something like "All commands run from the workspace
root." and ensure both Stage A and Stage B-H examples no longer mention the
absolute path so the execplan is portable across checkouts (look for the two
occurrences of the path in the command header lines above the Stage A and Stage
B-H blocks).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@docs/execplans/2-2-3-top-level-version-output.md`:
- Around line 423-439: Remove the hard-coded workstation path
`/home/user/project` and replace it with a generic reference to the workspace
root in the two command blocks; update the surrounding text to read something
like "All commands run from the workspace root." and ensure both Stage A and
Stage B-H examples no longer mention the absolute path so the execplan is
portable across checkouts (look for the two occurrences of the path in the
command header lines above the Stage A and Stage B-H blocks).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e23a2eec-51cc-4369-b625-a849be497163

📥 Commits

Reviewing files that changed from the base of the PR and between 84e298f and 2a1d620.

📒 Files selected for processing (4)
  • crates/weaver-plugin-rust-analyzer/src/tests/argument_validation.rs
  • crates/weaver-plugin-rust-analyzer/src/tests/support.rs
  • docs/execplans/2-2-3-top-level-version-output.md
  • docs/roadmap.md

@leynos leynos merged commit 443a10b into main Mar 11, 2026
11 checks passed
@leynos leynos deleted the refactor-rename-symbol-uri-and-docs-uqgz9w branch March 11, 2026 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant