Skip to content

ExternalPackAdapter.convertComponent() calls findProjectRoot() on every access #217

@bguidolim

Description

@bguidolim

Context

Follow-up from #176 (fixed in PR #216 for pack-level supplementaryDoctorChecks).

ExternalPackAdapter.convertComponent() calls ProjectDetector.findProjectRoot() for each component that has inline doctorChecks defined. These checks are baked into ComponentDefinition.supplementaryChecks as concrete [any DoctorCheck] instances at construction time — the projectRoot used during creation is frozen into the check structs.

This means:

  1. Every access to pack.components triggers findProjectRoot() for each component with doctorChecks
  2. Multi-scope doctor runs may use a stale/incorrect projectRoot (e.g., global scope should use nil, but picks up the project root from CWD)
  3. allDoctorChecks(projectRoot:) returns derived + supplementaryChecks — only derived checks use the scope-appropriate projectRoot; the baked-in supplementary checks do not

Why this is harder than #176

  • ComponentDefinition.supplementaryChecks is a let stored property ([any DoctorCheck])
  • Two consumers access it: allDoctorChecks(projectRoot:) (doctor runs) and ComponentExecutor (install-time "already installed?" checks)
  • components is a TechPack protocol property used in many contexts beyond doctor — adding a projectRoot parameter would be a larger refactor

Proposal

Change ComponentDefinition.supplementaryChecks from [any DoctorCheck] to @Sendable (URL?) -> [any DoctorCheck] (a factory closure). Call the factory from allDoctorChecks(projectRoot:) so each doctor run gets scope-correct checks. ComponentExecutor would pass nil or the appropriate project root.

Impact

Low — same as #176. Pack count and component count are small in practice and the walk-up is fast. This is a code quality improvement, not a performance fix.

Files involved

  • Sources/mcs/TechPack/Component.swift — change supplementaryChecks type
  • Sources/mcs/ExternalPack/ExternalPackAdapter.swift:157 — provide closure instead of eager checks
  • Sources/mcs/Doctor/DerivedDoctorChecks.swift:46-49 — call factory with projectRoot
  • Sources/mcs/Install/ComponentExecutor.swift:338 — pass appropriate projectRoot

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for newcomerstech-debtTechnical debt and code quality improvements

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions