8000 feat: add strategies option for detect API by bluwy · Pull Request #42 · antfu-collective/package-manager-detector · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: add strategies option for detect API #42

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

Merged
merged 7 commits into from
Mar 10, 2025

Conversation

bluwy
Copy link
Contributor
@bluwy bluwy commented Feb 23, 2025

Description

Currently the detect APIs uses the lock files for detection, however the lock files don't necessarily reflect the package manager used for installation. For example, when debugging a project that uses pnpm-lock.yaml, and then making an install with npm that generates package-lock.json, the correct package manager used for installing things is npm.

This behaviour is similar to https://www.npmjs.com/package/which-pm, which I wanted to replace with this but the lock file behaviour would yield different results.

I'm not sure if this is out-of-scope of the project. If so, I don't mind if this PR is closed.

Linked Issues

n/a

Additional context

Alternatively, perhaps the installation detection can be part of the main detect API so we don't need two APIs, but this would be a breaking change.

@antfu
Copy link
Member
antfu commented Feb 28, 2025

I would love to hear more about when this would be helpful (like you are debugging but still want to call some installation programmatically?). Does this also means there might be multiple results in a same project?

@bluwy
Copy link
Contributor Author
bluwy commented Feb 28, 2025

I would love to hear more about when this would be helpful (like you are debugging but still want to call some installation programmatically?)

Yeah that's the main scenario I can think of. I wanted to replace this in Astro where it has an astro add command for helping adding integrations/dependencies. Here's its install code. So when debugging and calling astro add, it would be nice if it uses the right package manager for installation.

Maybe it's fine if astro add just use lockfile-based detection, but I figured to avoid a breaking change if possible plus it helps DX a little.

Does this also means there might be multiple results in a same project?

Yes. It could be thought as "the package manager used for installation" and "the package manager preferred for other commands" for me.

@antfu
Copy link
Member
antfu commented Feb 28, 2025

Or maybe if we introduce a ENV flag to override that detect agent, which would cover your debugging case and being a bit more explicit? WDYT?

@bluwy
Copy link
Contributor Author
bluwy commented Feb 28, 2025
8000

The intention is to only use a different package manager when doing installation, so using an env override that also changes the package manager detected in other cases feels wrong to me I think. Also it's easy to forget or hard to know about the flag that in which at that point I think this feature isn't worth it.

If we're on the fence of this feature (personally I am a little too), maybe we could try to simply open a PR on astro side as see what they think? I figured the feature wasn't hard to implement so I open a PR here first.

Copy link
Collaborator
@benmccann benmccann left a comment

Choose a reason for hiding this comment

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

Do we need two different methods? If we just added this functionality to detect I think it would be simpler for users. It's hard to tell the difference apart between these methods. And it doesn't seem like you'd have someone install node_modules with a package manager, delete that package manager's lockfile, and then look for a different lockfile?

I'm guessing you added it as a second method to avoid a breaking change, but if we're talking about making a breaking change anyway in #44 then maybe it'd simplify the API here to just make a change to the existing method

src/detect.ts Outdated
* @param options {DetectOptions} The options to use when detecting the package manager.
* @returns {DetectResult | null} The detected package manager or `null` if not found.
*/
export function detectInstallSync(options: DetectOptions = {}): DetectResult | null {
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe drop the sync version per #44

src/detect.ts Outdated
@@ -63,6 +63,64 @@ export function detectSync(options: DetectOptions = {}): DetectResult | null {
return null
}

/**
* Detects the package manager used for installation in the project.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's quite difficult to tell from the JSDocs what the difference is between detect and detectInstall

@bluwy
Copy link
Contributor Author
bluwy commented Mar 5, 2025

I personally don't find it confusing. detectInstall is "the package manager used for installation" and detect is "the package manager preferred for other commands". If you're not sure or don't care then using detect is fine enough. But merging detectInstall into detect is something I've also thought about, but it's indeed a breaking change and requires tweaking this package's description that it won't only just look for lock files.

And it doesn't seem like you'd have someone install node_modules with a package manager, delete that package manager's lockfile, and then look for a different lockfile?

A more probable scenario would be like: You downloaded a repro that uses bun.lockb, you don't want to use it so you simply ran pnpm install, now you have two lockfiles. When a tool comes around to add dependencies for you, you'd want to use pnpm instead, not bun.


It's not clear to me what's the direction we want to go in this PR to make a change.

@antfu
Copy link
Member
antfu commented Mar 5, 2025

Maybe having a single detect entry with detect({ strategies: 'packageManager' | 'lockfile' | 'node_modules' }), which we default to ['packageManager', 'lockfile']?

@bluwy
Copy link
Contributor Author
bluwy commented Mar 5, 2025

I quite like that. Alternatively would making it usecase-oriented be useful too? detect({ case: 'general' | 'install' }) (general is default). for would've been a cooler parameter name but it's taken by the syntax.

@benmccann
Copy link
Collaborator

When a tool comes around to add dependencies for you, you'd want to use pnpm instead, not bun.

Right, that was my point. I don't know when you wouldn't want to employ all strategies. Is there ever a case where it would hurt to use them all and you'd want it to return bun?

@bluwy
Copy link
Contributor Author
bluwy commented Mar 5, 2025

Perhaps after installing with pnpm you'd want to print out "bun run some-command" or something? If you use a package manager to install it doesn't mean you'd want to use it for every other command. We could definitely put a stand otherwise if that's what we want the behaviour to be, I don't have a hard preference but maybe some folks prefer different results in different occasions.

In the context of me wanting to replace this in astro add, I think it's also fine if detect always account for node_modules. An option to change the behaviour would be a bonus.

@antfu
Copy link
Member
antfu commented Mar 5, 2025

case: 'general' | 'install'

I think in a way we are not an enduser-facing library. I think transparent might be better to have over easy-to-config. I also found "install" still a bit confusing to me. With more technically named strategies, user could even opt-out some, for example, they want to ignore packageManager, or if they want to fine-tune the priorities of them like ['node_modules', 'lockfiles', 'packageManager'] so it would even work in the case when node_modules is not yet created.

@bluwy bluwy changed the title feat: add detectInstall and detectInstallSync APIs feat: add strategies option for detect API Mar 5, 2025
@bluwy
Copy link
Contributor Author
bluwy commented Mar 5, 2025

I've updated the code to implement strategies as proposed at #42 (comment). I also updated the README to help reflect the strategies more generically, but feel free to change it or revert if you'd like to describe it differently.

One thing I'm unsure of is that node_modules maybe isn't the right name for the strategy, since not every installation uses node_modules? Maybe we can name it install-metadata like how I named the INSTALL_METADATAS constant?

@antfu
Copy link
Member
antfu commented Mar 8, 2025

I see, for yarn it's indeed not very obvious for name it node_modules. How about actual-installed? 🤣

@benmccann
Copy link
Collaborator

I like install-metadata as it describes what it's looking for inline with the others

Maybe rename packageManager to packageManager-field as right now it just sounds like it's looking for which package manager you're using which could be confusing

@bluwy
Copy link
Contributor Author
bluwy commented Mar 9, 2025

I've renamed to install-metadata, and renamed packageManager to packageManager-field 👍

@antfu antfu merged commit 4dcfab3 into antfu-collective:main Mar 10, 2025
2 checks passed
@userquin
Copy link
Member
userquin commented Mar 10, 2025

Hey @bluwy , when you have time, can you add some entry to the readme file 🙏 ?

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.

4 participants
0