Skip to content

refactor: introduce LintReader interface, decouple linter from sdk/mpr#5

Open
retran wants to merge 1 commit intopr1-quick-winsfrom
pr2-reader-migration
Open

refactor: introduce LintReader interface, decouple linter from sdk/mpr#5
retran wants to merge 1 commit intopr1-quick-winsfrom
pr2-reader-migration

Conversation

@retran
Copy link
Copy Markdown
Owner

@retran retran commented Apr 23, 2026

Why

The linter and executor packages import sdk/mpr directly for *mpr.Reader, coupling them to the concrete SQLite implementation. This blocks the WASM build (PR #7 series) where sdk/mpr is unavailable, and prevents testing with mock backends. Introducing a LintReader interface breaks this dependency using Go's implicit interface satisfaction — zero changes needed in the 10+ linter rule files.

Summary

  • Define LintReader interface in mdl/linter/context.go with 7 methods matching both *mpr.Reader and MprBackend signatures
  • Replace concrete *mpr.Reader dependency with LintReader interface throughout linter and executor packages
  • Remove Reader() methods and readerProvider interface from executor — callers now pass Backend() directly
  • Zero sdk/mpr imports remain in mdl/linter/ and mdl/executor/ production code

Stacked on

Test

make build && make test && make lint-go — all pass

Copilot AI review requested due to automatic review settings April 23, 2026 15:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a linter.LintReader interface to decouple linting/execution code from the concrete sdk/mpr.Reader, routing lint rules through a backend-compatible reader abstraction instead.

Changes:

  • Add LintReader to mdl/linter/context.go and thread it through LintContext.
  • Update lint rules to consume LintReader instead of *mpr.Reader.
  • Remove Executor.Reader() / ExecContext.Reader() and update lint entrypoints to pass Backend() directly.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
mdl/linter/rules/page_navigation_security.go Switch rule helper to accept linter.LintReader instead of *mpr.Reader.
mdl/linter/context.go Define LintReader; update LintContext construction and Reader() accessor to use it.
mdl/executor/executor.go Remove deprecated Reader(); add Backend() accessor for callers.
mdl/executor/exec_context.go Remove deprecated Reader() from ExecContext.
mdl/executor/cmd_lint.go Construct LintContext with ctx.Backend directly.
cmd/mxcli/cmd_report.go Construct LintContext with exec.Backend(); remove Reader() plumbing.
cmd/mxcli/cmd_lint.go Construct LintContext with exec.Backend(); remove Reader() plumbing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mdl/executor/executor.go
}

// Backend returns the full backend, or nil if not connected.
func (e *Executor) Backend() backend.FullBackend {
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

Backend() is documented as returning nil when not connected, but it currently returns e.backend even if IsConnected() is false. This can happen after a failed CONNECT where the previous backend was disconnected but ctx.Backend was never cleared, leaving a non-nil, disconnected backend reachable via Backend(). Either update the implementation to return nil unless e.backend != nil && e.backend.IsConnected(), or adjust the doc comment to reflect the actual behavior.

Suggested change
func (e *Executor) Backend() backend.FullBackend {
func (e *Executor) Backend() backend.FullBackend {
if e.backend == nil || !e.backend.IsConnected() {
return nil
}

Copilot uses AI. Check for mistakes.
Comment thread mdl/executor/executor.go
Comment on lines 310 to +318
// IsConnected returns true if connected to a project.
func (e *Executor) IsConnected() bool {
return e.backend != nil && e.backend.IsConnected()
}

// Backend returns the full backend, or nil if not connected.
func (e *Executor) Backend() backend.FullBackend {
return e.backend
}
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

Removing Executor.Reader() breaks -tags integration tests that still call it (e.g. mdl/executor/roundtrip_helpers_test.go and roundtrip_doctype_test.go call env.executor.Reader().ProjectVersion()). Update those call sites to use env.executor.Backend().ProjectVersion() (or similar) so make test-integration continues to compile/run.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mdl/executor/executor.go
func (e *Executor) Backend() backend.FullBackend {
return e.backend
}

Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

Removing Executor.Reader() breaks any remaining call sites (notably the integration tests under mdl/executor with the integration build tag) that still call env.executor.Reader().ProjectVersion() / similar. Please update those callers to use Executor.Backend().ProjectVersion() (or, if a test truly needs the underlying SDK reader, type-assert on the backend for an MprReader() accessor) so make test-integration continues to compile and run.

Suggested change
// Reader returns the backend for backward compatibility with older callers.
// Prefer Backend() in new code.
func (e *Executor) Reader() backend.FullBackend {
return e.Backend()
}

Copilot uses AI. Check for mistakes.
@retran retran force-pushed the pr2-reader-migration branch from dcf76c0 to 0091e56 Compare April 23, 2026 20:27
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.

2 participants