Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recategorize controller dependencies as devDependencies if only imports are messaging system-related types #3607

Merged
merged 8 commits into from
Dec 22, 2023

Conversation

MajorLift
Copy link
Contributor

@MajorLift MajorLift commented Dec 1, 2023

Explanation

  • Controller dependencies that are used via the messaging system should be listed under peerDependencies to ensure that we see warnings for incompatible versions.
  • A peerDependencies controller that is not invoked directly at runtime shouldn't be included under dependencies. Any type imports will still resolve because we can assume the controller package will be installed.

References

Changelog

@metamask/accounts-controller

Fixed

  • Add @metamask/snaps-controllers as a peer dependency in addition to a dev dependency (#3607)

@metamask/ens-controller

Fixed

  • Recategorize @metamask/network-controller as a dev dependency and peer dependency (#3607)

@metamask/keyring-controller

Fixed

  • Recategorize @metamask/preferences-controller as a dev dependency and peer dependency (#3607)

@metamask/permission-controller

Fixed

  • Recategorize @metamask/approval-controller as a dev dependency and peer dependency (#3607)

@metamask/queued-request-controller

Fixed

  • Recategorize @metamask/approval-controller, @metamask/network-controller, @metamask/selected-network-controller as dev dependencies (#3607)

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

@MajorLift MajorLift added dependencies Pull requests that update a dependency file team-wallet-framework labels Dec 1, 2023
@MajorLift MajorLift self-assigned this Dec 1, 2023
@MajorLift MajorLift requested a review from a team as a code owner December 1, 2023 20:14
@MajorLift MajorLift changed the title [accounts-controller] Restore `@metamask/{keyring-controller,snap-controllers} as deps [accounts-controller] Restore @metamask/{keyring-controller,snap-controllers} as deps Dec 1, 2023
@MajorLift MajorLift changed the title [accounts-controller] Restore @metamask/{keyring-controller,snap-controllers} as deps [accounts-controller] Restore @metamask/{keyring-controller,snaps-controllers} as deps Dec 1, 2023
@legobeat
Copy link
Contributor

legobeat commented Dec 1, 2023

Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

One thing but otherwise looks good!

packages/accounts-controller/CHANGELOG.md Outdated Show resolved Hide resolved
@mcmire
Copy link
Contributor

mcmire commented Dec 5, 2023

@legobeat Thanks for reminding me about that issue, I will take a closer look at it tomorrow.

@MajorLift MajorLift force-pushed the 231201-fix-accounts-controller-deps branch from 26ccef1 to 4f99106 Compare December 7, 2023 19:53
@@ -33,6 +33,8 @@
"@metamask/base-controller": "^4.0.0",
"@metamask/eth-snap-keyring": "^2.0.0",
"@metamask/keyring-api": "^1.1.0",
"@metamask/keyring-controller": "^10.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be a sufficient compromise to add them as peerDependencies + devDependencies, and drop them as direct dependencies?

Copy link
Member

Choose a reason for hiding this comment

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

That sounds like a better idea to me as well. This is better represented as a peerDependency because we're using it via the messaging system. A peerDependency is an expectation we have of the user of this package, which is the situation we're in here (we're expecting the user of this package to have a messaging system that includes a specific version of the KeyringController).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for explaining this! Applied here: b3be687

Also made the same changes to queued-request-controller (9b79604), and a few others (0e731b7) that we can revert if unnecessary.

queued-request-controller seems like an appropriate change though, since the controllers dependencies are only being used to import messaging types that are used in the middleware and not the controller itself.

Copy link
Contributor

Choose a reason for hiding this comment

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

Great! Maybe we can go even further but makes sense to not do everything in one go.

@MajorLift MajorLift force-pushed the 231201-fix-accounts-controller-deps branch from 4f99106 to 024b7ce Compare December 19, 2023 21:42
@MajorLift MajorLift requested a review from a team as a code owner December 19, 2023 21:42
@MajorLift MajorLift force-pushed the 231201-fix-accounts-controller-deps branch from 024b7ce to 0e731b7 Compare December 19, 2023 21:46
@MajorLift MajorLift changed the title [accounts-controller] Restore @metamask/{keyring-controller,snaps-controllers} as deps Recategorize controller dependencies as devDependencies if only imports are messaging system-related types Dec 19, 2023
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Upon a second review of this PR, does it make sense to do this? In all of these cases, dependencies are imported to use types from those dependencies. We want to make sure that those dependencies come along for the ride and aren't merely dev or peer dependencies, otherwise consumers that attempt to import these packages will get TypeScript compilation errors.

@MajorLift
Copy link
Contributor Author

MajorLift commented Dec 19, 2023

@mcmire That was my understanding going into this PR (packages from which we're only importing types can still be dependencies), which is why I initially recategorized keyring-controller and snaps-controllers from devDeps to deps.

@Gudahtt
Copy link
Member

Gudahtt commented Dec 20, 2023

We want to make sure that those dependencies come along for the ride and aren't merely dev or peer dependencies

peerDependencies aren't suggestions, they're strict requirements. I know we can ignore them (with yarn at least), but it's still a totally appropriate way to express the demand here. And more than that, it would be incorrect to use a dependency here because then we'd see situations where types don't fail where they should (e.g. where the globally setup controller differs from one we have at type for, in a meaningful way).

We've been doing this a long time now. This is what this constraint is meant to enforce:

gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, 'peerDependencies') :-

@mcmire
Copy link
Contributor

mcmire commented Dec 21, 2023

And more than that, it would be incorrect to use a dependency here because then we'd see situations where types don't fail where they should (e.g. where the globally setup controller differs from one we have at type for, in a meaningful way).

I'm not sure I follow. If the client is using a function or constructor from a library that expects an argument of a certain shape, and that shape comes from a dependency that the library loads, and the client passes an object that is of a different version of that shape because the library it uses is of a different version, TypeScript should fail.

We've been doing this a long time now

Have we? I know we've been using peerDependencies to enforce that if two controllers are talking to each other then the versions used should be compatible. But when it comes to types, the latest decision is that they should come along for the ride: #3578. Again, if those types aren't available, then TypeScript will fail to compile the code. Asking users to manually install dependencies to get types so they can compile their code seems non-ideal to me.

@Gudahtt
Copy link
Member

Gudahtt commented Dec 21, 2023

If the client is using a function or constructor from a library that expects an argument of a certain shape, and that shape comes from a dependency that the library loads, and the client passes an object that is of a different version of that shape because the library it uses is of a different version, TypeScript should fail.

This would be true if metamask-controller.js was in TypeScript, but today it would result in no errors.

Generally though you're right, these peerDependency entries would be less critical if the extension used TypeScript, as we'd get the benefit of knowing the types matched up for any interactions. We still might find it valuable to use peerDependencies to represent expectations on what methods do, beyond just type compatibility, but maybe not in all cases.

I know we've been using peerDependencies to enforce that if two controllers are talking to each other then the versions used should be compatible.

That's exactly the situation here though, it's no different. The types aren't just being used for some unrelated purpose, they're used to represent the expected shape of the controller that the types come from.

But when it comes to types, the latest decision is that they should come along for the ride

We need to ensure the types are present if they're referenced in the types bundled with the package itself, otherwise those types would be invalid. But peerDependencies is an equally effective way of ensuring that they are present. Again, we have already being doing this an enforcing it via constraints. The same expectation of the types existing applies to communication between controllers.

We're not asking users to manually install additional code to get the types to work in this case. That's already required. These controllers won't work correctly if the controller referenced in the type isn't present, and integrated via the messenger system/controller constructor parameters.

@Gudahtt
Copy link
Member

Gudahtt commented Dec 21, 2023

Oh, though I am noticing now that I have misremembered the constraint we have for controllers. It only checks that controller dependencies are set as peerDependencies, it ignores devDependencies. So we did have type references as dependencies, as you said. I don't recall why we would have done that.

Edit: While I don't recall why these controllers had each other as dependencies, it does make sense that we wouldn't have this constraint for devDependencies because some controllers are used only in tests. Though that pattern seems bad in itself (I don't think we have any good reason to use other controllers in unit tests), we of course wouldn't want to force ourselves to list it as a peerDependency just because it's in a test.

@Gudahtt
Copy link
Member

Gudahtt commented Dec 21, 2023

To recap:

  • If we're using another controller via the messaging system, it does seem important to list it under peerDependencies so that we get a warning if we're using a version that might not be compatible.
    • In the future, we can consider dropping this requirement and relying solely on types instead.
  • If a controller is listed under peerDependencies and not invoked directly at runtime, I see no reason to include it under dependencies as well. The types will resolve because we can assume the package will be installed.

Does that make sense?

@mcmire
Copy link
Contributor

mcmire commented Dec 21, 2023

I think so, yes. I'm on board.

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM!

@MajorLift MajorLift merged commit ca4baa0 into main Dec 22, 2023
136 checks passed
@MajorLift MajorLift deleted the 231201-fix-accounts-controller-deps branch December 22, 2023 19:20
Gudahtt added a commit that referenced this pull request Dec 22, 2023
* origin/main:
  Recategorize controller dependencies as devDependencies if only imports are messaging system-related types (#3607)
Gudahtt added a commit that referenced this pull request Dec 22, 2023
I've updated some of the changelogs to simplify them (no need to
explain `devDependency` changes, those aren't public) and to clarify
that the one peer dependency addition is breaking.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file team-wallet-framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants